diff --git a/plugins/_desktop/AGENTS.md b/plugins/_desktop/AGENTS.md index 5fc6f449c..f3dc67d12 100644 --- a/plugins/_desktop/AGENTS.md +++ b/plugins/_desktop/AGENTS.md @@ -17,7 +17,7 @@ - Keep desktop state injected into prompts accurate and bounded. - Do not expose desktop routes without the expected auth protections. - Keep Desktop host visibility tied to an attached modal or canvas host; modal cleanup may preserve the iframe in keepalive, but must not leave stale modal mode behind. -- Keep Markdown and plain text file open-with handling routed to the Editor surface through the desktop intent bridge; Desktop owns the Xfce launcher/MIME setup, while Editor owns `.md` and `.txt` editing. +- Keep LibreOffice Writer as the default handler for Markdown and plain text files; keep Agent Zero Editor available as a secondary Open With target through the desktop intent bridge. ## Work Guidance diff --git a/plugins/_desktop/helpers/desktop_session.py b/plugins/_desktop/helpers/desktop_session.py index efacb2c41..4acdab0cc 100644 --- a/plugins/_desktop/helpers/desktop_session.py +++ b/plugins/_desktop/helpers/desktop_session.py @@ -79,6 +79,7 @@ URL_INTENT_MAX_ITEMS = 50 URL_INTENT_MAX_LENGTH = 8192 URL_HANDLER_DESKTOP_ID = "agent-zero-browser.desktop" EDITOR_HANDLER_DESKTOP_ID = "agent-zero-editor.desktop" +WRITER_HANDLER_DESKTOP_ID = "libreoffice-writer.desktop" SHUTDOWN_HANDLER_DESKTOP_ID = "agent-zero-shutdown.desktop" SHUTDOWN_PANEL_LAUNCHER_ID = SHUTDOWN_HANDLER_DESKTOP_ID SHUTDOWN_CONFIRM_SECONDS = 8 @@ -2197,15 +2198,19 @@ def _editor_text_handler_mime_types() -> tuple[str, ...]: def _write_mimeapps_defaults(path: Path, url_desktop_id: str, editor_desktop_id: str) -> None: url_associations = ";".join([url_desktop_id, ""]) - editor_associations = ";".join([editor_desktop_id, ""]) + # LibreOffice Writer stays the default so double-clicks keep the user (and + # agents) inside the Desktop; the Agent Zero Editor remains an "Open With" + # option. When Writer's desktop entry is missing, xdg falls back through + # the added associations to the editor. + text_associations = ";".join([WRITER_HANDLER_DESKTOP_ID, editor_desktop_id, ""]) lines = [ "[Default Applications]", *(f"{mime_type}={url_desktop_id}" for mime_type in _url_handler_mime_types()), - *(f"{mime_type}={editor_desktop_id}" for mime_type in _editor_text_handler_mime_types()), + *(f"{mime_type}={WRITER_HANDLER_DESKTOP_ID}" for mime_type in _editor_text_handler_mime_types()), "", "[Added Associations]", *(f"{mime_type}={url_associations}" for mime_type in _url_handler_mime_types()), - *(f"{mime_type}={editor_associations}" for mime_type in _editor_text_handler_mime_types()), + *(f"{mime_type}={text_associations}" for mime_type in _editor_text_handler_mime_types()), "", ] path.parent.mkdir(parents=True, exist_ok=True) diff --git a/tests/test_office_canvas_setup.py b/tests/test_office_canvas_setup.py index 404e09c5e..6d29c36d0 100644 --- a/tests/test_office_canvas_setup.py +++ b/tests/test_office_canvas_setup.py @@ -608,6 +608,12 @@ def test_desktop_text_open_with_routes_to_editor_surface(): assert "handleEditorUrlIntent" in editor_store assert 'openLatestSurface("editor"' in editor_store + # Text files default to LibreOffice Writer inside the Desktop; the Agent + # Zero Editor stays available as a secondary "Open With" association. + assert 'WRITER_HANDLER_DESKTOP_ID = "libreoffice-writer.desktop"' in desktop_session + assert "{mime_type}={WRITER_HANDLER_DESKTOP_ID}" in desktop_session + assert "[WRITER_HANDLER_DESKTOP_ID, editor_desktop_id, " in desktop_session + # The browser surface must not claim a0-editor: intents, otherwise the # editor "Open With" handler lands on an unloadable about:blank page. assert "function isWebUrlIntent" in browser_store