The terminal already runs on macOS and Linux — CI proves it on every push, six jobs across Linux, macOS and Windows on Python 3.11 and 3.13. There is nothing to port.
What is missing is the convenience layer. app/tray.py is pure ctypes against user32/shell32/kernel32, so on anything but Windows the import raises and app/server.py:1283 catches it:
try:
from .tray import start_tray
start_tray(url, state)
except Exception as exc: # noqa: BLE001 — the tray is decoration
print(f" (tray unavailable: {exc})")
That is the correct behaviour — the terminal comes up either way — but Mac and Linux users lose the tray icon and the Ctrl+Alt+M global hotkey.
What it needs
A platform-appropriate implementation behind the same entry point:
start_tray(url: str, state) -> None
It should offer the same menu the Windows one does: Open, Refresh, Quit, and ideally a global summon hotkey.
The interesting constraint is that this project has three dependencies and requirements.txt is closed. A tray that needs pystray or PyQt is a much bigger conversation than one built on what is already there or on the platform's own tooling. Propose the approach in a comment before writing much code — happy to be talked into a dependency if there is genuinely no other way, but the bar is high.
Notes
- Keep the failure soft. Whatever you add must degrade to a printed line, never take the terminal down.
tray.py deliberately uses a window class distinct from OfflinePilotX's so both can sit in the tray at once; keep that property.
- Split by platform rather than growing one function with branches —
tray_win.py / tray_mac.py / tray_linux.py behind a small dispatcher would be cleaner than if sys.platform throughout.
The terminal already runs on macOS and Linux — CI proves it on every push, six jobs across Linux, macOS and Windows on Python 3.11 and 3.13. There is nothing to port.
What is missing is the convenience layer.
app/tray.pyis purectypesagainstuser32/shell32/kernel32, so on anything but Windows the import raises andapp/server.py:1283catches it:That is the correct behaviour — the terminal comes up either way — but Mac and Linux users lose the tray icon and the
Ctrl+Alt+Mglobal hotkey.What it needs
A platform-appropriate implementation behind the same entry point:
It should offer the same menu the Windows one does: Open, Refresh, Quit, and ideally a global summon hotkey.
The interesting constraint is that this project has three dependencies and
requirements.txtis closed. A tray that needspystrayorPyQtis a much bigger conversation than one built on what is already there or on the platform's own tooling. Propose the approach in a comment before writing much code — happy to be talked into a dependency if there is genuinely no other way, but the bar is high.Notes
tray.pydeliberately uses a window class distinct from OfflinePilotX's so both can sit in the tray at once; keep that property.tray_win.py/tray_mac.py/tray_linux.pybehind a small dispatcher would be cleaner thanif sys.platformthroughout.