Trois lecteurs de ~/.ssh/config tranchaient la même question autrement : l'un comparait le mot-clé avec la casse, un autre exigeait un espace là où une tabulation est légale, un troisième laissait passer le motif nié `!nom`. Un alias déclaré « host » en minuscules était donc vu par l'un et invisible aux deux autres, ce qui se lit comme une panne intermittente de la découverte. La décision passe dans un module qui ne lit aucun fichier. Il rend None sur ce qui n'est pas une déclaration et une liste — possiblement vide — sur ce qui en est une : « Host * » ne nomme aucune machine mais reste une déclaration, sinon ses directives se rattachent au bloc précédent. Vérifié : 19 tests, et le menu reconnaît toujours le serveur du réseau par sa source SSH. --- EN --- Three readers of ~/.ssh/config settled the same question differently: one compared the keyword case-sensitively, another required a space where a tab is legal, a third let the negated pattern `!name` through. An alias declared with a lowercase "host" was therefore seen by one and invisible to the other two, which reads as intermittent discovery failure. The decision moves into a module that reads no file. It returns None for what is not a declaration and a list — possibly empty — for what is: "Host *" names no machine yet remains a declaration, otherwise its directives attach to the previous block. Checked: 19 tests, and the menu still recognises the server on the network through its SSH source. Assisted-by: Claude Opus 5 |
||
|---|---|---|
| .. | ||
| assistant | ||
| assistant_menu.py | ||
| auto_ask.py | ||
| database_manager.py | ||
| deploy_form_extras.py | ||
| deploy_form_lib.py | ||
| deploy_form_plan.py | ||
| dev_tools.py | ||
| kdbx_manager.py | ||
| logo_ascii.txt | ||
| longtest_menu.py | ||
| migration_form.py | ||
| migration_stats.py | ||
| migration_status.py | ||
| migration_status_tui.py | ||
| proxmox_deploy_form.py | ||
| proxmox_menu.py | ||
| qemu_access.py | ||
| qemu_deploy.py | ||
| qemu_deploy_form.py | ||
| qemu_hardware.py | ||
| qemu_install.py | ||
| qemu_install_monitor.py | ||
| qemu_manage.py | ||
| qemu_menu.py | ||
| qemu_network.py | ||
| qemu_privilege.py | ||
| qemu_recover.py | ||
| README.base.md | ||
| README.fr.md | ||
| README.md | ||
| source_todo.sh | ||
| ssh_config.py | ||
| textual_setup.py | ||
| todo.json | ||
| todo.py | ||
| todo_example.json | ||
| todo_file_browser.py | ||
| todo_i18n.py | ||
| todo_install.py | ||
| todo_prefs.py | ||
| todo_telemetry.py | ||
| todo_upgrade.py | ||
| version_manager.py | ||
| vpn_menu.py | ||
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.
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.