// Typage de dialogue à partir de l'écran reconstruit (ScreenReader) : fonctions PURES. // L'écran sert à TYPER le dialogue et extraire ses options ; l'état (waiting vrai/faux) vient du // registre (source primaire). Tolérant aux variations de rendu inter-versions (texte aplati + regex). import type { DialogKind, DialogOption } from '@arboretum/shared'; export interface ClassifiedDialog { kind: DialogKind; options: DialogOption[]; } // Option numérotée, éventuellement préfixée du curseur ❯ : « ❯ 1. Yes », « 2) No »… const OPTION_RE = /^\s*(❯)?\s*(\d+)[.)]\s+(.*\S)\s*$/; export function parseOptions(lines: string[]): DialogOption[] { const out: DialogOption[] = []; for (const line of lines) { const m = OPTION_RE.exec(line); if (m && m[2] && m[3]) out.push({ n: Number(m[2]), label: m[3].trim(), selected: Boolean(m[1]) }); } return out; } /** * Retourne le dialogue typé visible à l'écran, ou null si aucun. `trust` et `question` priment sur * `permission` (un écran AskUserQuestion contient aussi « Esc to cancel »). Un écran numéroté non * typé est traité en `permission` générique (best-effort, le fallback reste le terminal web). */ export function classifyDialog(lines: string[]): ClassifiedDialog | null { const text = lines.join('\n'); const flat = text.replace(/\s+/g, '').toLowerCase(); const options = parseOptions(lines); const isTrust = flat.includes('trust') && (text.includes('❯') || flat.includes('entertoconfirm') || flat.includes('trustthisfolder')); const isQuestion = flat.includes('entertoselect') || flat.includes('tonavigate') || text.includes('↑/↓'); const isPermission = flat.includes('doyouwant') || flat.includes('esctocancel') || flat.includes('tabtoamend'); const isPlan = flat.includes('readytocode') || flat.includes('wouldyouliketoproceed'); let kind: DialogKind | null = null; if (isTrust) kind = 'trust'; else if (isQuestion) kind = 'question'; else if (isPlan) kind = 'plan'; else if (isPermission) kind = 'permission'; else if (options.length > 0) kind = 'permission'; return kind ? { kind, options } : null; }