Jason ruled on seven open items (20:27Z-20:45Z): seat Gitea tokens read in place, one Discord restart after 6b with row 25 live, row 8 limited to the dev seats, DYOR in dyor-stack-v4 with Sage moved to SetSpark, skills/aws-* excluded locally, no second WebUI return defect, and go on CHAT-02 only. Sage persona files name SetSpark as its business work. Darkwing's SOUL drops harness names that were wrong for T3. DEFERRED adds the slash-prefix paste hazard and the board Host/Origin gap, and moves the ledger T3 item to Done. Dewey's approved CHAT-02 brief (636b0fac) and Filbert's review are recorded. Co-Authored-By: Claude Opus 5.5 <[email protected]>
17 lines
1.4 KiB
JavaScript
17 lines
1.4 KiB
JavaScript
// Board-originated sends in pi session files: timestamps/roles only, no content beyond 80 chars of the send.
|
|
import { readFileSync, readdirSync, statSync } from 'node:fs'; import { join } from 'node:path';
|
|
const roots = process.argv.slice(2);
|
|
const walk = d => readdirSync(d).flatMap(n => { const p = join(d, n); const s = statSync(p); return s.isDirectory() ? walk(p) : n.endsWith('.jsonl') ? [p] : []; });
|
|
for (const root of roots) for (const f of walk(root)) {
|
|
const E = readFileSync(f, 'utf8').split('\n').filter(Boolean).map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
|
|
E.forEach((e, i) => {
|
|
if (e.type !== 'message' || e.message.role !== 'user') return;
|
|
const c = e.message.content; const t = typeof c === 'string' ? c : (c || []).filter(x => x.type === 'text').map(x => x.text).join('\n');
|
|
if (!/control-board ->/.test(t)) return;
|
|
const after = E.slice(i + 1).filter(x => x.type === 'message');
|
|
const firstA = after.find(x => x.message.role === 'assistant' && x.message.stopReason === 'stop');
|
|
const nextUser = after.find(x => x.message.role === 'user');
|
|
console.log(JSON.stringify({ file: f.replace(process.env.HOME, '~'), sent: e.timestamp, head: t.slice(0, 80).replace(/\n/g, ' '), firstStopAnswer: firstA?.timestamp ?? null, answerChars: firstA ? firstA.message.content.filter(x => x.type === 'text').map(x => x.text).join('\n').length : null, nextUser: nextUser?.timestamp ?? null }));
|
|
});
|
|
}
|