mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-10-27 16:01:54 +00:00
74 lines
2.3 KiB
JavaScript
74 lines
2.3 KiB
JavaScript
import fs from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { randomInt } from 'node:crypto';
|
|
import { todayDateStr, getIsoWeekStr } from './utils.mjs';
|
|
|
|
export { relayListLabel } from './utils.mjs';
|
|
|
|
/**
|
|
* Scans the local log directory to identify agents that have already completed their task
|
|
* for the current period (daily or weekly).
|
|
*
|
|
* @param {string} cadence - 'daily' or 'weekly'
|
|
* @param {string} logDir - Path to the log directory (e.g., 'task-logs')
|
|
* @param {Object} deps - Dependency injection for testing
|
|
* @returns {Promise<Set<string>>} - Set of agent names that have completed their task
|
|
*/
|
|
export async function getCompletedAgents(cadence, logDir, deps = {}) {
|
|
const { readdir = fs.readdir, getDateStr = todayDateStr, getIsoWeek = getIsoWeekStr } = deps;
|
|
const completed = new Set();
|
|
const targetDir = path.join(logDir, cadence);
|
|
|
|
try {
|
|
const files = await readdir(targetDir);
|
|
const today = getDateStr();
|
|
const currentWeek = getIsoWeek();
|
|
|
|
for (const file of files) {
|
|
// Format: YYYY-MM-DDTHH-mm-ssZ__<agent>__<status>.md
|
|
const match = file.match(/^(\d{4}-\d{2}-\d{2})T.*__([a-zA-Z0-9-_]+)__(.*)\.md$/);
|
|
if (!match) continue;
|
|
|
|
const [, datePart, agent, status] = match;
|
|
|
|
if (status === 'completed') {
|
|
if (cadence === 'daily' && datePart === today) {
|
|
completed.add(agent);
|
|
} else if (cadence === 'weekly') {
|
|
const fileWeek = getIsoWeek(datePart); // datePart is YYYY-MM-DD
|
|
if (fileWeek === currentWeek) {
|
|
completed.add(agent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
if (err.code !== 'ENOENT') {
|
|
console.error(`Warning: Failed to read log dir ${targetDir}: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
return completed;
|
|
}
|
|
|
|
export function withTimeout(promise, timeoutMs, timeoutMessage = 'Operation timed out') {
|
|
let timer;
|
|
const timeoutPromise = new Promise((_, reject) => {
|
|
timer = setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
});
|
|
return Promise.race([
|
|
promise.finally(() => clearTimeout(timer)),
|
|
timeoutPromise,
|
|
]);
|
|
}
|
|
|
|
export function mergeRelayList(primaryRelays, fallbackRelays) {
|
|
return [...new Set([...primaryRelays, ...fallbackRelays])];
|
|
}
|
|
|
|
const MAX_RANDOM = 281474976710655; // 2**48 - 1
|
|
|
|
export function secureRandom() {
|
|
return randomInt(0, MAX_RANDOM) / MAX_RANDOM;
|
|
}
|