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.
- package/LICENSE +21 -0
- package/NODEBENCH_AGENTS.md +2 -2
- package/README.md +516 -82
- package/dist/__tests__/analytics.test.d.ts +11 -0
- package/dist/__tests__/analytics.test.js +546 -0
- package/dist/__tests__/analytics.test.js.map +1 -0
- package/dist/__tests__/dynamicLoading.test.d.ts +1 -0
- package/dist/__tests__/dynamicLoading.test.js +278 -0
- package/dist/__tests__/dynamicLoading.test.js.map +1 -0
- package/dist/__tests__/evalHarness.test.js +1 -1
- package/dist/__tests__/evalHarness.test.js.map +1 -1
- package/dist/__tests__/helpers/answerMatch.js +22 -22
- package/dist/__tests__/presetRealWorldBench.test.js +9 -0
- package/dist/__tests__/presetRealWorldBench.test.js.map +1 -1
- package/dist/__tests__/tools.test.js +1 -1
- package/dist/__tests__/toolsetGatingEval.test.js +9 -1
- package/dist/__tests__/toolsetGatingEval.test.js.map +1 -1
- package/dist/analytics/index.d.ts +10 -0
- package/dist/analytics/index.js +11 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/projectDetector.d.ts +19 -0
- package/dist/analytics/projectDetector.js +259 -0
- package/dist/analytics/projectDetector.js.map +1 -0
- package/dist/analytics/schema.d.ts +57 -0
- package/dist/analytics/schema.js +157 -0
- package/dist/analytics/schema.js.map +1 -0
- package/dist/analytics/smartPreset.d.ts +63 -0
- package/dist/analytics/smartPreset.js +300 -0
- package/dist/analytics/smartPreset.js.map +1 -0
- package/dist/analytics/toolTracker.d.ts +59 -0
- package/dist/analytics/toolTracker.js +163 -0
- package/dist/analytics/toolTracker.js.map +1 -0
- package/dist/analytics/usageStats.d.ts +64 -0
- package/dist/analytics/usageStats.js +252 -0
- package/dist/analytics/usageStats.js.map +1 -0
- package/dist/db.js +359 -321
- package/dist/db.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +652 -89
- package/dist/index.js.map +1 -1
- package/dist/tools/architectTools.js +13 -13
- package/dist/tools/critterTools.js +14 -14
- package/dist/tools/parallelAgentTools.js +176 -176
- package/dist/tools/patternTools.js +11 -11
- package/dist/tools/progressiveDiscoveryTools.d.ts +5 -1
- package/dist/tools/progressiveDiscoveryTools.js +111 -19
- package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
- package/dist/tools/researchWritingTools.js +42 -42
- package/dist/tools/rssTools.js +396 -396
- package/dist/tools/toolRegistry.d.ts +17 -0
- package/dist/tools/toolRegistry.js +65 -17
- package/dist/tools/toolRegistry.js.map +1 -1
- package/dist/tools/voiceBridgeTools.js +498 -498
- package/dist/toolsetRegistry.d.ts +10 -0
- package/dist/toolsetRegistry.js +84 -0
- package/dist/toolsetRegistry.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive tests for the analytics subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Tests cover:
|
|
5
|
+
* - schema.ts: DB init, singleton, CRUD, cache TTL, retention cleanup
|
|
6
|
+
* - projectDetector.ts: project type detection, glob matching, edge cases
|
|
7
|
+
* - usageStats.ts: aggregation queries, trends, failing tools, formatted display
|
|
8
|
+
* - smartPreset.ts: signal computation, scoring model, formatted output
|
|
9
|
+
* - toolTracker.ts: AnalyticsTracker singleton, record(), session stats, close
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,546 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive tests for the analytics subsystem.
|
|
3
|
+
*
|
|
4
|
+
* Tests cover:
|
|
5
|
+
* - schema.ts: DB init, singleton, CRUD, cache TTL, retention cleanup
|
|
6
|
+
* - projectDetector.ts: project type detection, glob matching, edge cases
|
|
7
|
+
* - usageStats.ts: aggregation queries, trends, failing tools, formatted display
|
|
8
|
+
* - smartPreset.ts: signal computation, scoring model, formatted output
|
|
9
|
+
* - toolTracker.ts: AnalyticsTracker singleton, record(), session stats, close
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
12
|
+
import Database from "better-sqlite3";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import fs from "fs";
|
|
15
|
+
import os from "os";
|
|
16
|
+
// ── Schema tests ────────────────────────────────────────────────────────
|
|
17
|
+
import { recordToolUsage, updateProjectContext, recordPresetSelection, getCachedStats, setCachedStats, clearOldRecords, } from "../analytics/schema.js";
|
|
18
|
+
function freshDb() {
|
|
19
|
+
// In-memory DB for test isolation
|
|
20
|
+
const db = new Database(":memory:");
|
|
21
|
+
db.pragma("journal_mode = WAL");
|
|
22
|
+
db.exec(`
|
|
23
|
+
CREATE TABLE IF NOT EXISTS tool_usage (
|
|
24
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
25
|
+
tool_name TEXT NOT NULL,
|
|
26
|
+
toolset TEXT NOT NULL,
|
|
27
|
+
timestamp INTEGER NOT NULL,
|
|
28
|
+
duration INTEGER NOT NULL,
|
|
29
|
+
success BOOLEAN NOT NULL,
|
|
30
|
+
error_message TEXT,
|
|
31
|
+
project_path TEXT NOT NULL,
|
|
32
|
+
preset TEXT NOT NULL,
|
|
33
|
+
args TEXT
|
|
34
|
+
);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_tool ON tool_usage(tool_name);
|
|
36
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_toolset ON tool_usage(toolset);
|
|
37
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_project ON tool_usage(project_path);
|
|
38
|
+
CREATE INDEX IF NOT EXISTS idx_tool_usage_timestamp ON tool_usage(timestamp);
|
|
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
|
+
CREATE TABLE IF NOT EXISTS preset_history (
|
|
53
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
54
|
+
project_path TEXT NOT NULL,
|
|
55
|
+
preset TEXT NOT NULL,
|
|
56
|
+
toolset_count INTEGER NOT NULL,
|
|
57
|
+
selected_at INTEGER NOT NULL,
|
|
58
|
+
selection_reason TEXT NOT NULL
|
|
59
|
+
);
|
|
60
|
+
CREATE TABLE IF NOT EXISTS usage_stats_cache (
|
|
61
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
62
|
+
project_path TEXT NOT NULL,
|
|
63
|
+
cache_key TEXT NOT NULL,
|
|
64
|
+
stats TEXT NOT NULL,
|
|
65
|
+
computed_at INTEGER NOT NULL,
|
|
66
|
+
ttl INTEGER NOT NULL,
|
|
67
|
+
UNIQUE(project_path, cache_key)
|
|
68
|
+
);
|
|
69
|
+
CREATE INDEX IF NOT EXISTS idx_usage_stats_cache_key ON usage_stats_cache(project_path, cache_key);
|
|
70
|
+
`);
|
|
71
|
+
return db;
|
|
72
|
+
}
|
|
73
|
+
describe("schema", () => {
|
|
74
|
+
let db;
|
|
75
|
+
beforeEach(() => { db = freshDb(); });
|
|
76
|
+
afterEach(() => { db.close(); });
|
|
77
|
+
it("recordToolUsage inserts a row", () => {
|
|
78
|
+
recordToolUsage(db, {
|
|
79
|
+
toolName: "verify_fix",
|
|
80
|
+
toolset: "verification",
|
|
81
|
+
timestamp: Date.now(),
|
|
82
|
+
duration: 150,
|
|
83
|
+
success: true,
|
|
84
|
+
projectPath: "/test",
|
|
85
|
+
preset: "default",
|
|
86
|
+
});
|
|
87
|
+
const count = db.prepare("SELECT COUNT(*) as c FROM tool_usage").get().c;
|
|
88
|
+
expect(count).toBe(1);
|
|
89
|
+
});
|
|
90
|
+
it("recordToolUsage stores error messages", () => {
|
|
91
|
+
recordToolUsage(db, {
|
|
92
|
+
toolName: "web_search",
|
|
93
|
+
toolset: "web",
|
|
94
|
+
timestamp: Date.now(),
|
|
95
|
+
duration: 500,
|
|
96
|
+
success: false,
|
|
97
|
+
errorMessage: "timeout",
|
|
98
|
+
projectPath: "/test",
|
|
99
|
+
preset: "full",
|
|
100
|
+
});
|
|
101
|
+
const row = db.prepare("SELECT * FROM tool_usage WHERE tool_name = 'web_search'").get();
|
|
102
|
+
expect(row.success).toBe(0);
|
|
103
|
+
expect(row.error_message).toBe("timeout");
|
|
104
|
+
});
|
|
105
|
+
it("updateProjectContext upserts on conflict", () => {
|
|
106
|
+
const base = {
|
|
107
|
+
projectPath: "/proj",
|
|
108
|
+
projectType: "web_frontend",
|
|
109
|
+
detectedAt: Date.now(),
|
|
110
|
+
lastSeen: Date.now(),
|
|
111
|
+
language: "typescript",
|
|
112
|
+
hasTests: true,
|
|
113
|
+
hasCI: false,
|
|
114
|
+
hasDocs: false,
|
|
115
|
+
fileCount: 100,
|
|
116
|
+
};
|
|
117
|
+
updateProjectContext(db, base);
|
|
118
|
+
updateProjectContext(db, { ...base, fileCount: 200 });
|
|
119
|
+
const rows = db.prepare("SELECT * FROM project_context WHERE project_path = '/proj'").all();
|
|
120
|
+
expect(rows).toHaveLength(1);
|
|
121
|
+
expect(rows[0].file_count).toBe(200);
|
|
122
|
+
});
|
|
123
|
+
it("recordPresetSelection inserts a history row", () => {
|
|
124
|
+
recordPresetSelection(db, {
|
|
125
|
+
projectPath: "/proj",
|
|
126
|
+
preset: "full",
|
|
127
|
+
toolsetCount: 175,
|
|
128
|
+
selectedAt: Date.now(),
|
|
129
|
+
selectionReason: "smart",
|
|
130
|
+
});
|
|
131
|
+
const count = db.prepare("SELECT COUNT(*) as c FROM preset_history").get().c;
|
|
132
|
+
expect(count).toBe(1);
|
|
133
|
+
});
|
|
134
|
+
it("cache: setCachedStats + getCachedStats round-trip", () => {
|
|
135
|
+
const now = Date.now();
|
|
136
|
+
setCachedStats(db, {
|
|
137
|
+
projectPath: "/proj",
|
|
138
|
+
cacheKey: "summary_30d",
|
|
139
|
+
stats: JSON.stringify({ totalCalls: 42 }),
|
|
140
|
+
computedAt: now,
|
|
141
|
+
ttl: 300, // 5 minutes in seconds
|
|
142
|
+
});
|
|
143
|
+
const cached = getCachedStats(db, "/proj", "summary_30d");
|
|
144
|
+
expect(cached).not.toBeNull();
|
|
145
|
+
expect(JSON.parse(cached).totalCalls).toBe(42);
|
|
146
|
+
});
|
|
147
|
+
it("cache: expired entries return null", () => {
|
|
148
|
+
const past = Date.now() - 600_000; // 10 minutes ago
|
|
149
|
+
setCachedStats(db, {
|
|
150
|
+
projectPath: "/proj",
|
|
151
|
+
cacheKey: "old",
|
|
152
|
+
stats: "{}",
|
|
153
|
+
computedAt: past,
|
|
154
|
+
ttl: 60, // 1 minute TTL — should be expired
|
|
155
|
+
});
|
|
156
|
+
const result = getCachedStats(db, "/proj", "old");
|
|
157
|
+
expect(result).toBeNull();
|
|
158
|
+
});
|
|
159
|
+
it("clearOldRecords deletes old tool_usage rows", () => {
|
|
160
|
+
const old = Date.now() - 100 * 24 * 60 * 60 * 1000; // 100 days ago
|
|
161
|
+
recordToolUsage(db, {
|
|
162
|
+
toolName: "old_tool",
|
|
163
|
+
toolset: "verification",
|
|
164
|
+
timestamp: old,
|
|
165
|
+
duration: 10,
|
|
166
|
+
success: true,
|
|
167
|
+
projectPath: "/proj",
|
|
168
|
+
preset: "default",
|
|
169
|
+
});
|
|
170
|
+
recordToolUsage(db, {
|
|
171
|
+
toolName: "new_tool",
|
|
172
|
+
toolset: "verification",
|
|
173
|
+
timestamp: Date.now(),
|
|
174
|
+
duration: 10,
|
|
175
|
+
success: true,
|
|
176
|
+
projectPath: "/proj",
|
|
177
|
+
preset: "default",
|
|
178
|
+
});
|
|
179
|
+
clearOldRecords(db, 90);
|
|
180
|
+
const count = db.prepare("SELECT COUNT(*) as c FROM tool_usage").get().c;
|
|
181
|
+
expect(count).toBe(1);
|
|
182
|
+
const row = db.prepare("SELECT tool_name FROM tool_usage").get();
|
|
183
|
+
expect(row.tool_name).toBe("new_tool");
|
|
184
|
+
});
|
|
185
|
+
it("clearOldRecords(0) deletes everything", () => {
|
|
186
|
+
recordToolUsage(db, {
|
|
187
|
+
toolName: "any",
|
|
188
|
+
toolset: "any",
|
|
189
|
+
timestamp: Date.now() - 1, // 1ms in the past to satisfy strict < comparison
|
|
190
|
+
duration: 10,
|
|
191
|
+
success: true,
|
|
192
|
+
projectPath: "/proj",
|
|
193
|
+
preset: "default",
|
|
194
|
+
});
|
|
195
|
+
clearOldRecords(db, 0);
|
|
196
|
+
const count = db.prepare("SELECT COUNT(*) as c FROM tool_usage").get().c;
|
|
197
|
+
expect(count).toBe(0);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
// ── usageStats tests ────────────────────────────────────────────────────
|
|
201
|
+
import { getToolUsageStats, getToolsetUsageStats, getProjectUsageSummary, getUsageTrend, getUnusedTools, getFrequentlyFailingTools, formatStatsDisplay, getCachedProjectSummary, } from "../analytics/usageStats.js";
|
|
202
|
+
function seedUsageData(db) {
|
|
203
|
+
const now = Date.now();
|
|
204
|
+
const tools = [
|
|
205
|
+
{ name: "verify_fix", toolset: "verification", success: true },
|
|
206
|
+
{ name: "verify_fix", toolset: "verification", success: true },
|
|
207
|
+
{ name: "verify_fix", toolset: "verification", success: false },
|
|
208
|
+
{ name: "run_eval", toolset: "eval", success: true },
|
|
209
|
+
{ name: "web_search", toolset: "web", success: true },
|
|
210
|
+
{ name: "web_search", toolset: "web", success: false },
|
|
211
|
+
{ name: "web_search", toolset: "web", success: false },
|
|
212
|
+
{ name: "web_search", toolset: "web", success: false },
|
|
213
|
+
];
|
|
214
|
+
for (const t of tools) {
|
|
215
|
+
recordToolUsage(db, {
|
|
216
|
+
toolName: t.name,
|
|
217
|
+
toolset: t.toolset,
|
|
218
|
+
timestamp: now - Math.random() * 1000000,
|
|
219
|
+
duration: 100 + Math.random() * 500,
|
|
220
|
+
success: t.success,
|
|
221
|
+
errorMessage: t.success ? undefined : "test error",
|
|
222
|
+
projectPath: "/test-project",
|
|
223
|
+
preset: "default",
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
describe("usageStats", () => {
|
|
228
|
+
let db;
|
|
229
|
+
beforeEach(() => {
|
|
230
|
+
db = freshDb();
|
|
231
|
+
seedUsageData(db);
|
|
232
|
+
});
|
|
233
|
+
afterEach(() => { db.close(); });
|
|
234
|
+
it("getToolUsageStats returns per-tool aggregations", () => {
|
|
235
|
+
const stats = getToolUsageStats(db, "/test-project", 30);
|
|
236
|
+
expect(stats.length).toBeGreaterThan(0);
|
|
237
|
+
const verifyStats = stats.find(s => s.toolName === "verify_fix");
|
|
238
|
+
expect(verifyStats).toBeDefined();
|
|
239
|
+
expect(verifyStats.callCount).toBe(3);
|
|
240
|
+
expect(verifyStats.successCount).toBe(2);
|
|
241
|
+
expect(verifyStats.failureCount).toBe(1);
|
|
242
|
+
});
|
|
243
|
+
it("getToolsetUsageStats returns per-toolset aggregations", () => {
|
|
244
|
+
const stats = getToolsetUsageStats(db, "/test-project", 30);
|
|
245
|
+
expect(stats.length).toBeGreaterThan(0);
|
|
246
|
+
const webStats = stats.find(s => s.toolset === "web");
|
|
247
|
+
expect(webStats).toBeDefined();
|
|
248
|
+
expect(webStats.totalCalls).toBe(4);
|
|
249
|
+
});
|
|
250
|
+
it("getProjectUsageSummary returns null for empty project", () => {
|
|
251
|
+
const summary = getProjectUsageSummary(db, "/nonexistent", 30);
|
|
252
|
+
expect(summary).toBeNull();
|
|
253
|
+
});
|
|
254
|
+
it("getProjectUsageSummary returns valid summary", () => {
|
|
255
|
+
const summary = getProjectUsageSummary(db, "/test-project", 30);
|
|
256
|
+
expect(summary).not.toBeNull();
|
|
257
|
+
expect(summary.totalCalls).toBe(8);
|
|
258
|
+
expect(summary.uniqueToolsUsed).toBe(3);
|
|
259
|
+
expect(summary.successRate).toBeGreaterThan(0);
|
|
260
|
+
expect(summary.successRate).toBeLessThanOrEqual(1);
|
|
261
|
+
expect(summary.topTools.length).toBeGreaterThan(0);
|
|
262
|
+
expect(summary.topToolsets.length).toBeGreaterThan(0);
|
|
263
|
+
});
|
|
264
|
+
it("getUsageTrend returns daily aggregation", () => {
|
|
265
|
+
const trends = getUsageTrend(db, "/test-project", 30);
|
|
266
|
+
expect(trends.length).toBeGreaterThan(0);
|
|
267
|
+
expect(trends[0]).toHaveProperty("date");
|
|
268
|
+
expect(trends[0]).toHaveProperty("callCount");
|
|
269
|
+
});
|
|
270
|
+
it("getUnusedTools returns tools not called", () => {
|
|
271
|
+
const unused = getUnusedTools(db, "/test-project", ["verify_fix", "run_eval", "web_search", "never_used_tool"], 30);
|
|
272
|
+
expect(unused).toContain("never_used_tool");
|
|
273
|
+
expect(unused).not.toContain("verify_fix");
|
|
274
|
+
});
|
|
275
|
+
it("getFrequentlyFailingTools returns tools with many failures", () => {
|
|
276
|
+
const failing = getFrequentlyFailingTools(db, "/test-project", 30, 2);
|
|
277
|
+
expect(failing.length).toBeGreaterThan(0);
|
|
278
|
+
const webFailing = failing.find(f => f.toolName === "web_search");
|
|
279
|
+
expect(webFailing).toBeDefined();
|
|
280
|
+
expect(webFailing.failureCount).toBe(3);
|
|
281
|
+
});
|
|
282
|
+
it("formatStatsDisplay produces human-readable output", () => {
|
|
283
|
+
const summary = getProjectUsageSummary(db, "/test-project", 30);
|
|
284
|
+
const output = formatStatsDisplay(summary, "/test-project");
|
|
285
|
+
expect(output).toContain("Usage Analytics");
|
|
286
|
+
expect(output).toContain("Total calls:");
|
|
287
|
+
expect(output).toContain("Success rate:");
|
|
288
|
+
expect(output).toContain("Top Tools");
|
|
289
|
+
});
|
|
290
|
+
it("getCachedProjectSummary caches on first call and returns from cache on second", () => {
|
|
291
|
+
const s1 = getCachedProjectSummary(db, "/test-project", 30);
|
|
292
|
+
expect(s1).not.toBeNull();
|
|
293
|
+
// Verify cache was written
|
|
294
|
+
const cached = getCachedStats(db, "/test-project", "summary_30d");
|
|
295
|
+
expect(cached).not.toBeNull();
|
|
296
|
+
// Second call should return cached data
|
|
297
|
+
const s2 = getCachedProjectSummary(db, "/test-project", 30);
|
|
298
|
+
expect(s2).toEqual(s1);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
// ── projectDetector tests ───────────────────────────────────────────────
|
|
302
|
+
import { detectProject } from "../analytics/projectDetector.js";
|
|
303
|
+
describe("projectDetector", () => {
|
|
304
|
+
let tmpDir;
|
|
305
|
+
beforeEach(() => {
|
|
306
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "nb-test-"));
|
|
307
|
+
});
|
|
308
|
+
afterEach(() => {
|
|
309
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
310
|
+
});
|
|
311
|
+
it("detects unknown project type for empty dir", () => {
|
|
312
|
+
const ctx = detectProject(tmpDir);
|
|
313
|
+
expect(ctx.projectType).toBe("unknown");
|
|
314
|
+
expect(ctx.language).toBe("unknown");
|
|
315
|
+
});
|
|
316
|
+
it("detects web_frontend for React project", () => {
|
|
317
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({
|
|
318
|
+
dependencies: { react: "^18" },
|
|
319
|
+
}));
|
|
320
|
+
fs.writeFileSync(path.join(tmpDir, "tsconfig.json"), "{}");
|
|
321
|
+
const ctx = detectProject(tmpDir);
|
|
322
|
+
expect(ctx.projectType).toBe("web_frontend");
|
|
323
|
+
expect(ctx.language).toBe("typescript");
|
|
324
|
+
expect(ctx.framework).toBe("react");
|
|
325
|
+
});
|
|
326
|
+
it("detects library type for package.json with main field", () => {
|
|
327
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({
|
|
328
|
+
main: "dist/index.js",
|
|
329
|
+
name: "my-lib",
|
|
330
|
+
}));
|
|
331
|
+
const ctx = detectProject(tmpDir);
|
|
332
|
+
// Library detection depends on the heuristics — at minimum should detect JS
|
|
333
|
+
expect(ctx.language).toBe("javascript");
|
|
334
|
+
});
|
|
335
|
+
it("detects tests when test files exist", () => {
|
|
336
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), "{}");
|
|
337
|
+
// Detector needs actual test files matching *.test.ts or a tests/ dir
|
|
338
|
+
fs.mkdirSync(path.join(tmpDir, "tests"));
|
|
339
|
+
fs.writeFileSync(path.join(tmpDir, "app.test.ts"), "");
|
|
340
|
+
const ctx = detectProject(tmpDir);
|
|
341
|
+
expect(ctx.hasTests).toBe(true);
|
|
342
|
+
});
|
|
343
|
+
it("detects CI when workflow files exist", () => {
|
|
344
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), "{}");
|
|
345
|
+
fs.mkdirSync(path.join(tmpDir, ".github", "workflows"), { recursive: true });
|
|
346
|
+
fs.writeFileSync(path.join(tmpDir, ".github", "workflows", "ci.yml"), "name: CI");
|
|
347
|
+
const ctx = detectProject(tmpDir);
|
|
348
|
+
expect(ctx.hasCI).toBe(true);
|
|
349
|
+
});
|
|
350
|
+
it("counts files correctly", () => {
|
|
351
|
+
fs.writeFileSync(path.join(tmpDir, "a.ts"), "");
|
|
352
|
+
fs.writeFileSync(path.join(tmpDir, "b.ts"), "");
|
|
353
|
+
fs.writeFileSync(path.join(tmpDir, "c.js"), "");
|
|
354
|
+
const ctx = detectProject(tmpDir);
|
|
355
|
+
expect(ctx.fileCount).toBeGreaterThanOrEqual(3);
|
|
356
|
+
});
|
|
357
|
+
it("detects Python project from requirements.txt", () => {
|
|
358
|
+
fs.writeFileSync(path.join(tmpDir, "requirements.txt"), "pandas\nnumpy\n");
|
|
359
|
+
const ctx = detectProject(tmpDir);
|
|
360
|
+
expect(ctx.language).toBe("python");
|
|
361
|
+
// requirements.txt can trigger fastapi pattern (web_backend) via anyFileExists
|
|
362
|
+
expect(["web_backend", "data_science", "unknown"]).toContain(ctx.projectType);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
// ── smartPreset tests ───────────────────────────────────────────────────
|
|
366
|
+
import { generateSmartPreset, listPresets, formatPresetRecommendation, } from "../analytics/smartPreset.js";
|
|
367
|
+
function mockToolsetMap() {
|
|
368
|
+
const makeTool = (name) => ({
|
|
369
|
+
name,
|
|
370
|
+
description: `Mock ${name}`,
|
|
371
|
+
inputSchema: { type: "object", properties: {} },
|
|
372
|
+
handler: async () => ({}),
|
|
373
|
+
});
|
|
374
|
+
return {
|
|
375
|
+
verification: [makeTool("verify_fix"), makeTool("verify_plan")],
|
|
376
|
+
eval: [makeTool("run_eval")],
|
|
377
|
+
quality_gate: [makeTool("quality_check")],
|
|
378
|
+
learning: [makeTool("record_learning")],
|
|
379
|
+
flywheel: [makeTool("flywheel_step")],
|
|
380
|
+
recon: [makeTool("recon_scan")],
|
|
381
|
+
security: [makeTool("security_check")],
|
|
382
|
+
boilerplate: [makeTool("scaffold")],
|
|
383
|
+
web: [makeTool("web_search"), makeTool("fetch_url")],
|
|
384
|
+
github: [makeTool("github_search")],
|
|
385
|
+
vision: [makeTool("capture_screenshot")],
|
|
386
|
+
ui_capture: [makeTool("capture_ui")],
|
|
387
|
+
llm: [makeTool("call_llm")],
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
describe("smartPreset", () => {
|
|
391
|
+
let db;
|
|
392
|
+
const toolsetMap = mockToolsetMap();
|
|
393
|
+
beforeEach(() => { db = freshDb(); });
|
|
394
|
+
afterEach(() => { db.close(); });
|
|
395
|
+
it("recommends default for empty project with no history", () => {
|
|
396
|
+
const rec = generateSmartPreset(db, toolsetMap, "/empty");
|
|
397
|
+
expect(rec.preset).toBe("default");
|
|
398
|
+
expect(rec.confidence).toBeGreaterThan(0);
|
|
399
|
+
expect(rec.confidence).toBeLessThanOrEqual(1);
|
|
400
|
+
expect(rec.signals.historyWeight).toBe(0);
|
|
401
|
+
expect(rec.reason).toContain("No usage history");
|
|
402
|
+
});
|
|
403
|
+
it("includes signal breakdown with all 5 signals", () => {
|
|
404
|
+
const rec = generateSmartPreset(db, toolsetMap, "/empty");
|
|
405
|
+
expect(rec.signals).toHaveProperty("projectTypeAffinity");
|
|
406
|
+
expect(rec.signals).toHaveProperty("usageBreadth");
|
|
407
|
+
expect(rec.signals).toHaveProperty("specializedDepth");
|
|
408
|
+
expect(rec.signals).toHaveProperty("failurePenalty");
|
|
409
|
+
expect(rec.signals).toHaveProperty("historyWeight");
|
|
410
|
+
});
|
|
411
|
+
it("score increases when specialized toolsets are used heavily", () => {
|
|
412
|
+
// Seed heavy usage of non-default toolsets
|
|
413
|
+
const now = Date.now();
|
|
414
|
+
for (let i = 0; i < 50; i++) {
|
|
415
|
+
recordToolUsage(db, {
|
|
416
|
+
toolName: "web_search",
|
|
417
|
+
toolset: "web",
|
|
418
|
+
timestamp: now - i * 10000,
|
|
419
|
+
duration: 100,
|
|
420
|
+
success: true,
|
|
421
|
+
projectPath: "/heavy-web",
|
|
422
|
+
preset: "full",
|
|
423
|
+
});
|
|
424
|
+
recordToolUsage(db, {
|
|
425
|
+
toolName: "github_search",
|
|
426
|
+
toolset: "github",
|
|
427
|
+
timestamp: now - i * 10000,
|
|
428
|
+
duration: 100,
|
|
429
|
+
success: true,
|
|
430
|
+
projectPath: "/heavy-web",
|
|
431
|
+
preset: "full",
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
const rec = generateSmartPreset(db, toolsetMap, "/heavy-web");
|
|
435
|
+
expect(rec.signals.specializedDepth).toBeGreaterThan(0);
|
|
436
|
+
expect(rec.signals.historyWeight).toBeGreaterThan(0.5);
|
|
437
|
+
expect(rec.score).toBeGreaterThan(0.3);
|
|
438
|
+
});
|
|
439
|
+
it("failure penalty reduces confidence", () => {
|
|
440
|
+
const now = Date.now();
|
|
441
|
+
// Seed lots of failures
|
|
442
|
+
for (let i = 0; i < 30; i++) {
|
|
443
|
+
recordToolUsage(db, {
|
|
444
|
+
toolName: "web_search",
|
|
445
|
+
toolset: "web",
|
|
446
|
+
timestamp: now - i * 1000,
|
|
447
|
+
duration: 100,
|
|
448
|
+
success: false,
|
|
449
|
+
errorMessage: "timeout",
|
|
450
|
+
projectPath: "/failing",
|
|
451
|
+
preset: "full",
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
const rec = generateSmartPreset(db, toolsetMap, "/failing");
|
|
455
|
+
expect(rec.signals.failurePenalty).toBeGreaterThan(0);
|
|
456
|
+
expect(rec.usageInsights.frequentlyFailingTools.length).toBeGreaterThan(0);
|
|
457
|
+
});
|
|
458
|
+
it("listPresets returns all presets with counts", () => {
|
|
459
|
+
const presets = listPresets(toolsetMap);
|
|
460
|
+
expect(presets.length).toBeGreaterThanOrEqual(10); // default + 8 themed + full
|
|
461
|
+
expect(presets[0].name).toBe("default");
|
|
462
|
+
expect(presets[presets.length - 1].name).toBe("full");
|
|
463
|
+
expect(presets[presets.length - 1].toolCount).toBeGreaterThan(presets[0].toolCount);
|
|
464
|
+
// Themed presets should have at least as many tools as default (extras may not exist in mock)
|
|
465
|
+
for (const p of presets.slice(1, -1)) {
|
|
466
|
+
expect(p.toolCount).toBeGreaterThanOrEqual(presets[0].toolCount);
|
|
467
|
+
expect(p.toolCount).toBeLessThanOrEqual(presets[presets.length - 1].toolCount);
|
|
468
|
+
}
|
|
469
|
+
});
|
|
470
|
+
it("formatPresetRecommendation includes signal breakdown and apply commands", () => {
|
|
471
|
+
const rec = generateSmartPreset(db, toolsetMap, "/empty");
|
|
472
|
+
const output = formatPresetRecommendation(rec, toolsetMap);
|
|
473
|
+
expect(output).toContain("Smart Preset Recommendation");
|
|
474
|
+
expect(output).toContain("Signal Breakdown");
|
|
475
|
+
expect(output).toContain("Project Type Affinity");
|
|
476
|
+
expect(output).toContain("Usage Breadth");
|
|
477
|
+
expect(output).toContain("Apply");
|
|
478
|
+
expect(output).toContain("npx nodebench-mcp --preset");
|
|
479
|
+
});
|
|
480
|
+
it("formatPresetRecommendation surfaces failing tools", () => {
|
|
481
|
+
const now = Date.now();
|
|
482
|
+
for (let i = 0; i < 10; i++) {
|
|
483
|
+
recordToolUsage(db, {
|
|
484
|
+
toolName: "broken_tool",
|
|
485
|
+
toolset: "web",
|
|
486
|
+
timestamp: now - i * 1000,
|
|
487
|
+
duration: 50,
|
|
488
|
+
success: false,
|
|
489
|
+
errorMessage: "ECONNREFUSED",
|
|
490
|
+
projectPath: "/broken",
|
|
491
|
+
preset: "full",
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
const rec = generateSmartPreset(db, toolsetMap, "/broken");
|
|
495
|
+
const output = formatPresetRecommendation(rec, toolsetMap);
|
|
496
|
+
expect(output).toContain("Failing Tools");
|
|
497
|
+
expect(output).toContain("broken_tool");
|
|
498
|
+
expect(output).toContain("ECONNREFUSED");
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
// ── AnalyticsTracker tests ──────────────────────────────────────────────
|
|
502
|
+
// We test the AnalyticsTracker in a limited way since it's a singleton
|
|
503
|
+
// that opens a real DB. We test the core logic via the schema/stats tests above.
|
|
504
|
+
// Here we just verify the class API contract.
|
|
505
|
+
describe("AnalyticsTracker API contract", () => {
|
|
506
|
+
it("exports AnalyticsTracker class with expected static methods", async () => {
|
|
507
|
+
const { AnalyticsTracker } = await import("../analytics/toolTracker.js");
|
|
508
|
+
expect(typeof AnalyticsTracker.init).toBe("function");
|
|
509
|
+
expect(typeof AnalyticsTracker.get).toBe("function");
|
|
510
|
+
});
|
|
511
|
+
it("exports initializeProjectContext for backward compat", async () => {
|
|
512
|
+
const { initializeProjectContext } = await import("../analytics/toolTracker.js");
|
|
513
|
+
expect(typeof initializeProjectContext).toBe("function");
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
// ── toolsetRegistry tests ───────────────────────────────────────────────
|
|
517
|
+
describe("toolsetRegistry", () => {
|
|
518
|
+
it("exports TOOLSET_MAP with expected toolsets", async () => {
|
|
519
|
+
const { TOOLSET_MAP } = await import("../toolsetRegistry.js");
|
|
520
|
+
expect(TOOLSET_MAP).toBeDefined();
|
|
521
|
+
expect(typeof TOOLSET_MAP).toBe("object");
|
|
522
|
+
expect(Object.keys(TOOLSET_MAP).length).toBeGreaterThan(20);
|
|
523
|
+
// Core toolsets must exist
|
|
524
|
+
expect(TOOLSET_MAP).toHaveProperty("verification");
|
|
525
|
+
expect(TOOLSET_MAP).toHaveProperty("eval");
|
|
526
|
+
expect(TOOLSET_MAP).toHaveProperty("quality_gate");
|
|
527
|
+
expect(TOOLSET_MAP).toHaveProperty("web");
|
|
528
|
+
});
|
|
529
|
+
it("exports TOOL_TO_TOOLSET map", async () => {
|
|
530
|
+
const { TOOL_TO_TOOLSET, TOOLSET_MAP } = await import("../toolsetRegistry.js");
|
|
531
|
+
expect(TOOL_TO_TOOLSET).toBeInstanceOf(Map);
|
|
532
|
+
// Every tool in TOOLSET_MAP should be in the lookup
|
|
533
|
+
for (const [tsName, tools] of Object.entries(TOOLSET_MAP)) {
|
|
534
|
+
for (const tool of tools) {
|
|
535
|
+
expect(TOOL_TO_TOOLSET.get(tool.name)).toBe(tsName);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
it("total tool count matches expectations (175)", async () => {
|
|
540
|
+
const { TOOLSET_MAP } = await import("../toolsetRegistry.js");
|
|
541
|
+
const total = Object.values(TOOLSET_MAP).reduce((s, t) => s + t.length, 0);
|
|
542
|
+
// Should be around 169 domain tools (175 - 6 meta/discovery)
|
|
543
|
+
expect(total).toBeGreaterThan(100);
|
|
544
|
+
});
|
|
545
|
+
});
|
|
546
|
+
//# sourceMappingURL=analytics.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.test.js","sourceRoot":"","sources":["../../src/__tests__/analytics.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|