import { mkdir, readFile, readdir, writeFile } from 'fs/promises'; import { join, resolve } from 'path'; function parseArgs(argv) { const parsed = { args: [], recordingDir: undefined, outputDir: undefined, }; for (let i = 0; i < argv.length; i++) { const arg = argv[i]; if (arg === '--recording-dir' || arg === '-r') { parsed.recordingDir = argv[++i]; continue; } if (arg === '--output-dir' || arg === '-o') { parsed.outputDir = argv[++i]; continue; } parsed.args.push(arg); } return parsed; } function recordingDir(cliRecordingDir) { return ( cliRecordingDir ?? process.env.N8N_AGENT_INTEGRATION_RECORDING_DIR ?? resolve(process.cwd(), '.agent-recordings', 'channel-integrations') ); } function sanitizeSessionId(value) { return value.replace(/[^a-zA-Z0-9._-]/g, '-'); } async function listSessions(cliRecordingDir) { const dir = recordingDir(cliRecordingDir); console.log(`Scanning ${dir} for sessions...`); let files = []; try { files = await readdir(dir); } catch { return []; } const sessions = await Promise.all( files .filter((file) => file.endsWith('.jsonl')) .map(async (file) => { const contents = await readFile(join(dir, file), 'utf8'); return { sessionId: file.slice(0, -'.jsonl'.length), entries: contents.split('\n').filter(Boolean).length, }; }), ); return sessions.sort((a, b) => a.sessionId.localeCompare(b.sessionId)); } async function exportSession(sessionId, cliRecordingDir) { const file = join(recordingDir(cliRecordingDir), `${sanitizeSessionId(sessionId)}.jsonl`); const contents = await readFile(file, 'utf8'); return contents .split('\n') .filter(Boolean) .map((line) => JSON.parse(line)); } async function writeExport(sessionId, records, outputDir) { await mkdir(outputDir, { recursive: true }); const outputPath = join(outputDir, `${sanitizeSessionId(sessionId)}.json`); await writeFile(outputPath, `${JSON.stringify(records, null, 2)}\n`, 'utf8'); return outputPath; } function printHelp() { console.log(` Usage: node scripts/agent-integration-recordings.mjs --list [--recording-dir