viberadar 0.3.222 → 0.3.223
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/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +127 -0
- package/dist/server/index.js.map +1 -1
- package/dist/tracker.d.ts +53 -0
- package/dist/tracker.d.ts.map +1 -0
- package/dist/tracker.js +388 -0
- package/dist/tracker.js.map +1 -0
- package/dist/ui/dashboard.html +746 -70
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAO7B,OAAO,EAAE,UAAU,EAA4H,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAO7B,OAAO,EAAE,UAAU,EAA4H,MAAM,YAAY,CAAC;AAkBlK,UAAU,aAAa;IACrB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;CACrB;AA0vED,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAqgH1G"}
|
package/dist/server/index.js
CHANGED
|
@@ -49,6 +49,7 @@ const docx_1 = require("../docx");
|
|
|
49
49
|
const config_1 = require("../probe/config");
|
|
50
50
|
const runner_1 = require("../probe/runner");
|
|
51
51
|
const notify_1 = require("../probe/notify");
|
|
52
|
+
const tracker_1 = require("../tracker");
|
|
52
53
|
const DASHBOARD_HTML = fs.readFileSync(path.join(__dirname, '../ui/dashboard.html'), 'utf-8');
|
|
53
54
|
// ─── Agent CLI commands ───────────────────────────────────────────────────────
|
|
54
55
|
const WIN = process.platform === 'win32';
|
|
@@ -2437,6 +2438,44 @@ function startServer({ data: initialData, port, projectRoot }) {
|
|
|
2437
2438
|
catch { }
|
|
2438
2439
|
}
|
|
2439
2440
|
loadLastRunIntoState();
|
|
2441
|
+
function sendJson(res, statusCode, payload) {
|
|
2442
|
+
res.writeHead(statusCode, jsonH);
|
|
2443
|
+
res.end(JSON.stringify(payload));
|
|
2444
|
+
}
|
|
2445
|
+
function readJsonBody(req, maxBytes = 1024 * 1024) {
|
|
2446
|
+
return new Promise((resolve, reject) => {
|
|
2447
|
+
let body = '';
|
|
2448
|
+
req.on('data', (chunk) => {
|
|
2449
|
+
body += chunk.toString('utf-8');
|
|
2450
|
+
if (Buffer.byteLength(body, 'utf-8') > maxBytes) {
|
|
2451
|
+
reject(new Error('Request body is too large'));
|
|
2452
|
+
req.destroy();
|
|
2453
|
+
}
|
|
2454
|
+
});
|
|
2455
|
+
req.on('end', () => {
|
|
2456
|
+
if (!body.trim()) {
|
|
2457
|
+
resolve({});
|
|
2458
|
+
return;
|
|
2459
|
+
}
|
|
2460
|
+
try {
|
|
2461
|
+
resolve(JSON.parse(body));
|
|
2462
|
+
}
|
|
2463
|
+
catch (err) {
|
|
2464
|
+
reject(new tracker_1.TrackerValidationError([{ field: 'body', message: err.message || 'invalid JSON' }]));
|
|
2465
|
+
}
|
|
2466
|
+
});
|
|
2467
|
+
req.on('error', reject);
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
function sendTrackerError(res, err) {
|
|
2471
|
+
if (err instanceof tracker_1.TrackerValidationError) {
|
|
2472
|
+
const notFound = err.issues.some((issue) => issue.field === 'id' && issue.message.includes('не найдена'));
|
|
2473
|
+
sendJson(res, notFound ? 404 : 400, { ok: false, error: err.message, issues: err.issues });
|
|
2474
|
+
return;
|
|
2475
|
+
}
|
|
2476
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
2477
|
+
sendJson(res, 500, { ok: false, error: message });
|
|
2478
|
+
}
|
|
2440
2479
|
// ── SSE clients ────────────────────────────────────────────────────────────
|
|
2441
2480
|
const sseClients = new Set();
|
|
2442
2481
|
function broadcast(event, payload = {}) {
|
|
@@ -3639,6 +3678,9 @@ function startServer({ data: initialData, port, projectRoot }) {
|
|
|
3639
3678
|
}
|
|
3640
3679
|
title = `${agentLabel} — пайплайны для "${feat.label}"`;
|
|
3641
3680
|
}
|
|
3681
|
+
else if (task === 'custom-prompt') {
|
|
3682
|
+
title = `${agentLabel} — ${meta?.title || 'задача трекера'}`;
|
|
3683
|
+
}
|
|
3642
3684
|
else if (task === 'classify-orphan-tests') {
|
|
3643
3685
|
const orphanCount = getOrphanTests(currentData.modules).noFeature.length;
|
|
3644
3686
|
if (orphanCount === 0) {
|
|
@@ -3730,6 +3772,14 @@ function startServer({ data: initialData, port, projectRoot }) {
|
|
|
3730
3772
|
.on('add', f => scheduleRescan(path.join(projectRoot, f)))
|
|
3731
3773
|
.on('change', f => scheduleRescan(path.join(projectRoot, f)))
|
|
3732
3774
|
.on('unlink', f => scheduleRescan(path.join(projectRoot, f)));
|
|
3775
|
+
chokidar_1.default.watch([tracker_1.TRACKER_FILE_NAME], {
|
|
3776
|
+
cwd: projectRoot,
|
|
3777
|
+
ignoreInitial: true,
|
|
3778
|
+
persistent: true,
|
|
3779
|
+
})
|
|
3780
|
+
.on('add', () => broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME }))
|
|
3781
|
+
.on('change', () => broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME }))
|
|
3782
|
+
.on('unlink', () => broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, deleted: true }));
|
|
3733
3783
|
// ── HTTP server ────────────────────────────────────────────────────────────
|
|
3734
3784
|
const server = http.createServer((req, res) => {
|
|
3735
3785
|
const rawUrl = req.url ?? '/';
|
|
@@ -3906,6 +3956,83 @@ function startServer({ data: initialData, port, projectRoot }) {
|
|
|
3906
3956
|
res.end(JSON.stringify(buildAgentStateSnapshot()));
|
|
3907
3957
|
return;
|
|
3908
3958
|
}
|
|
3959
|
+
if (url === '/api/tasks' && req.method === 'GET') {
|
|
3960
|
+
try {
|
|
3961
|
+
sendJson(res, 200, { ...(0, tracker_1.readTrackerFile)(projectRoot), filePath: tracker_1.TRACKER_FILE_NAME });
|
|
3962
|
+
}
|
|
3963
|
+
catch (err) {
|
|
3964
|
+
sendTrackerError(res, err);
|
|
3965
|
+
}
|
|
3966
|
+
return;
|
|
3967
|
+
}
|
|
3968
|
+
if (url === '/api/tasks' && req.method === 'POST') {
|
|
3969
|
+
readJsonBody(req).then((payload) => {
|
|
3970
|
+
const task = (0, tracker_1.createTrackerTask)(projectRoot, payload?.task ?? payload);
|
|
3971
|
+
broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, taskId: task.id });
|
|
3972
|
+
sendJson(res, 201, { ok: true, task, file: (0, tracker_1.readTrackerFile)(projectRoot) });
|
|
3973
|
+
}).catch((err) => sendTrackerError(res, err));
|
|
3974
|
+
return;
|
|
3975
|
+
}
|
|
3976
|
+
if (url === '/api/tasks/import' && req.method === 'POST') {
|
|
3977
|
+
readJsonBody(req, 2 * 1024 * 1024).then((payload) => {
|
|
3978
|
+
const result = (0, tracker_1.importTrackerTasks)(projectRoot, payload);
|
|
3979
|
+
broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, imported: result.imported });
|
|
3980
|
+
sendJson(res, 200, { ok: true, imported: result.imported, file: result.file });
|
|
3981
|
+
}).catch((err) => sendTrackerError(res, err));
|
|
3982
|
+
return;
|
|
3983
|
+
}
|
|
3984
|
+
const taskRunMatch = url.match(/^\/api\/tasks\/([^/]+)\/run$/);
|
|
3985
|
+
if (taskRunMatch && req.method === 'POST') {
|
|
3986
|
+
const taskId = decodeURIComponent(taskRunMatch[1]);
|
|
3987
|
+
try {
|
|
3988
|
+
const file = (0, tracker_1.readTrackerFile)(projectRoot);
|
|
3989
|
+
const task = file.tasks.find((item) => item.id === taskId);
|
|
3990
|
+
if (!task) {
|
|
3991
|
+
sendJson(res, 404, { ok: false, error: `Задача не найдена: ${taskId}` });
|
|
3992
|
+
return;
|
|
3993
|
+
}
|
|
3994
|
+
const prompt = (0, tracker_1.buildTrackerTaskPrompt)(task);
|
|
3995
|
+
const runId = runAgent('custom-prompt', undefined, undefined, undefined, {
|
|
3996
|
+
prompt,
|
|
3997
|
+
title: `задача "${task.title}"`,
|
|
3998
|
+
taskId: task.id,
|
|
3999
|
+
});
|
|
4000
|
+
if (!runId) {
|
|
4001
|
+
sendJson(res, 409, { ok: false, error: 'Не удалось поставить задачу в очередь агента' });
|
|
4002
|
+
return;
|
|
4003
|
+
}
|
|
4004
|
+
const updatedTask = (0, tracker_1.setTrackerTaskRun)(projectRoot, task.id, runId);
|
|
4005
|
+
broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, taskId: task.id, runId });
|
|
4006
|
+
sendJson(res, 200, { ok: true, runId, task: updatedTask });
|
|
4007
|
+
}
|
|
4008
|
+
catch (err) {
|
|
4009
|
+
sendTrackerError(res, err);
|
|
4010
|
+
}
|
|
4011
|
+
return;
|
|
4012
|
+
}
|
|
4013
|
+
const taskArchiveMatch = url.match(/^\/api\/tasks\/([^/]+)\/archive$/);
|
|
4014
|
+
if (taskArchiveMatch && req.method === 'POST') {
|
|
4015
|
+
const taskId = decodeURIComponent(taskArchiveMatch[1]);
|
|
4016
|
+
try {
|
|
4017
|
+
const task = (0, tracker_1.archiveTrackerTask)(projectRoot, taskId);
|
|
4018
|
+
broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, taskId });
|
|
4019
|
+
sendJson(res, 200, { ok: true, task });
|
|
4020
|
+
}
|
|
4021
|
+
catch (err) {
|
|
4022
|
+
sendTrackerError(res, err);
|
|
4023
|
+
}
|
|
4024
|
+
return;
|
|
4025
|
+
}
|
|
4026
|
+
const taskPatchMatch = url.match(/^\/api\/tasks\/([^/]+)$/);
|
|
4027
|
+
if (taskPatchMatch && req.method === 'PATCH') {
|
|
4028
|
+
const taskId = decodeURIComponent(taskPatchMatch[1]);
|
|
4029
|
+
readJsonBody(req).then((payload) => {
|
|
4030
|
+
const task = (0, tracker_1.updateTrackerTask)(projectRoot, taskId, payload);
|
|
4031
|
+
broadcast('tasks-updated', { filePath: tracker_1.TRACKER_FILE_NAME, taskId });
|
|
4032
|
+
sendJson(res, 200, { ok: true, task, file: (0, tracker_1.readTrackerFile)(projectRoot) });
|
|
4033
|
+
}).catch((err) => sendTrackerError(res, err));
|
|
4034
|
+
return;
|
|
4035
|
+
}
|
|
3909
4036
|
const queueCancelMatch = url.match(/^\/api\/queue\/([^/]+)\/cancel$/);
|
|
3910
4037
|
if (queueCancelMatch && req.method === 'POST') {
|
|
3911
4038
|
const runId = decodeURIComponent(queueCancelMatch[1]);
|