Documentation
Frontends
Source:
frontends/README.md
frontends contains reusable concrete UI implementations. The current
graphical frontend uses Tkinter, and frontends/tui provides reusable curses
views. Another frontend, such as Qt, can implement the same contracts without
changing the toolkit-independent models under ui.
Dependency boundary
flowchart LR
app["Application"] --> frontends["frontends"] --> contracts["ui + input_events"]
classDef orcApp fill:#dbeafe,stroke:#2563eb,color:#172554;
classDef orcService fill:#ede9fe,stroke:#7c3aed,color:#2e1065;
classDef orcController fill:#dcfce7,stroke:#16a34a,color:#14532d;
classDef orcMessage fill:#ffedd5,stroke:#ea580c,color:#7c2d12;
classDef orcAdapter fill:#fee2e2,stroke:#dc2626,color:#7f1d1d;
classDef orcExternal fill:#f3f4f6,stroke:#6b7280,color:#1f2937;
class app,frontends orcApp;
class contracts orcMessage;
Frontend code must not import apps.carUi. Application routes, domain
controllers, resource ownership, and product-specific composition remain in
the application package.
The common input dispatcher consumes only the neutral physical-input contracts
from input_events. It does not import controller policy or implementations.
It queues physical events until the selected frontend thread can deliver them.
Package map
common/input/provides the thread-safe physical-input event queue shared by frontend event loops.tk/runtime/owns Tk window and display runtime helpers.tk/menu/renders toolkit-independentui.menumodels.tk/system/contains persistent top bar, status, volume, and startup widgets.tk/media/,tk/lighting/, andtk/radio/provide reusable domain screens and panels. Tk media includes rich Spotify playback plus reusable Netflix and YouTube browser panels; application-owned services are injected through narrow protocols.tk/automotive/provides reusable vehicle and off-road dashboard panels.tui/automotive/provides reusable navigation and vehicle terminal views.tk/aircraft/andtk/weather/contain reusable menu panels used by Car UI destinations.
Extension rules
- Put navigable destinations in a frontend-specific screen module.
- Put reusable, non-navigable regions in panel modules.
- Accept data and request-handler contracts from
ui; do not reach into an application or controller implementation to fetch state. - Inject theme values, callbacks, hosts, and services rather than importing an application singleton.
- Keep domain logic and hardware ownership outside widget classes.
- Schedule widget mutations on the frontend event-loop thread.
A new frontend supplies its own shell, dispatcher, screen host, menu renderer,
and application screen factory. It can reuse the contracts and menu models in
ui while making no dependency on Tkinter.
Documentation and tests
venv/bin/python scripts/check_doxygen_contracts.py
venv/bin/python -m unittest discover \
-s frontends/common/input/unit_test -p 'test_*.py'
doxygen Doxyfile
Generated API documentation is written under build/doxygen/html.
The native weather map adapter is frontends/common/map_weather_overlay_ui.py.
It implements WeatherOverlayUiIf, converts SI weather snapshots into display
values and renderer commands, and leaves provider/cache/timer work to controllers.
weather_overlay_ui_group.py fans the same immutable snapshot out to map and
controls. Toolkit widgets bind explicit request-handler interfaces; composition
connects and owns the controllers.
Automatic architecture enforcement
python scripts/check_ui_boundaries.py recursively discovers production Python
modules in frontends/, app frontend/ and screens/ directories, controllers/,
and ui/. Views cannot add controller, service, transport, network, worker, or
process imports; controllers cannot add frontend/framework imports, and UI
contracts cannot add either. Relative imports and aliased imports are checked.
Composition roots remain outside frontend directories.
Existing dependencies are listed individually in
scripts/ui_boundary_exceptions.json, with a reason and occurrence count. The
check rejects new dependencies, increased counts, and stale exceptions. Remove
entries as coupling is fixed; do not regenerate the baseline to accept new code.
The weather gate additionally rejects backend private-state access. These checks
run locally in the quality gate and in CI. They check static imports; behavioral
contract tests and review remain necessary for indirect runtime dependencies.