#!/usr/bin/env node // stop-assessment-reminder.mjs // Reminds about uncommitted assessments and suggests next steps on session end. // Output: JSON { systemMessage } to stdout. Always exits 0 (advisory, never blocking). import { readdirSync, statSync, existsSync } from 'node:fs'; import { join } from 'node:path'; const cwd = process.cwd(); const workDir = join(cwd, '.work'); const TWELVE_HOURS_MS = 12 * 60 * 60 * 1000; const now = Date.now(); // No .work/ directory — nothing to remind about if (!existsSync(workDir)) { console.log('{}'); process.exit(0); } // Find recent state files in .work/ const recentSessions = []; try { const entries = readdirSync(workDir, { withFileTypes: true }); for (const entry of entries) { if (!entry.isDirectory()) continue; const sessionDir = join(workDir, entry.name); try { const files = readdirSync(sessionDir); for (const file of files) { const filePath = join(sessionDir, file); try { const stat = statSync(filePath); if (now - stat.mtimeMs < TWELVE_HOURS_MS) { recentSessions.push(entry.name); break; } } catch { // Skip } } } catch { // Skip } } } catch { console.log('{}'); process.exit(0); } if (recentSessions.length === 0) { console.log('{}'); process.exit(0); } // Build reminder const suggestions = [ '/architect:adr — generer ADR fra vurderinger', '/architect:export — eksporter til PDF', '/architect:summary — lag beslutningsnotat', ]; // Add AI Act suggestion if deadline is within 180 days const DAY_MS = 24 * 60 * 60 * 1000; const gpaiDeadline = new Date('2026-08-02'); const daysToGpai = Math.ceil((gpaiDeadline.getTime() - now) / DAY_MS); if (daysToGpai > 0 && daysToGpai <= 180) { suggestions.push(`/architect:classify — EU AI Act-klassifisering (${daysToGpai}d til GPAI-frist)`); } const sessionList = recentSessions.join(', '); const message = `Architect: ${recentSessions.length} aktiv(e) vurdering(er) i .work/ (${sessionList}). Foreslåtte neste steg: ${suggestions.join(' | ')}`; console.log(JSON.stringify({ systemMessage: message })); process.exit(0);