diff --git a/scripts/subagent_delivery_watchdog.mjs b/scripts/subagent_delivery_watchdog.mjs index d23fcc2..5818590 100755 --- a/scripts/subagent_delivery_watchdog.mjs +++ b/scripts/subagent_delivery_watchdog.mjs @@ -1,8 +1,12 @@ #!/usr/bin/env node import fs from 'node:fs'; +import path from 'node:path'; import process from 'node:process'; +const ROOT_DIR = path.resolve(import.meta.dirname, '..'); +const STATE_DIR = path.join(ROOT_DIR, 'state', 'subagent-delivery-watchdog'); + function parseArgs(argv) { const args = { compact: false, @@ -44,7 +48,9 @@ function printHelp() { '', 'Minimal CLI skeleton for the subagent delivery watchdog.', ]; - process.stdout.write(`${lines.join('\n')}\n`); + process.stdout.write(`${lines.join(' +')} +`); } function tryReadInput(inputPath) { @@ -64,6 +70,7 @@ function tryReadInput(inputPath) { exists: true, bytes: Buffer.byteLength(content, 'utf8'), preview: content.slice(0, 200), + content, }; } catch (error) { return { @@ -76,6 +83,48 @@ function tryReadInput(inputPath) { } } +function tryParseJson(content) { + if (typeof content !== 'string' || content.length === 0) { + return null; + } + + try { + return JSON.parse(content); + } catch { + return null; + } +} + +function writeDispatchReceiptState(payload) { + if (!payload || typeof payload !== 'object') { + return null; + } + + const { runId, childSessionKey, dispatchAt, expectedBy } = payload; + + if (![runId, childSessionKey, dispatchAt, expectedBy].every((value) => typeof value === 'string' && value.length > 0)) { + return null; + } + + fs.mkdirSync(STATE_DIR, { recursive: true }); + + const statePath = path.join(STATE_DIR, `${runId}.json`); + const dispatchRecord = { + runId, + childSessionKey, + dispatchAt, + expectedBy, + }; + + fs.writeFileSync(statePath, `${JSON.stringify(dispatchRecord, null, 2)} +`, 'utf8'); + + return { + statePath, + record: dispatchRecord, + }; +} + function main() { const args = parseArgs(process.argv.slice(2)); @@ -85,11 +134,18 @@ function main() { } const input = tryReadInput(args.input); + const inputPayload = input.exists ? tryParseJson(input.content) : null; + const dispatchWrite = writeDispatchReceiptState(inputPayload); + + if ('content' in input) { + delete input.content; + } + const response = { ok: true, tool: 'subagent_delivery_watchdog', - version: 'skeleton-v1', - mode: 'placeholder', + version: 'skeleton-v2', + mode: 'dispatch-receipt-write', args: { compact: args.compact, input: args.input, @@ -97,13 +153,15 @@ function main() { input, result: { status: 'not_implemented', - message: 'Watchdog skeleton ready for follow-up tasks.', - records: [], + message: 'Dispatch receipt write is implemented; status recompute remains pending.', + records: dispatchWrite ? [dispatchWrite.record] : [], + dispatchReceiptWrite: dispatchWrite, }, }; const spacing = args.compact ? 0 : 2; - process.stdout.write(`${JSON.stringify(response, null, spacing)}\n`); + process.stdout.write(`${JSON.stringify(response, null, spacing)} +`); } main();