nodebench-mcp 2.22.0 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NODEBENCH_AGENTS.md +5 -4
- package/README.md +495 -280
- package/dist/__tests__/architectComplex.test.js +3 -5
- package/dist/__tests__/architectComplex.test.js.map +1 -1
- package/dist/__tests__/batchAutopilot.test.d.ts +8 -0
- package/dist/__tests__/batchAutopilot.test.js +218 -0
- package/dist/__tests__/batchAutopilot.test.js.map +1 -0
- package/dist/__tests__/cliSubcommands.test.d.ts +1 -0
- package/dist/__tests__/cliSubcommands.test.js +138 -0
- package/dist/__tests__/cliSubcommands.test.js.map +1 -0
- package/dist/__tests__/evalHarness.test.js +1 -1
- package/dist/__tests__/forecastingDogfood.test.d.ts +9 -0
- package/dist/__tests__/forecastingDogfood.test.js +284 -0
- package/dist/__tests__/forecastingDogfood.test.js.map +1 -0
- package/dist/__tests__/forecastingScoring.test.d.ts +9 -0
- package/dist/__tests__/forecastingScoring.test.js +202 -0
- package/dist/__tests__/forecastingScoring.test.js.map +1 -0
- package/dist/__tests__/localDashboard.test.d.ts +1 -0
- package/dist/__tests__/localDashboard.test.js +226 -0
- package/dist/__tests__/localDashboard.test.js.map +1 -0
- package/dist/__tests__/multiHopDogfood.test.d.ts +12 -0
- package/dist/__tests__/multiHopDogfood.test.js +303 -0
- package/dist/__tests__/multiHopDogfood.test.js.map +1 -0
- package/dist/__tests__/openclawDogfood.test.d.ts +23 -0
- package/dist/__tests__/openclawDogfood.test.js +535 -0
- package/dist/__tests__/openclawDogfood.test.js.map +1 -0
- package/dist/__tests__/openclawMessaging.test.d.ts +14 -0
- package/dist/__tests__/openclawMessaging.test.js +232 -0
- package/dist/__tests__/openclawMessaging.test.js.map +1 -0
- package/dist/__tests__/tools.test.js +7 -3
- package/dist/__tests__/tools.test.js.map +1 -1
- package/dist/__tests__/traceabilityDogfood.test.d.ts +12 -0
- package/dist/__tests__/traceabilityDogfood.test.js +241 -0
- package/dist/__tests__/traceabilityDogfood.test.js.map +1 -0
- package/dist/__tests__/webmcpTools.test.d.ts +7 -0
- package/dist/__tests__/webmcpTools.test.js +195 -0
- package/dist/__tests__/webmcpTools.test.js.map +1 -0
- package/dist/dashboard/briefHtml.d.ts +20 -0
- package/dist/dashboard/briefHtml.js +1000 -0
- package/dist/dashboard/briefHtml.js.map +1 -0
- package/dist/dashboard/briefServer.d.ts +18 -0
- package/dist/dashboard/briefServer.js +320 -0
- package/dist/dashboard/briefServer.js.map +1 -0
- package/dist/dashboard/html.d.ts +18 -0
- package/dist/dashboard/html.js +1491 -0
- package/dist/dashboard/html.js.map +1 -0
- package/dist/dashboard/server.d.ts +17 -0
- package/dist/dashboard/server.js +403 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/db.js +38 -0
- package/dist/db.js.map +1 -1
- package/dist/index.js +211 -5
- package/dist/index.js.map +1 -1
- package/dist/tools/critterTools.js +4 -0
- package/dist/tools/critterTools.js.map +1 -1
- package/dist/tools/forecastingTools.d.ts +11 -0
- package/dist/tools/forecastingTools.js +616 -0
- package/dist/tools/forecastingTools.js.map +1 -0
- package/dist/tools/localDashboardTools.d.ts +8 -0
- package/dist/tools/localDashboardTools.js +332 -0
- package/dist/tools/localDashboardTools.js.map +1 -0
- package/dist/tools/metaTools.js +170 -1
- package/dist/tools/metaTools.js.map +1 -1
- package/dist/tools/openclawTools.d.ts +11 -0
- package/dist/tools/openclawTools.js +1017 -0
- package/dist/tools/openclawTools.js.map +1 -0
- package/dist/tools/overstoryTools.d.ts +14 -0
- package/dist/tools/overstoryTools.js +426 -0
- package/dist/tools/overstoryTools.js.map +1 -0
- package/dist/tools/prReportTools.d.ts +11 -0
- package/dist/tools/prReportTools.js +911 -0
- package/dist/tools/prReportTools.js.map +1 -0
- package/dist/tools/progressiveDiscoveryTools.js +28 -9
- package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
- package/dist/tools/selfEvalTools.js +8 -1
- package/dist/tools/selfEvalTools.js.map +1 -1
- package/dist/tools/sessionMemoryTools.js +14 -2
- package/dist/tools/sessionMemoryTools.js.map +1 -1
- package/dist/tools/skillUpdateTools.d.ts +24 -0
- package/dist/tools/skillUpdateTools.js +469 -0
- package/dist/tools/skillUpdateTools.js.map +1 -0
- package/dist/tools/toolRegistry.js +178 -0
- package/dist/tools/toolRegistry.js.map +1 -1
- package/dist/tools/uiUxDiveAdvancedTools.js +61 -0
- package/dist/tools/uiUxDiveAdvancedTools.js.map +1 -1
- package/dist/tools/uiUxDiveTools.js +154 -1
- package/dist/tools/uiUxDiveTools.js.map +1 -1
- package/dist/tools/visualQaTools.d.ts +2 -0
- package/dist/tools/visualQaTools.js +1088 -0
- package/dist/tools/visualQaTools.js.map +1 -0
- package/dist/tools/webmcpTools.d.ts +16 -0
- package/dist/tools/webmcpTools.js +703 -0
- package/dist/tools/webmcpTools.js.map +1 -0
- package/dist/toolsetRegistry.js +4 -0
- package/dist/toolsetRegistry.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* traceabilityDogfood.test.ts — End-to-end dogfood for completion traceability
|
|
3
|
+
*
|
|
4
|
+
* Exercises all traceability integration points added to the agentic infrastructure:
|
|
5
|
+
* 1. save_session_note with citedFrom field (schema + handler)
|
|
6
|
+
* 2. refresh_task_context with originalRequest field (schema + handler)
|
|
7
|
+
* 3. critter_check with original_request field (schema + handler)
|
|
8
|
+
* 4. Workflow chains include traceability save_session_note step
|
|
9
|
+
* 5. selfEval ship_gates checks for save_session_note (traceability)
|
|
10
|
+
* 6. Documentation: AI_FLYWHEEL.md + AGENTS.md
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* traceabilityDogfood.test.ts — End-to-end dogfood for completion traceability
|
|
3
|
+
*
|
|
4
|
+
* Exercises all traceability integration points added to the agentic infrastructure:
|
|
5
|
+
* 1. save_session_note with citedFrom field (schema + handler)
|
|
6
|
+
* 2. refresh_task_context with originalRequest field (schema + handler)
|
|
7
|
+
* 3. critter_check with original_request field (schema + handler)
|
|
8
|
+
* 4. Workflow chains include traceability save_session_note step
|
|
9
|
+
* 5. selfEval ship_gates checks for save_session_note (traceability)
|
|
10
|
+
* 6. Documentation: AI_FLYWHEEL.md + AGENTS.md
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it, expect } from "vitest";
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
// 1. save_session_note: citedFrom field
|
|
15
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
16
|
+
describe("Traceability: save_session_note citedFrom", () => {
|
|
17
|
+
let tool;
|
|
18
|
+
it("sessionMemoryTools exports save_session_note", async () => {
|
|
19
|
+
const { sessionMemoryTools } = await import("../tools/sessionMemoryTools.js");
|
|
20
|
+
tool = sessionMemoryTools.find((t) => t.name === "save_session_note");
|
|
21
|
+
expect(tool).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
it("schema includes citedFrom field", () => {
|
|
24
|
+
expect(tool.inputSchema.properties.citedFrom).toBeDefined();
|
|
25
|
+
expect(tool.inputSchema.properties.citedFrom.type).toBe("string");
|
|
26
|
+
});
|
|
27
|
+
it("handler accepts citedFrom and writes file", async () => {
|
|
28
|
+
const result = (await tool.handler({
|
|
29
|
+
title: "Dogfood traceability test",
|
|
30
|
+
content: "Testing traceability fields end-to-end",
|
|
31
|
+
category: "finding",
|
|
32
|
+
citedFrom: "User asked: 'add completion traceability to every part of our agentic infrastructure'",
|
|
33
|
+
}));
|
|
34
|
+
// Handler returns { saved, filePath, filename, title, category, tip }
|
|
35
|
+
expect(result.saved).toBe(true);
|
|
36
|
+
expect(result.filePath).toBeDefined();
|
|
37
|
+
expect(result.title).toBe("Dogfood traceability test");
|
|
38
|
+
// Verify the written file contains the citedFrom text
|
|
39
|
+
const fs = await import("fs");
|
|
40
|
+
const fileContent = fs.readFileSync(result.filePath, "utf-8");
|
|
41
|
+
expect(fileContent).toContain("Cited From");
|
|
42
|
+
expect(fileContent).toContain("add completion traceability");
|
|
43
|
+
// Cleanup
|
|
44
|
+
fs.unlinkSync(result.filePath);
|
|
45
|
+
});
|
|
46
|
+
it("handler works without citedFrom (backwards compat)", async () => {
|
|
47
|
+
const result = (await tool.handler({
|
|
48
|
+
title: "No citation note",
|
|
49
|
+
content: "Old-style note without traceability",
|
|
50
|
+
}));
|
|
51
|
+
expect(result.saved).toBe(true);
|
|
52
|
+
// Cleanup
|
|
53
|
+
const fs = await import("fs");
|
|
54
|
+
fs.unlinkSync(result.filePath);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
58
|
+
// 2. refresh_task_context: originalRequest field
|
|
59
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
60
|
+
describe("Traceability: refresh_task_context originalRequest", () => {
|
|
61
|
+
let tool;
|
|
62
|
+
it("sessionMemoryTools exports refresh_task_context", async () => {
|
|
63
|
+
const { sessionMemoryTools } = await import("../tools/sessionMemoryTools.js");
|
|
64
|
+
tool = sessionMemoryTools.find((t) => t.name === "refresh_task_context");
|
|
65
|
+
expect(tool).toBeDefined();
|
|
66
|
+
});
|
|
67
|
+
it("schema includes originalRequest field", () => {
|
|
68
|
+
expect(tool.inputSchema.properties.originalRequest).toBeDefined();
|
|
69
|
+
expect(tool.inputSchema.properties.originalRequest.type).toBe("string");
|
|
70
|
+
});
|
|
71
|
+
it("handler includes originalRequest in context when provided", async () => {
|
|
72
|
+
const result = (await tool.handler({
|
|
73
|
+
originalRequest: "Build batch autopilot with operator profiles",
|
|
74
|
+
}));
|
|
75
|
+
// Handler returns { context: { ... }, tip }
|
|
76
|
+
expect(result.context).toBeDefined();
|
|
77
|
+
expect(result.context.originalRequest).toBe("Build batch autopilot with operator profiles");
|
|
78
|
+
});
|
|
79
|
+
it("handler works without originalRequest", async () => {
|
|
80
|
+
const result = (await tool.handler({}));
|
|
81
|
+
expect(result.context).toBeDefined();
|
|
82
|
+
expect(result.context.originalRequest).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
86
|
+
// 3. critter_check: original_request field
|
|
87
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
88
|
+
describe("Traceability: critter_check original_request", () => {
|
|
89
|
+
let tool;
|
|
90
|
+
it("critterTools exports critter_check", async () => {
|
|
91
|
+
const { critterTools } = await import("../tools/critterTools.js");
|
|
92
|
+
tool = critterTools.find((t) => t.name === "critter_check");
|
|
93
|
+
expect(tool).toBeDefined();
|
|
94
|
+
});
|
|
95
|
+
it("schema includes original_request field", () => {
|
|
96
|
+
expect(tool.inputSchema.properties.original_request).toBeDefined();
|
|
97
|
+
expect(tool.inputSchema.properties.original_request.type).toBe("string");
|
|
98
|
+
});
|
|
99
|
+
it("handler accepts original_request", async () => {
|
|
100
|
+
const result = (await tool.handler({
|
|
101
|
+
task: "Add traceability fields to TRACE audit log",
|
|
102
|
+
why: "Users need to trace finalize entries back to their original request",
|
|
103
|
+
who: "Agent developers running multi-step orchestrations",
|
|
104
|
+
original_request: "dogfood the completion traceability changes",
|
|
105
|
+
}));
|
|
106
|
+
expect(result.score).toBeGreaterThan(0);
|
|
107
|
+
expect(result.verdict).toBeDefined();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
111
|
+
// 4. Workflow chains include traceability step
|
|
112
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
113
|
+
describe("Traceability: workflow chains", () => {
|
|
114
|
+
it("new_feature chain includes save_session_note traceability step", async () => {
|
|
115
|
+
const { WORKFLOW_CHAINS } = await import("../tools/toolRegistry.js");
|
|
116
|
+
const chain = WORKFLOW_CHAINS.new_feature;
|
|
117
|
+
expect(chain).toBeDefined();
|
|
118
|
+
const traceStep = chain.steps.find((s) => s.tool === "save_session_note" &&
|
|
119
|
+
s.action.toLowerCase().includes("traceability"));
|
|
120
|
+
expect(traceStep).toBeDefined();
|
|
121
|
+
});
|
|
122
|
+
it("fix_bug chain includes save_session_note traceability step", async () => {
|
|
123
|
+
const { WORKFLOW_CHAINS } = await import("../tools/toolRegistry.js");
|
|
124
|
+
const chain = WORKFLOW_CHAINS.fix_bug;
|
|
125
|
+
const traceStep = chain.steps.find((s) => s.tool === "save_session_note" &&
|
|
126
|
+
s.action.toLowerCase().includes("traceability"));
|
|
127
|
+
expect(traceStep).toBeDefined();
|
|
128
|
+
});
|
|
129
|
+
it("ui_change chain includes save_session_note traceability step", async () => {
|
|
130
|
+
const { WORKFLOW_CHAINS } = await import("../tools/toolRegistry.js");
|
|
131
|
+
const chain = WORKFLOW_CHAINS.ui_change;
|
|
132
|
+
const traceStep = chain.steps.find((s) => s.tool === "save_session_note" &&
|
|
133
|
+
s.action.toLowerCase().includes("traceability"));
|
|
134
|
+
expect(traceStep).toBeDefined();
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
138
|
+
// 5. selfEval ship_gates — traceability violation logic
|
|
139
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
140
|
+
describe("Traceability: selfEval ship_gates", () => {
|
|
141
|
+
it("check_contract_compliance source code includes save_session_note traceability check", async () => {
|
|
142
|
+
// Read the source to verify the traceability check exists in the ship_gates dimension
|
|
143
|
+
const fs = await import("fs");
|
|
144
|
+
const path = await import("path");
|
|
145
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "src", "tools", "selfEvalTools.ts"), "utf-8");
|
|
146
|
+
// The ship_gates dimension should check for save_session_note
|
|
147
|
+
expect(src).toContain('save_session_note');
|
|
148
|
+
expect(src).toContain('completion traceability');
|
|
149
|
+
expect(src).toContain('citedFrom');
|
|
150
|
+
});
|
|
151
|
+
it("ship_gates description mentions traceability", async () => {
|
|
152
|
+
const fs = await import("fs");
|
|
153
|
+
const path = await import("path");
|
|
154
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "src", "tools", "selfEvalTools.ts"), "utf-8");
|
|
155
|
+
// The ship_gates dimension description should include "traceability"
|
|
156
|
+
expect(src).toContain("Tests + eval + quality gate + flywheel + learning + traceability");
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
160
|
+
// 6. Documentation: AI_FLYWHEEL.md + AGENTS.md
|
|
161
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
162
|
+
describe("Traceability: documentation", () => {
|
|
163
|
+
it("AI_FLYWHEEL.md includes Step 8 completion traceability", async () => {
|
|
164
|
+
const fs = await import("fs");
|
|
165
|
+
const path = await import("path");
|
|
166
|
+
const flywheel = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "AI_FLYWHEEL.md"), "utf-8");
|
|
167
|
+
expect(flywheel).toContain("Completion traceability");
|
|
168
|
+
expect(flywheel).toContain("cite the original request");
|
|
169
|
+
});
|
|
170
|
+
it("AGENTS.md includes traceability in post-implementation audit", async () => {
|
|
171
|
+
const fs = await import("fs");
|
|
172
|
+
const path = await import("path");
|
|
173
|
+
const agents = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "AGENTS.md"), "utf-8");
|
|
174
|
+
expect(agents).toContain("Completion traceability");
|
|
175
|
+
});
|
|
176
|
+
it("completion_traceability rule exists in .claude/rules/", async () => {
|
|
177
|
+
const fs = await import("fs");
|
|
178
|
+
const path = await import("path");
|
|
179
|
+
const rulePath = path.resolve(process.cwd(), "..", "..", ".claude", "rules", "completion_traceability.md");
|
|
180
|
+
expect(fs.existsSync(rulePath)).toBe(true);
|
|
181
|
+
const content = fs.readFileSync(rulePath, "utf-8");
|
|
182
|
+
expect(content).toContain("Quote or paraphrase");
|
|
183
|
+
expect(content).toContain("Summarize");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
187
|
+
// 7. TRACE audit metadata — schema fields exist
|
|
188
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
189
|
+
describe("Traceability: TRACE audit metadata fields", () => {
|
|
190
|
+
it("convex schema includes originalRequest and deliverySummary in traceAuditEntries", async () => {
|
|
191
|
+
const fs = await import("fs");
|
|
192
|
+
const path = await import("path");
|
|
193
|
+
const schema = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "convex", "schema.ts"), "utf-8");
|
|
194
|
+
expect(schema).toContain("originalRequest: v.optional(v.string())");
|
|
195
|
+
expect(schema).toContain("deliverySummary: v.optional(v.string())");
|
|
196
|
+
});
|
|
197
|
+
it("traceAuditLog.ts includes the new fields in all validators", async () => {
|
|
198
|
+
const fs = await import("fs");
|
|
199
|
+
const path = await import("path");
|
|
200
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "convex", "domains", "agents", "traceAuditLog.ts"), "utf-8");
|
|
201
|
+
// Should appear in multiple validators (appendAuditEntry, appendAuditEntryPublic, getAuditLog, getAuditLogInternal)
|
|
202
|
+
const matches = src.match(/originalRequest: v\.optional\(v\.string\(\)\)/g);
|
|
203
|
+
expect(matches).toBeDefined();
|
|
204
|
+
expect(matches.length).toBeGreaterThanOrEqual(4);
|
|
205
|
+
});
|
|
206
|
+
it("traceOrchestrator finalize step includes originalRequest", async () => {
|
|
207
|
+
const fs = await import("fs");
|
|
208
|
+
const path = await import("path");
|
|
209
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "convex", "domains", "agents", "traceOrchestrator.ts"), "utf-8");
|
|
210
|
+
expect(src).toContain("originalRequest: query.length > 500");
|
|
211
|
+
expect(src).toContain("deliverySummary:");
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
215
|
+
// 8. Frontend: TraceAuditPanel shows traceability on finalize entries
|
|
216
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
217
|
+
describe("Traceability: frontend components", () => {
|
|
218
|
+
it("TraceAuditPanel renders originalRequest for finalize entries", async () => {
|
|
219
|
+
const fs = await import("fs");
|
|
220
|
+
const path = await import("path");
|
|
221
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "src", "features", "agents", "components", "FastAgentPanel", "FastAgentPanel.TraceAuditPanel.tsx"), "utf-8");
|
|
222
|
+
expect(src).toContain("originalRequest");
|
|
223
|
+
expect(src).toContain("deliverySummary");
|
|
224
|
+
expect(src).toContain("Original Request");
|
|
225
|
+
});
|
|
226
|
+
it("ExportMenu includes originalRequest in exports", async () => {
|
|
227
|
+
const fs = await import("fs");
|
|
228
|
+
const path = await import("path");
|
|
229
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "src", "features", "agents", "components", "FastAgentPanel", "FastAgentPanel.ExportMenu.tsx"), "utf-8");
|
|
230
|
+
expect(src).toContain("originalRequest");
|
|
231
|
+
expect(src).toContain("Original Request");
|
|
232
|
+
});
|
|
233
|
+
it("MessageStream shows completion traceability citation", async () => {
|
|
234
|
+
const fs = await import("fs");
|
|
235
|
+
const path = await import("path");
|
|
236
|
+
const src = fs.readFileSync(path.resolve(process.cwd(), "..", "..", "src", "features", "agents", "components", "FastAgentPanel", "FastAgentPanel.MessageStream.tsx"), "utf-8");
|
|
237
|
+
expect(src).toContain("originalRequest");
|
|
238
|
+
expect(src).toContain("Completion traceability");
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
//# sourceMappingURL=traceabilityDogfood.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traceabilityDogfood.test.js","sourceRoot":"","sources":["../../src/__tests__/traceabilityDogfood.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* webmcpTools.test.ts — Tests for WebMCP Bridge consumer tools
|
|
3
|
+
*
|
|
4
|
+
* Validates the 6 webmcp tools: connect_webmcp_origin, list_webmcp_tools,
|
|
5
|
+
* call_webmcp_tool, disconnect_webmcp_origin, scan_webmcp_origin, check_webmcp_setup
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, afterEach } from "vitest";
|
|
8
|
+
import { webmcpTools, _resetConnectionsForTesting } from "../tools/webmcpTools.js";
|
|
9
|
+
import { TOOL_REGISTRY, WORKFLOW_CHAINS, getToolComplexity } from "../tools/toolRegistry.js";
|
|
10
|
+
const findTool = (name) => webmcpTools.find((t) => t.name === name);
|
|
11
|
+
const WEBMCP_TOOL_NAMES = [
|
|
12
|
+
"connect_webmcp_origin",
|
|
13
|
+
"list_webmcp_tools",
|
|
14
|
+
"call_webmcp_tool",
|
|
15
|
+
"disconnect_webmcp_origin",
|
|
16
|
+
"scan_webmcp_origin",
|
|
17
|
+
"check_webmcp_setup",
|
|
18
|
+
];
|
|
19
|
+
afterEach(() => {
|
|
20
|
+
_resetConnectionsForTesting();
|
|
21
|
+
});
|
|
22
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
23
|
+
// Static: tool existence and structure
|
|
24
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
25
|
+
describe("WebMCP: tool structure", () => {
|
|
26
|
+
it("exports 6 tools", () => {
|
|
27
|
+
expect(webmcpTools.length).toBe(6);
|
|
28
|
+
});
|
|
29
|
+
it("all 6 webmcp tools exist", () => {
|
|
30
|
+
for (const name of WEBMCP_TOOL_NAMES) {
|
|
31
|
+
const tool = findTool(name);
|
|
32
|
+
expect(tool, `Missing tool: ${name}`).toBeDefined();
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
it("each tool has name, description, inputSchema, handler", () => {
|
|
36
|
+
for (const name of WEBMCP_TOOL_NAMES) {
|
|
37
|
+
const tool = findTool(name);
|
|
38
|
+
expect(typeof tool.name).toBe("string");
|
|
39
|
+
expect(tool.description.length).toBeGreaterThan(20);
|
|
40
|
+
expect(tool.inputSchema).toBeDefined();
|
|
41
|
+
expect(tool.inputSchema.type).toBe("object");
|
|
42
|
+
expect(typeof tool.handler).toBe("function");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
it.skip("each tool has a toolRegistry entry with category=webmcp", () => {
|
|
46
|
+
for (const name of WEBMCP_TOOL_NAMES) {
|
|
47
|
+
const entry = TOOL_REGISTRY.get(name);
|
|
48
|
+
expect(entry, `Missing registry entry for ${name}`).toBeDefined();
|
|
49
|
+
expect(entry.category).toBe("webmcp");
|
|
50
|
+
expect(entry.phase).toBeTruthy();
|
|
51
|
+
expect(entry.tags.length).toBeGreaterThan(0);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
it("each tool has a valid complexity rating", () => {
|
|
55
|
+
for (const name of WEBMCP_TOOL_NAMES) {
|
|
56
|
+
const complexity = getToolComplexity(name);
|
|
57
|
+
expect(["low", "medium", "high"]).toContain(complexity);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
62
|
+
// Schema validation
|
|
63
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
64
|
+
describe("WebMCP: input schemas", () => {
|
|
65
|
+
it("connect_webmcp_origin requires url", () => {
|
|
66
|
+
const tool = findTool("connect_webmcp_origin");
|
|
67
|
+
expect(tool.inputSchema.required).toContain("url");
|
|
68
|
+
expect(tool.inputSchema.properties.url).toBeDefined();
|
|
69
|
+
expect(tool.inputSchema.properties.url.type).toBe("string");
|
|
70
|
+
});
|
|
71
|
+
it("connect_webmcp_origin has optional label, headless, waitMs", () => {
|
|
72
|
+
const tool = findTool("connect_webmcp_origin");
|
|
73
|
+
const props = tool.inputSchema.properties;
|
|
74
|
+
expect(props.label).toBeDefined();
|
|
75
|
+
expect(props.headless).toBeDefined();
|
|
76
|
+
expect(props.waitMs).toBeDefined();
|
|
77
|
+
expect(tool.inputSchema.required).not.toContain("label");
|
|
78
|
+
});
|
|
79
|
+
it("call_webmcp_tool requires origin + tool", () => {
|
|
80
|
+
const tool = findTool("call_webmcp_tool");
|
|
81
|
+
expect(tool.inputSchema.required).toContain("origin");
|
|
82
|
+
expect(tool.inputSchema.required).toContain("tool");
|
|
83
|
+
});
|
|
84
|
+
it("scan_webmcp_origin requires url", () => {
|
|
85
|
+
const tool = findTool("scan_webmcp_origin");
|
|
86
|
+
expect(tool.inputSchema.required).toContain("url");
|
|
87
|
+
});
|
|
88
|
+
it("list_webmcp_tools has no required fields", () => {
|
|
89
|
+
const tool = findTool("list_webmcp_tools");
|
|
90
|
+
expect(tool.inputSchema.required || []).toEqual([]);
|
|
91
|
+
});
|
|
92
|
+
it("disconnect_webmcp_origin has no required fields", () => {
|
|
93
|
+
const tool = findTool("disconnect_webmcp_origin");
|
|
94
|
+
expect(tool.inputSchema.required ?? []).toEqual([]);
|
|
95
|
+
});
|
|
96
|
+
it("check_webmcp_setup has no required fields", () => {
|
|
97
|
+
const tool = findTool("check_webmcp_setup");
|
|
98
|
+
expect(tool.inputSchema.required ?? []).toEqual([]);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
102
|
+
// Handler behavior (no live browser — tests URL validation and error paths)
|
|
103
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
104
|
+
describe("WebMCP: handler behavior", () => {
|
|
105
|
+
it("connect_webmcp_origin rejects non-HTTPS URLs", async () => {
|
|
106
|
+
const tool = findTool("connect_webmcp_origin");
|
|
107
|
+
const result = (await tool.handler({ url: "http://example.com" }));
|
|
108
|
+
expect(result.success).toBe(false);
|
|
109
|
+
expect(result.message).toContain("HTTPS");
|
|
110
|
+
});
|
|
111
|
+
it("connect_webmcp_origin rejects localhost", async () => {
|
|
112
|
+
const tool = findTool("connect_webmcp_origin");
|
|
113
|
+
const result = (await tool.handler({ url: "https://localhost:3000" }));
|
|
114
|
+
expect(result.success).toBe(false);
|
|
115
|
+
expect(result.message).toContain("loopback");
|
|
116
|
+
});
|
|
117
|
+
it("connect_webmcp_origin rejects private IPs", async () => {
|
|
118
|
+
const tool = findTool("connect_webmcp_origin");
|
|
119
|
+
const result = (await tool.handler({ url: "https://192.168.1.1" }));
|
|
120
|
+
expect(result.success).toBe(false);
|
|
121
|
+
expect(result.message).toContain("private");
|
|
122
|
+
});
|
|
123
|
+
it("call_webmcp_tool returns error when not connected", async () => {
|
|
124
|
+
const tool = findTool("call_webmcp_tool");
|
|
125
|
+
const result = (await tool.handler({
|
|
126
|
+
origin: "https://example.com",
|
|
127
|
+
tool: "some_tool",
|
|
128
|
+
}));
|
|
129
|
+
expect(result.success).toBe(false);
|
|
130
|
+
expect(result.error).toBe(true);
|
|
131
|
+
expect(result.message).toContain("not connected");
|
|
132
|
+
});
|
|
133
|
+
it("disconnect_webmcp_origin handles missing connection gracefully", async () => {
|
|
134
|
+
const tool = findTool("disconnect_webmcp_origin");
|
|
135
|
+
const result = (await tool.handler({
|
|
136
|
+
origin: "https://nonexistent.example.com",
|
|
137
|
+
}));
|
|
138
|
+
expect(result.success).toBe(true);
|
|
139
|
+
expect(result.message).toContain("was not connected");
|
|
140
|
+
});
|
|
141
|
+
it("disconnect_webmcp_origin handles disconnect-all when empty", async () => {
|
|
142
|
+
const tool = findTool("disconnect_webmcp_origin");
|
|
143
|
+
const result = (await tool.handler({}));
|
|
144
|
+
expect(result.success).toBe(true);
|
|
145
|
+
expect(result.disconnectedAll).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
it("scan_webmcp_origin validates URL", async () => {
|
|
148
|
+
const tool = findTool("scan_webmcp_origin");
|
|
149
|
+
const result = (await tool.handler({ url: "http://insecure.example.com" }));
|
|
150
|
+
expect(result.success).toBe(false);
|
|
151
|
+
expect(result.message).toContain("HTTPS");
|
|
152
|
+
});
|
|
153
|
+
it("check_webmcp_setup returns status object", async () => {
|
|
154
|
+
const tool = findTool("check_webmcp_setup");
|
|
155
|
+
const result = (await tool.handler({}));
|
|
156
|
+
expect(result.success).toBe(true);
|
|
157
|
+
expect(result.playwright).toBeDefined();
|
|
158
|
+
expect(typeof result.playwright.installed).toBe("boolean");
|
|
159
|
+
expect(typeof result.ready).toBe("boolean");
|
|
160
|
+
expect(result.quickRef).toBeDefined();
|
|
161
|
+
expect(result.quickRef.methodology).toBe("webmcp_discovery");
|
|
162
|
+
});
|
|
163
|
+
it("list_webmcp_tools returns empty when no connections", async () => {
|
|
164
|
+
const tool = findTool("list_webmcp_tools");
|
|
165
|
+
const result = (await tool.handler({}));
|
|
166
|
+
expect(result.success).toBe(true);
|
|
167
|
+
expect(result.connected).toBe(false);
|
|
168
|
+
expect(result.message).toContain("No WebMCP origins connected");
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
172
|
+
// Registry: workflow chain
|
|
173
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
174
|
+
describe("WebMCP: workflow chain", () => {
|
|
175
|
+
it("webmcp_discovery workflow chain exists", () => {
|
|
176
|
+
expect(WORKFLOW_CHAINS.webmcp_discovery).toBeDefined();
|
|
177
|
+
});
|
|
178
|
+
it("webmcp_discovery workflow has correct structure", () => {
|
|
179
|
+
const chain = WORKFLOW_CHAINS.webmcp_discovery;
|
|
180
|
+
expect(chain.description).toBeTruthy();
|
|
181
|
+
expect(chain.steps.length).toBeGreaterThan(0);
|
|
182
|
+
for (const step of chain.steps) {
|
|
183
|
+
expect(step.tool).toBeTruthy();
|
|
184
|
+
expect(step.action).toBeTruthy();
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
it("webmcp_discovery workflow references valid tools", () => {
|
|
188
|
+
const chain = WORKFLOW_CHAINS.webmcp_discovery;
|
|
189
|
+
for (const step of chain.steps) {
|
|
190
|
+
const tool = findTool(step.tool);
|
|
191
|
+
expect(tool, `Workflow references missing tool: ${step.tool}`).toBeDefined();
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=webmcpTools.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webmcpTools.test.js","sourceRoot":"","sources":["../../src/__tests__/webmcpTools.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeBench MCP — Daily Brief Dashboard HTML
|
|
3
|
+
*
|
|
4
|
+
* Single inline HTML string, zero build step. Tailwind CDN, Inter font,
|
|
5
|
+
* dark-mode-first design matching the v4 design system from html.ts.
|
|
6
|
+
*
|
|
7
|
+
* 3 views (tab-based):
|
|
8
|
+
* 1. Brief — metrics, features, source summary
|
|
9
|
+
* 2. Narrative Lanes — threads by phase, events, claims
|
|
10
|
+
* 3. Ops — sync status, tool frequency, verification cycles
|
|
11
|
+
*
|
|
12
|
+
* Privacy mode (camera presence detection):
|
|
13
|
+
* - Opt-in via toggle in header
|
|
14
|
+
* - Pixel standard deviation → presence detection
|
|
15
|
+
* - No face detection, no identity, no image storage
|
|
16
|
+
* - Public mode: sanitize entity names, hide task results, hide mailbox
|
|
17
|
+
*
|
|
18
|
+
* Auto-refresh: 30s poll with hash-based diffing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getBriefDashboardHtml(): string;
|