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.
@@ -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;AAOlK,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,CAk4G1G"}
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"}
@@ -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]);