import { LogEntry, NlCommand } from './types.js'; let _logId = 0; export function makeLog(level: LogEntry['level'], message: string): LogEntry { const now = new Date(); const timestamp = `${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`; return { id: ++_logId, timestamp, level, message }; } const DESTRUCTIVE = ['delete', 'destroy', 'wipe', 'reset', 'force', 'purge', 'drop']; export function isDestructive(input: string): boolean { return DESTRUCTIVE.some(w => input.toLowerCase().includes(w)); } /** * Parses a natural language command string into a typed NlCommand. * Extend this to connect to an LLM for richer parsing. */ export function parseNlCommand(input: string): NlCommand { const lower = input.trim().toLowerCase(); if (['status', 'stat', 'health', 'ping'].includes(lower)) { return { type: 'status' }; } if (['refresh', 'reload', 'sync', 'r'].includes(lower)) { return { type: 'refresh' }; } if (['hive', 'antidote', 'antidotes', 'stats hive'].includes(lower)) { return { type: 'antidote_stats' }; } if (lower.startsWith('find antidote') || lower.startsWith('search antidote') || lower.startsWith('lookup antidote')) { const query = lower.replace(/^(find|search|lookup) antidote(s)?\s*/, '').trim(); return { type: 'antidote_query', query }; } if (lower.startsWith('go ') || lower.startsWith('open ') || lower.startsWith('show ')) { return { type: 'navigate', target: lower.split(' ').slice(1).join(' ') }; } if (isDestructive(lower)) { return { type: 'confirm_destructive', original: input }; } return { type: 'unknown', raw: input }; } export function formatProgress(completed: number, total: number, width = 20): string { if (total === 0) return '─'.repeat(width); const filled = Math.round((completed / total) * width); return '█'.repeat(filled) + '░'.repeat(width - filled); }