import { access } from 'node:fs/promises'; import { constants } from 'node:fs'; import { execFile } from 'node:child_process'; import { promisify } from 'node:util'; const run = promisify(execFile); const checks = [ ['session', false, async () => process.env.XDG_SESSION_TYPE || 'unknown'], ['portal', false, async () => { await access('/usr/share/dbus-1/services/org.freedesktop.portal.Desktop.service', constants.F_OK); return 'installed'; }], ['pipewire', false, async () => { await run('which', ['pw-cat']); return 'installed'; }], ['at-spi', false, async () => { await run('python3', ['-c', 'import gi; gi.require_version("Atspi", "2.0"); from gi.repository import Atspi']); return 'PyGObject Atspi available'; }], ['libei', false, async () => { const result = await run('ldconfig', ['-p']); if (!/libei|libeis/.test(result.stdout)) throw new Error('libei/libeis not found'); return 'libei/libeis installed'; }], ['ydotool', true, async () => { await run('which', ['ydotool']); return 'optional fallback present'; }], ]; let failed = 0; for (const [name, optional, check] of checks) { try { console.log(`ok ${name}: ${await check()}${optional ? ' (optional)' : ''}`); } catch { if (!optional) failed += 1; console.log(`---- ${name}: unavailable${optional ? ' (optional)' : ''}`); } } console.log(failed ? `cu-doctor: ${failed} required checks unavailable` : 'cu-doctor: required checks passed'); process.exitCode = failed ? 1 : 0;