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 @@
|
|
|
1
|
+
{"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/dashboard/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA87CD,CAAC;AACT,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeBench MCP — Local Dashboard Server
|
|
3
|
+
*
|
|
4
|
+
* Serves a local web dashboard showing the full UI Dive flywheel cycle:
|
|
5
|
+
* explored routes, components, interactions, screenshots, bugs,
|
|
6
|
+
* code locations, fixes, changelogs, generated tests, code reviews.
|
|
7
|
+
*
|
|
8
|
+
* Inspired by Serena MCP's local dashboard. Zero external deps — uses
|
|
9
|
+
* Node's built-in http module + reads from existing SQLite DB.
|
|
10
|
+
*/
|
|
11
|
+
import type Database from "better-sqlite3";
|
|
12
|
+
/** Start the dashboard HTTP server. Returns the port it's listening on. */
|
|
13
|
+
export declare function startDashboardServer(db: Database.Database, preferredPort?: number): Promise<number>;
|
|
14
|
+
/** Stop the dashboard server */
|
|
15
|
+
export declare function stopDashboardServer(): void;
|
|
16
|
+
/** Get the current dashboard URL */
|
|
17
|
+
export declare function getDashboardUrl(): string | null;
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NodeBench MCP — Local Dashboard Server
|
|
3
|
+
*
|
|
4
|
+
* Serves a local web dashboard showing the full UI Dive flywheel cycle:
|
|
5
|
+
* explored routes, components, interactions, screenshots, bugs,
|
|
6
|
+
* code locations, fixes, changelogs, generated tests, code reviews.
|
|
7
|
+
*
|
|
8
|
+
* Inspired by Serena MCP's local dashboard. Zero external deps — uses
|
|
9
|
+
* Node's built-in http module + reads from existing SQLite DB.
|
|
10
|
+
*/
|
|
11
|
+
import { createServer } from "node:http";
|
|
12
|
+
import { getDashboardHtml } from "./html.js";
|
|
13
|
+
let _server = null;
|
|
14
|
+
let _port = 0;
|
|
15
|
+
/** Start the dashboard HTTP server. Returns the port it's listening on. */
|
|
16
|
+
export function startDashboardServer(db, preferredPort = 6274) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
if (_server) {
|
|
19
|
+
resolve(_port);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
_server = createServer((req, res) => handleRequest(db, req, res));
|
|
23
|
+
let attempts = 0;
|
|
24
|
+
const maxAttempts = 10;
|
|
25
|
+
function tryListen(port) {
|
|
26
|
+
_server.listen(port, "127.0.0.1", () => {
|
|
27
|
+
_port = port;
|
|
28
|
+
resolve(_port);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
_server.on("error", (err) => {
|
|
32
|
+
if (err.code === "EADDRINUSE" && attempts < maxAttempts) {
|
|
33
|
+
attempts++;
|
|
34
|
+
tryListen(preferredPort + attempts);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
reject(err);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
tryListen(preferredPort);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/** Stop the dashboard server */
|
|
44
|
+
export function stopDashboardServer() {
|
|
45
|
+
if (_server) {
|
|
46
|
+
_server.close();
|
|
47
|
+
_server = null;
|
|
48
|
+
_port = 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** Get the current dashboard URL */
|
|
52
|
+
export function getDashboardUrl() {
|
|
53
|
+
return _port ? `http://127.0.0.1:${_port}` : null;
|
|
54
|
+
}
|
|
55
|
+
// ── Request Router ──────────────────────────────────────────────────
|
|
56
|
+
function handleRequest(db, req, res) {
|
|
57
|
+
const url = new URL(req.url || "/", `http://127.0.0.1:${_port}`);
|
|
58
|
+
const path = url.pathname;
|
|
59
|
+
// CORS for local dev
|
|
60
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
61
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
62
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
63
|
+
if (req.method === "OPTIONS") {
|
|
64
|
+
res.writeHead(204);
|
|
65
|
+
res.end();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
if (path === "/" || path === "/index.html") {
|
|
70
|
+
serveHtml(res);
|
|
71
|
+
}
|
|
72
|
+
else if (path === "/api/sessions") {
|
|
73
|
+
apiSessions(db, res);
|
|
74
|
+
}
|
|
75
|
+
else if (path.startsWith("/api/screenshot/") && path.endsWith("/image")) {
|
|
76
|
+
const ssId = decodeURIComponent(path.split("/api/screenshot/")[1].split("/image")[0]);
|
|
77
|
+
apiScreenshotImage(db, ssId, res);
|
|
78
|
+
}
|
|
79
|
+
else if (path.startsWith("/api/session/")) {
|
|
80
|
+
const sessionId = decodeURIComponent(path.split("/api/session/")[1].split("/")[0]);
|
|
81
|
+
const sub = path.split(sessionId + "/")[1] || "overview";
|
|
82
|
+
apiSessionDetail(db, sessionId, sub, res);
|
|
83
|
+
}
|
|
84
|
+
else if (path === "/api/latest") {
|
|
85
|
+
apiLatestSession(db, res);
|
|
86
|
+
}
|
|
87
|
+
else if (path === "/api/agents/status") {
|
|
88
|
+
apiAgentStatus(db, res);
|
|
89
|
+
}
|
|
90
|
+
else if (path === "/api/agents/activity") {
|
|
91
|
+
apiAgentActivity(db, res);
|
|
92
|
+
}
|
|
93
|
+
else if (path === "/api/agents/mailbox") {
|
|
94
|
+
apiAgentMailbox(db, res);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
98
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
103
|
+
res.end(JSON.stringify({ error: err.message }));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ── HTML ────────────────────────────────────────────────────────────
|
|
107
|
+
function serveHtml(res) {
|
|
108
|
+
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
109
|
+
res.end(getDashboardHtml());
|
|
110
|
+
}
|
|
111
|
+
// ── API: List sessions ──────────────────────────────────────────────
|
|
112
|
+
function apiSessions(db, res) {
|
|
113
|
+
const rows = db.prepare(`
|
|
114
|
+
SELECT s.id, s.app_url, s.app_name, s.status, s.created_at, s.completed_at,
|
|
115
|
+
(SELECT COUNT(*) FROM ui_dive_components WHERE session_id = s.id) as component_count,
|
|
116
|
+
(SELECT COUNT(*) FROM ui_dive_bugs WHERE session_id = s.id) as bug_count,
|
|
117
|
+
(SELECT COUNT(*) FROM ui_dive_bugs WHERE session_id = s.id AND status = 'resolved') as bugs_resolved,
|
|
118
|
+
(SELECT COUNT(*) FROM ui_dive_interactions WHERE session_id = s.id) as interaction_count,
|
|
119
|
+
(SELECT COUNT(*) FROM ui_dive_fix_verifications WHERE session_id = s.id) as fix_count,
|
|
120
|
+
(SELECT COUNT(*) FROM ui_dive_code_reviews WHERE session_id = s.id) as review_count
|
|
121
|
+
FROM ui_dive_sessions s
|
|
122
|
+
ORDER BY s.created_at DESC
|
|
123
|
+
LIMIT 50
|
|
124
|
+
`).all();
|
|
125
|
+
json(res, rows);
|
|
126
|
+
}
|
|
127
|
+
// ── API: Latest session redirect ────────────────────────────────────
|
|
128
|
+
function apiLatestSession(db, res) {
|
|
129
|
+
const row = db.prepare(`
|
|
130
|
+
SELECT id FROM ui_dive_sessions ORDER BY created_at DESC LIMIT 1
|
|
131
|
+
`).get();
|
|
132
|
+
if (!row) {
|
|
133
|
+
json(res, { error: "No sessions found" }, 404);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// Return full overview for latest
|
|
137
|
+
apiSessionDetail(db, row.id, "overview", res);
|
|
138
|
+
}
|
|
139
|
+
// ── API: Session detail ─────────────────────────────────────────────
|
|
140
|
+
function apiSessionDetail(db, sessionId, sub, res) {
|
|
141
|
+
switch (sub) {
|
|
142
|
+
case "overview":
|
|
143
|
+
return apiOverview(db, sessionId, res);
|
|
144
|
+
case "components":
|
|
145
|
+
return apiComponents(db, sessionId, res);
|
|
146
|
+
case "bugs":
|
|
147
|
+
return apiBugs(db, sessionId, res);
|
|
148
|
+
case "interactions":
|
|
149
|
+
return apiInteractions(db, sessionId, res);
|
|
150
|
+
case "screenshots":
|
|
151
|
+
return apiScreenshots(db, sessionId, res);
|
|
152
|
+
case "code-locations":
|
|
153
|
+
return apiCodeLocations(db, sessionId, res);
|
|
154
|
+
case "fixes":
|
|
155
|
+
return apiFixes(db, sessionId, res);
|
|
156
|
+
case "changelogs":
|
|
157
|
+
return apiChangelogs(db, sessionId, res);
|
|
158
|
+
case "tests":
|
|
159
|
+
return apiTests(db, sessionId, res);
|
|
160
|
+
case "reviews":
|
|
161
|
+
return apiReviews(db, sessionId, res);
|
|
162
|
+
case "design-issues":
|
|
163
|
+
return apiDesignIssues(db, sessionId, res);
|
|
164
|
+
default:
|
|
165
|
+
json(res, { error: `Unknown sub-route: ${sub}` }, 404);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function apiOverview(db, sid, res) {
|
|
169
|
+
const session = db.prepare("SELECT * FROM ui_dive_sessions WHERE id = ?").get(sid);
|
|
170
|
+
if (!session) {
|
|
171
|
+
json(res, { error: "Session not found" }, 404);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const stats = {
|
|
175
|
+
components: db.prepare("SELECT COUNT(*) as c FROM ui_dive_components WHERE session_id = ?").get(sid),
|
|
176
|
+
interactions: db.prepare("SELECT COUNT(*) as c FROM ui_dive_interactions WHERE session_id = ?").get(sid),
|
|
177
|
+
bugs: db.prepare("SELECT COUNT(*) as c FROM ui_dive_bugs WHERE session_id = ?").get(sid),
|
|
178
|
+
bugsOpen: db.prepare("SELECT COUNT(*) as c FROM ui_dive_bugs WHERE session_id = ? AND status = 'open'").get(sid),
|
|
179
|
+
bugsResolved: db.prepare("SELECT COUNT(*) as c FROM ui_dive_bugs WHERE session_id = ? AND status = 'resolved'").get(sid),
|
|
180
|
+
screenshots: db.prepare("SELECT COUNT(*) as c FROM ui_dive_screenshots WHERE session_id = ?").get(sid),
|
|
181
|
+
tests: db.prepare("SELECT COUNT(*) as c FROM ui_dive_interaction_tests WHERE session_id = ?").get(sid),
|
|
182
|
+
designIssues: db.prepare("SELECT COUNT(*) as c FROM ui_dive_design_issues WHERE session_id = ?").get(sid),
|
|
183
|
+
codeLocations: db.prepare("SELECT COUNT(*) as c FROM ui_dive_code_locations WHERE session_id = ?").get(sid),
|
|
184
|
+
fixes: db.prepare("SELECT COUNT(*) as c FROM ui_dive_fix_verifications WHERE session_id = ?").get(sid),
|
|
185
|
+
fixesVerified: db.prepare("SELECT COUNT(*) as c FROM ui_dive_fix_verifications WHERE session_id = ? AND verified = 1").get(sid),
|
|
186
|
+
changelogs: db.prepare("SELECT COUNT(*) as c FROM ui_dive_changelogs WHERE session_id = ?").get(sid),
|
|
187
|
+
generatedTests: db.prepare("SELECT COUNT(*) as c FROM ui_dive_generated_tests WHERE session_id = ?").get(sid),
|
|
188
|
+
codeReviews: db.prepare("SELECT COUNT(*) as c FROM ui_dive_code_reviews WHERE session_id = ?").get(sid),
|
|
189
|
+
};
|
|
190
|
+
const latestReview = db.prepare("SELECT score, summary, severity_counts, recommendations FROM ui_dive_code_reviews WHERE session_id = ? ORDER BY created_at DESC LIMIT 1").get(sid);
|
|
191
|
+
json(res, {
|
|
192
|
+
session,
|
|
193
|
+
stats: Object.fromEntries(Object.entries(stats).map(([k, v]) => [k, v?.c ?? 0])),
|
|
194
|
+
latestReview,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
function apiComponents(db, sid, res) {
|
|
198
|
+
json(res, db.prepare("SELECT * FROM ui_dive_components WHERE session_id = ? ORDER BY created_at").all(sid));
|
|
199
|
+
}
|
|
200
|
+
function apiBugs(db, sid, res) {
|
|
201
|
+
json(res, db.prepare(`
|
|
202
|
+
SELECT b.*, c.name as component_name
|
|
203
|
+
FROM ui_dive_bugs b
|
|
204
|
+
LEFT JOIN ui_dive_components c ON b.component_id = c.id
|
|
205
|
+
WHERE b.session_id = ?
|
|
206
|
+
ORDER BY
|
|
207
|
+
CASE b.severity WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 ELSE 3 END,
|
|
208
|
+
b.created_at
|
|
209
|
+
`).all(sid));
|
|
210
|
+
}
|
|
211
|
+
function apiInteractions(db, sid, res) {
|
|
212
|
+
json(res, db.prepare(`
|
|
213
|
+
SELECT i.*, c.name as component_name
|
|
214
|
+
FROM ui_dive_interactions i
|
|
215
|
+
LEFT JOIN ui_dive_components c ON i.component_id = c.id
|
|
216
|
+
WHERE i.session_id = ?
|
|
217
|
+
ORDER BY i.sequence_num
|
|
218
|
+
`).all(sid));
|
|
219
|
+
}
|
|
220
|
+
function apiScreenshots(db, sid, res) {
|
|
221
|
+
json(res, db.prepare("SELECT id, session_id, component_id, label, route, file_path, base64_thumbnail, width, height, metadata, created_at FROM ui_dive_screenshots WHERE session_id = ? ORDER BY created_at").all(sid));
|
|
222
|
+
}
|
|
223
|
+
/** Serve a screenshot as an actual PNG image */
|
|
224
|
+
function apiScreenshotImage(db, ssId, res) {
|
|
225
|
+
const row = db.prepare("SELECT base64_thumbnail, file_path FROM ui_dive_screenshots WHERE id = ?").get(ssId);
|
|
226
|
+
if (!row) {
|
|
227
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
228
|
+
res.end("Screenshot not found");
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Prefer inline base64, fall back to file on disk
|
|
232
|
+
if (row.base64_thumbnail) {
|
|
233
|
+
const buf = Buffer.from(row.base64_thumbnail, "base64");
|
|
234
|
+
res.writeHead(200, {
|
|
235
|
+
"Content-Type": "image/png",
|
|
236
|
+
"Content-Length": buf.length.toString(),
|
|
237
|
+
"Cache-Control": "public, max-age=86400",
|
|
238
|
+
});
|
|
239
|
+
res.end(buf);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (row.file_path) {
|
|
243
|
+
try {
|
|
244
|
+
const fs = require("node:fs");
|
|
245
|
+
const buf = fs.readFileSync(row.file_path);
|
|
246
|
+
res.writeHead(200, {
|
|
247
|
+
"Content-Type": "image/png",
|
|
248
|
+
"Content-Length": buf.length.toString(),
|
|
249
|
+
"Cache-Control": "public, max-age=86400",
|
|
250
|
+
});
|
|
251
|
+
res.end(buf);
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
255
|
+
res.end("Screenshot file not found on disk");
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
260
|
+
res.end("No image data available");
|
|
261
|
+
}
|
|
262
|
+
function apiCodeLocations(db, sid, res) {
|
|
263
|
+
json(res, db.prepare("SELECT * FROM ui_dive_code_locations WHERE session_id = ? ORDER BY created_at").all(sid));
|
|
264
|
+
}
|
|
265
|
+
function apiFixes(db, sid, res) {
|
|
266
|
+
json(res, db.prepare(`
|
|
267
|
+
SELECT f.*, b.title as bug_title, b.severity as bug_severity, b.status as bug_status
|
|
268
|
+
FROM ui_dive_fix_verifications f
|
|
269
|
+
LEFT JOIN ui_dive_bugs b ON f.bug_id = b.id
|
|
270
|
+
WHERE f.session_id = ?
|
|
271
|
+
ORDER BY f.created_at
|
|
272
|
+
`).all(sid));
|
|
273
|
+
}
|
|
274
|
+
function apiChangelogs(db, sid, res) {
|
|
275
|
+
json(res, db.prepare("SELECT * FROM ui_dive_changelogs WHERE session_id = ? ORDER BY created_at DESC").all(sid));
|
|
276
|
+
}
|
|
277
|
+
function apiTests(db, sid, res) {
|
|
278
|
+
json(res, db.prepare("SELECT * FROM ui_dive_generated_tests WHERE session_id = ? ORDER BY created_at").all(sid));
|
|
279
|
+
}
|
|
280
|
+
function apiReviews(db, sid, res) {
|
|
281
|
+
json(res, db.prepare("SELECT * FROM ui_dive_code_reviews WHERE session_id = ? ORDER BY created_at DESC").all(sid));
|
|
282
|
+
}
|
|
283
|
+
function apiDesignIssues(db, sid, res) {
|
|
284
|
+
json(res, db.prepare("SELECT * FROM ui_dive_design_issues WHERE session_id = ? ORDER BY created_at").all(sid));
|
|
285
|
+
}
|
|
286
|
+
// ── API: Agent Monitor ──────────────────────────────────────────────
|
|
287
|
+
function apiAgentStatus(db, res) {
|
|
288
|
+
// Only agents active in the last 2 hours (has recent calls OR a claimed task)
|
|
289
|
+
const roles = db.prepare(`
|
|
290
|
+
SELECT r.session_id, r.role, r.focus_area, r.created_at
|
|
291
|
+
FROM agent_roles r
|
|
292
|
+
WHERE EXISTS (
|
|
293
|
+
SELECT 1 FROM tool_call_log t
|
|
294
|
+
WHERE t.session_id = r.session_id AND t.created_at >= datetime('now', '-2 hours')
|
|
295
|
+
) OR EXISTS (
|
|
296
|
+
SELECT 1 FROM agent_tasks a
|
|
297
|
+
WHERE a.session_id = r.session_id AND a.status = 'claimed'
|
|
298
|
+
AND a.claimed_at >= datetime('now', '-4 hours')
|
|
299
|
+
)
|
|
300
|
+
ORDER BY r.created_at DESC
|
|
301
|
+
LIMIT 20
|
|
302
|
+
`).all();
|
|
303
|
+
const agents = roles.map(r => {
|
|
304
|
+
const task = db.prepare(`
|
|
305
|
+
SELECT task_key, description, claimed_at
|
|
306
|
+
FROM agent_tasks
|
|
307
|
+
WHERE session_id = ? AND status = 'claimed'
|
|
308
|
+
ORDER BY claimed_at DESC LIMIT 1
|
|
309
|
+
`).get(r.session_id);
|
|
310
|
+
const callCount = db.prepare(`
|
|
311
|
+
SELECT COUNT(*) as c FROM tool_call_log
|
|
312
|
+
WHERE session_id = ? AND created_at >= datetime('now', '-30 minutes')
|
|
313
|
+
`).get(r.session_id);
|
|
314
|
+
const lastCall = db.prepare(`
|
|
315
|
+
SELECT created_at FROM tool_call_log
|
|
316
|
+
WHERE session_id = ? ORDER BY created_at DESC LIMIT 1
|
|
317
|
+
`).get(r.session_id);
|
|
318
|
+
const budget = db.prepare(`
|
|
319
|
+
SELECT tokens_used, tokens_limit FROM context_budget_log
|
|
320
|
+
WHERE session_id = ? ORDER BY created_at DESC LIMIT 1
|
|
321
|
+
`).get(r.session_id);
|
|
322
|
+
const unread = db.prepare(`
|
|
323
|
+
SELECT COUNT(*) as c FROM agent_mailbox
|
|
324
|
+
WHERE (recipient_id = ? OR recipient_role = ?) AND read = 0
|
|
325
|
+
`).get(r.session_id, r.role);
|
|
326
|
+
return {
|
|
327
|
+
sessionId: r.session_id,
|
|
328
|
+
role: r.role,
|
|
329
|
+
focusArea: r.focus_area,
|
|
330
|
+
assignedAt: r.created_at,
|
|
331
|
+
currentTask: task ? { key: task.task_key, description: task.description, claimedAt: task.claimed_at } : null,
|
|
332
|
+
toolCallCount: callCount.c,
|
|
333
|
+
lastCallAt: lastCall?.created_at ?? null,
|
|
334
|
+
tokenBudget: budget
|
|
335
|
+
? { used: budget.tokens_used, limit: budget.tokens_limit, percent: Math.round((budget.tokens_used / budget.tokens_limit) * 100) }
|
|
336
|
+
: { used: 0, limit: 200000, percent: 0 },
|
|
337
|
+
unreadMessages: unread.c,
|
|
338
|
+
};
|
|
339
|
+
});
|
|
340
|
+
// Summary stats
|
|
341
|
+
const activeSessions = agents.map(a => a.sessionId);
|
|
342
|
+
const totalCalls = activeSessions.length > 0
|
|
343
|
+
? db.prepare(`SELECT COUNT(*) as c FROM tool_call_log WHERE session_id IN (${activeSessions.map(() => "?").join(",")})`)
|
|
344
|
+
.get(...activeSessions).c
|
|
345
|
+
: 0;
|
|
346
|
+
const claimedCount = agents.filter(a => a.currentTask).length;
|
|
347
|
+
const completedTasks = db.prepare(`
|
|
348
|
+
SELECT task_key, session_id, description, progress_note, released_at
|
|
349
|
+
FROM agent_tasks
|
|
350
|
+
WHERE status = 'released' AND released_at >= datetime('now', '-1 hour')
|
|
351
|
+
ORDER BY released_at DESC LIMIT 20
|
|
352
|
+
`).all();
|
|
353
|
+
json(res, {
|
|
354
|
+
agents,
|
|
355
|
+
completedTasks,
|
|
356
|
+
summary: {
|
|
357
|
+
activeAgents: agents.length,
|
|
358
|
+
activeTasks: claimedCount,
|
|
359
|
+
completedTasks: completedTasks.length,
|
|
360
|
+
totalCalls,
|
|
361
|
+
},
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function apiAgentActivity(db, res) {
|
|
365
|
+
// Only show calls from agents active in last 2 hours
|
|
366
|
+
const calls = db.prepare(`
|
|
367
|
+
SELECT t.tool_name, t.session_id, t.result_status, t.duration_ms, t.created_at
|
|
368
|
+
FROM tool_call_log t
|
|
369
|
+
WHERE EXISTS (
|
|
370
|
+
SELECT 1 FROM agent_roles r
|
|
371
|
+
WHERE r.session_id = t.session_id AND (
|
|
372
|
+
EXISTS (SELECT 1 FROM tool_call_log t2 WHERE t2.session_id = r.session_id AND t2.created_at >= datetime('now', '-2 hours'))
|
|
373
|
+
OR EXISTS (SELECT 1 FROM agent_tasks a WHERE a.session_id = r.session_id AND a.status = 'claimed')
|
|
374
|
+
)
|
|
375
|
+
)
|
|
376
|
+
ORDER BY t.created_at DESC LIMIT 30
|
|
377
|
+
`).all();
|
|
378
|
+
json(res, { calls, totalCalls: calls.length });
|
|
379
|
+
}
|
|
380
|
+
function apiAgentMailbox(db, res) {
|
|
381
|
+
// Deduplicate by subject+sender — keep only the latest of each
|
|
382
|
+
const messages = db.prepare(`
|
|
383
|
+
SELECT id, sender_id, recipient_id, recipient_role, category, priority, subject, body, created_at
|
|
384
|
+
FROM agent_mailbox
|
|
385
|
+
WHERE read = 0 AND id IN (
|
|
386
|
+
SELECT id FROM (
|
|
387
|
+
SELECT id, ROW_NUMBER() OVER (PARTITION BY sender_id, subject ORDER BY created_at DESC) as rn
|
|
388
|
+
FROM agent_mailbox WHERE read = 0
|
|
389
|
+
) WHERE rn = 1
|
|
390
|
+
)
|
|
391
|
+
ORDER BY
|
|
392
|
+
CASE priority WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'normal' THEN 2 ELSE 3 END,
|
|
393
|
+
created_at DESC
|
|
394
|
+
LIMIT 10
|
|
395
|
+
`).all();
|
|
396
|
+
json(res, { messages });
|
|
397
|
+
}
|
|
398
|
+
// ── Helpers ─────────────────────────────────────────────────────────
|
|
399
|
+
function json(res, data, status = 200) {
|
|
400
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
401
|
+
res.end(JSON.stringify(data));
|
|
402
|
+
}
|
|
403
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"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"}
|
package/dist/db.js
CHANGED
|
@@ -614,6 +614,44 @@ CREATE INDEX IF NOT EXISTS idx_dive_code_locations_bug ON ui_dive_code_locations
|
|
|
614
614
|
CREATE INDEX IF NOT EXISTS idx_dive_fix_verifications_bug ON ui_dive_fix_verifications(bug_id);
|
|
615
615
|
CREATE INDEX IF NOT EXISTS idx_dive_generated_tests_session ON ui_dive_generated_tests(session_id);
|
|
616
616
|
CREATE INDEX IF NOT EXISTS idx_dive_code_reviews_session ON ui_dive_code_reviews(session_id);
|
|
617
|
+
|
|
618
|
+
-- ═══════════════════════════════════════════
|
|
619
|
+
-- SKILL SELF-UPDATE PROTOCOL — Track rule/
|
|
620
|
+
-- memory file provenance, source hashes,
|
|
621
|
+
-- update triggers, sync history.
|
|
622
|
+
-- ═══════════════════════════════════════════
|
|
623
|
+
|
|
624
|
+
CREATE TABLE IF NOT EXISTS skills (
|
|
625
|
+
id TEXT PRIMARY KEY,
|
|
626
|
+
skill_id TEXT NOT NULL UNIQUE,
|
|
627
|
+
name TEXT NOT NULL,
|
|
628
|
+
file_path TEXT NOT NULL,
|
|
629
|
+
description TEXT,
|
|
630
|
+
source_files TEXT NOT NULL DEFAULT '[]',
|
|
631
|
+
source_hash TEXT,
|
|
632
|
+
update_triggers TEXT NOT NULL DEFAULT '[]',
|
|
633
|
+
update_instructions TEXT NOT NULL DEFAULT '[]',
|
|
634
|
+
last_synced_at TEXT,
|
|
635
|
+
status TEXT NOT NULL DEFAULT 'fresh',
|
|
636
|
+
metadata TEXT,
|
|
637
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
638
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
CREATE TABLE IF NOT EXISTS skill_sync_history (
|
|
642
|
+
id TEXT PRIMARY KEY,
|
|
643
|
+
skill_id TEXT NOT NULL,
|
|
644
|
+
previous_hash TEXT,
|
|
645
|
+
new_hash TEXT NOT NULL,
|
|
646
|
+
changed_sources TEXT,
|
|
647
|
+
trigger_reason TEXT,
|
|
648
|
+
sync_notes TEXT,
|
|
649
|
+
synced_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
CREATE INDEX IF NOT EXISTS idx_skills_skill_id ON skills(skill_id);
|
|
653
|
+
CREATE INDEX IF NOT EXISTS idx_skills_status ON skills(status);
|
|
654
|
+
CREATE INDEX IF NOT EXISTS idx_skill_sync_history_skill ON skill_sync_history(skill_id);
|
|
617
655
|
`;
|
|
618
656
|
export function getDb() {
|
|
619
657
|
if (_db)
|
package/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC,MAAM,UAAU,GAAG
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|