UNPKG

paqad-ai

Version:

Spec-driven development framework — AI agents that think before they type

80 lines (74 loc) • 2.41 kB
#!/usr/bin/env node import process from 'node:process'; function quickFilter(input) { try { const payload = JSON.parse(input); if (payload?.hook_event_name === 'SubagentStop') return payload; if (payload?.hook_event_name !== undefined && payload.hook_event_name !== 'PostToolUse') { return null; } return payload?.tool_name === 'Agent' || payload?.tool_name === 'Task' ? payload : null; } catch { return null; } } async function record(payload) { const fs = await import('node:fs'); const { join } = await import('node:path'); const core = await import('./lib/agent-delegation-core.mjs'); const gate = await import('./lib/paqad-disabled.mjs'); const projectRoot = gate.resolveProjectRoot(process.env, payload); if (gate.isPaqadDisabled(projectRoot) || !gate.isProjectOnboarded(projectRoot)) return; const enabled = gate.readLayeredKey( projectRoot, 'agent_orchestrator_enabled', 'PAQAD_AGENT_ORCHESTRATOR_ENABLED', ); if (enabled !== undefined && ['false', '0', 'no', 'off'].includes(enabled.trim().toLowerCase())) return; const entry = core.delegationFromPayload(payload); const line = entry === null ? null : core.delegationLine(entry); if (line === null) return; const file = join(projectRoot, core.DELEGATIONS_REL); const { seenInTail, withTailLock } = await import('./lib/ledger-tail-dedupe.mjs'); const wrote = withTailLock(file, (assertHeld) => { if ( entry.request_id !== null && seenInTail(file, core.isSameDelegation(entry), { byValue: typeof payload.tool_use_id === 'string', }) ) { return false; } assertHeld(); fs.appendFileSync(file, line, 'utf8'); return true; }); if (!wrote) return; if (fs.statSync(file).size <= core.PRUNE_THRESHOLD_BYTES) return; const window = Number( gate.readLayeredKey( projectRoot, 'authoring_dark_window_days', 'PAQAD_AUTHORING_DARK_WINDOW_DAYS', ), ); core.compactDelegations( fs, file, new Date(), Number.isInteger(window) && window > 0 ? window : core.DEFAULT_DARK_WINDOW_DAYS, ); } async function main() { let input = ''; try { for await (const chunk of process.stdin) input += chunk; const payload = quickFilter(input); if (payload !== null) await record(payload); } catch { process.exitCode = 0; } process.exitCode = 0; } await main();