TODO is an assistant robot to use ERPLibre Execute it with `./script/todo/todo.py` or `make todo`. For a new project, copy todo_example.json to private/todo/todo_override.json | private/todo/todo_override_private.json and edit it. The `mail/` package is the mail client reachable from `Assistant > Mail`: several IMAP/SMTP accounts, a local cache, and a Textual TUI. See [../../doc/EMAIL.md](../../doc/EMAIL.md). ## Where the code lives `todo.py` carries the menus and the general helpers. Everything around a single subject sits in its own file, and the whole thing is assembled by mixins on the `TODO` class — one file, one subject, its header states its boundary. | File | What it owns | |------|--------------| | `todo.py` | the menus, the configuration, the general helpers | | `qemu_menu.py` | the QEMU/KVM menu, the image catalogue, the statistics | | `qemu_deploy.py` | deciding then running a deployment | | `qemu_install.py` | the recipes run inside a VM | | `qemu_manage.py` | lifecycle, disks, hardware, cleanup, addresses | | `qemu_access.py` | SSH, tunnels, consoles, Android emulator | | `proxmox_menu.py` | the same, on a REMOTE Proxmox VE host | The two deployment forms — libvirt here, Proxmox over there — ask the same questions, so they share a foundation rather than each holding a copy: | File | What it owns | |------|--------------| | `deploy_form_lib.py` | pure logic (sizes, plan, totals, spec), the shared CSS, the resource-row factory, the progress view | | `deploy_form_plan.py` | the plan's gestures: overrides, locks, copies, renaming, free values | | `qemu_deploy_form.py` | what QEMU/KVM adds: desktops, tools, branches, install profiles | | `proxmox_deploy_form.py` | what Proxmox adds: host, storage, bridge, VMID, address | A form inherits `PlanMixin` and provides three hooks: which presets each resource offers, the name a VM would fall back to, and what a lock freezes. `test_todo_deploy_form_lib.py` fails if a form redefines a gesture the foundation already carries — that is what keeps the architecture from drifting back into two copies.