diff --git a/index.js b/index.js index 26fd291..cdfea8c 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,12 @@ export const name = 'omp-security' export const inject = ['tools', 'llm'] const STORE = path.join(os.homedir(), '.dsh', 'security-scans') + +/** Wait for `promise` or `ms`, whichever first — and clear the timer so it never outlives the wait. */ +function waitAtMost(promise, ms) { + let t + return Promise.race([promise, new Promise((r) => { t = setTimeout(r, ms) })]).finally(() => clearTimeout(t)) +} const ACTIONS = ['preflight', 'start', 'status', 'cancel', 'validate', 'list', 'scanners'] export function apply(ctx, config = {}) { @@ -135,7 +141,7 @@ export function apply(ctx, config = {}) { } })() // Small scans finish quickly: wait briefly so the first status is useful. - await Promise.race([op.promise, new Promise((r) => setTimeout(r, Math.min(args.wait_seconds ?? 20, 240) * 1000))]) + await waitAtMost(op.promise, Math.min(args.wait_seconds ?? 20, 240) * 1000) return statusText(scan, args) } @@ -236,7 +242,7 @@ ${extra}` const op = ops.get(args.operation_id) const scan = op?.scan ?? load(args.scan_id ?? '') ?? [...ops.values()].findLast((o) => o.scan.scanId === args.scan_id)?.scan if (!scan) throw new Error('unknown operation_id/scan_id') - if (op && args.wait_seconds) await Promise.race([op.promise, new Promise((r) => setTimeout(r, Math.min(args.wait_seconds, 240) * 1000))]) + if (op && args.wait_seconds) await waitAtMost(op.promise, Math.min(args.wait_seconds, 240) * 1000) return statusText(scan, args) } case 'cancel': {