Skip to content

Commit 4891d6f

Browse files
authored
Merge pull request #97 from Zeus-Deus/feature/95-empty-project-dialog-not-opening
fix: stop file dialogs failing silently on portal-less Linux setups
2 parents 7af9c94 + fcfa0a2 commit 4891d6f

24 files changed

Lines changed: 968 additions & 14 deletions

docs/INDEX.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ If the docs themselves feel stale or scattered, also read `docs/reference/DOCS_R
6363
- Automations (scheduled host-side agent runs): `docs/features/automations.md`; roadmap at `docs/plans/automations.md`; Phase 2 (sync + remote-host) detailed plan at `docs/plans/automations-sync.md`; Superset research at `docs/research/superset-automations.md`
6464
- Agent hooks: `docs/features/hooks.md`
6565
- Execution backends / sandboxing: `docs/features/execution.md`
66-
- Observability (flags, metrics, safety config): `docs/features/observability.md`
66+
- Observability (flags, metrics, safety config + native log file / `codemux logs` / `codemux doctor`): `docs/features/observability.md`
67+
- Linux file-dialog backend preflight (issue #95 — portal/zenity detection, install-hint toast): `docs/features/workspace-creation.md` (§ constraints), `docs/reference/CONTROL.md` (§ local diagnostics)
6768
- Port detection (incl. Docker-published container ports for open worktrees): `docs/features/ports.md`
6869
- Search: `docs/features/search.md`
6970
- Code indexing: `docs/features/code-indexing.md`

docs/core/STATUS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Landed on `main` after the `v0.8.0` tag (unreleased): the **Tauri/React performa
1616

1717
Also landed on `main` after the `v0.8.0` tag (unreleased): **headless-daemon worktree provisioning parity** (issue #78). The daemon's `worktree_create` MCP tool now provisions a new worktree the same way the desktop does: gitignored include files (`.env` & co, `.codemuxinclude` → defaults) are copied from the parent repo synchronously before the tool returns, and the project's `.codemux/config.json` setup commands run on a background thread through a new UI-free `crate::scripts::run_setup_commands` core (shared with the desktop's `run_setup_scripts_with_config`, now a thin Tauri-event wrapper over it) with the full `CODEMUX_ROOT_PATH`/`CODEMUX_WORKSPACE_PATH`/`CODEMUX_BRANCH`/`CODEMUX_PORT` (+ NAME/ID) env and the same deterministic `allocate_workspace_port` port. The tool response gains a `setup` summary (`{port, includes_copied, setup_commands, setup_running}`); setup progress/failures log to the daemon's stderr, and a failing setup script never fails the tool call. Combined with the earlier daemon-side fetch-before-branch in `remote/git.rs` (issue #76 parity), remote-created branches start at the freshly-fetched `origin/<base>` tip with graceful offline/local-only fallback. Verified by 3 new unit tests in `remote/tools/mod.rs`, a full-daemon HTTP integration test (`http_worktree_create_provisions_like_desktop` in `src-tauri/tests/codemux_remote_serve_mcp.rs`, stale-clone scenario), and a checked-in containerized clean-host e2e (`scripts/e2e/daemon-worktree-setup-e2e.sh`, PR #93 — drives the real authed HTTP `tools/call` surface in a fresh Arch container and asserts worktree creation + setup-script run + gitignored-include copy on the container's filesystem). See `docs/features/setup-teardown.md` § "Headless Daemon Parity", `docs/features/remote-hosts.md`.
1818

19+
Also landed after the `v0.8.0` tag (unreleased): the **silent file-dialog fix for minimal Linux setups** (issue #95). The Linux dialog backend is portal-only (`tauri-plugin-dialog` with `xdg-portal`; rfd falls back to spawning `zenity` when the portal call fails), so on a minimal WM (i3/dwm) with neither installed every folder/file picker resolved `None` exactly like a user cancel — "Open Project" did nothing, with zero diagnostics (no Rust logger was installed, so rfd's `log::error!` vanished). The fix is four-layered: (1) `src-tauri/src/dialog_preflight.rs` probes the portal's `FileChooser.version` property over zbus + `which zenity` before every dialog command and returns a marker error (`NO_FILE_PICKER_BACKEND`) when neither backend exists; (2) all UI call sites route through `src/lib/file-dialog.ts`, which turns that marker into an actionable install-hint toast and resolves like a cancel (the settings export/import sites already surfaced errors inline); (3) tauri-plugin-log now writes warn+ to stderr and a rotating `~/.local/share/com.codemux.app/logs/codemux.log`, readable via the new `codemux logs [--tail n]`, and the new `codemux doctor` prints a local environment diagnosis (portal/zenity/session info) with no running app required; (4) the AUR PKGBUILD template gains `xdg-desktop-portal` + `xdg-desktop-portal-gtk` as hard deps and `zenity` as optdepends. Verified by an env-isolated integration test (`src-tauri/tests/dialog_preflight.rs`), `src/lib/file-dialog.test.ts`, a dev-mock toast simulation (`sessionStorage` flag in `src/dev/tauri-mock.ts`), and a clean-Arch-container `codemux doctor` run replicating the reporter's machine. See `docs/features/workspace-creation.md` § constraints, `docs/features/observability.md` § native log file, `docs/reference/CONTROL.md` § local diagnostics.
20+
1921
Shipped in `v0.7.9` is **"Operate a remote workspace in place" (Open on host)** — the no-pull remote-operation capability (issue #64). The Workspaces overview's host-backed sibling row gains an **"Open on host"** action (enabled when the host is configured locally) that creates a local *attach-in-place* workspace: `WorkspaceSnapshot` gains `remote_cwd` (the workspace's real on-host directory) + `attach_only` (operated in place, no local files), `create_remote_attach_workspace` builds a ready single-terminal workspace with `host_id` set and **nothing copied under `~/.codemux/` locally**, and the daemon-backed terminal path (`remote_spawn_cwd`) spawns into `remote_cwd` over the existing SSH-tunneled pty-daemon so commands run on the host with live streaming. Persistence is real: `ssh::tunnel::build_remote_command` now **reuses a still-running daemon** (via a `<socket>.pid` liveness probe) or **spawns it detached** (`setsid`/`nohup`, stdio redirected) instead of `exec`-ing it in the SSH foreground, so closing the app leaves the host process running and reopening re-tunnels + `client.list()`-reattaches the live sessions (a strict improvement for the push flow too). The command (`workspace_open_on_host`) resolves the host-backed sync row → local host → `origin_path`, is idempotent, and is excluded from `reconcile_from_snapshot` so it never creates a duplicate cloud row; the overview dedupes the sibling card against the open in-place view and renders an "on host" badge with detach-only close. See `docs/features/remote-in-place.md`.
2022

2123
Shipped in `v0.7.9` is a **multi-device robustness + remote-persistence pass** layered on top of repo-unit sync. (1) **SSH tunnel health is now surfaced in the UI**: the `TunnelStatus` the supervisor already computed (`connected`/`pending`/`reconnecting`/`circuit_open`) is bridged to the frontend via a new `tunnel-status-changed` event + `spawn_tunnel_status_forwarder` (self-terminating per supervisor), a zustand `tunnel-status-store` fed by an app-root `useTunnelStatusEvents` hook, and a sidebar pill — amber **"Reconnecting…"** on a sleep/wake or WiFi flap, red **"Connection lost — re-push"** once the circuit breaker trips — so a dropped tunnel no longer looks like a frozen workspace. (2) **Host persistence**: auto-upgrade no longer kills host-side agents — `hosts_upgrade` probes the daemon's `live_terminals` (via `codemux-remote serve status`) and **defers** the systemd-unit restart when sessions are live (`UpgradeOutcome::Skipped`); separately, the local pty-daemon now **idle-reaps** itself after 1h with zero sessions (hard re-check under lock so it can never reap a live session). (3) **Workspaces-sync robustness**: project-first remote pull with a real protected root (new local-only `default_branch` column + `resolve_default_branch`/`ensure_origin_head` + `workspaces_adopt_project` "Pull project" action), serialized adopts via a per-row creation lock, client-side `dedupe_sibling_rows` collapse of cross-device duplicate cards, daemon-side `collapse_main_for_uid`/`normalize_main_workspaces` (one repo root per project), uid-keyed collision-safe host paths (`<basename>-<short-uid>`), and a non-destructive `workspaces_reconcile_copy` action for legacy divergent copies. (4) **OpenFlow comm-log fix**: the daemon-backed agent spawn path (default since persistent agents) now tees cleaned PTY output to the communication log via the shared `comm_log_entry_for_chunk` helper, so daemon-spawned OpenFlow agents stop producing an empty log that blinded stuck-detection. See `docs/features/remote-hosts.md`, `docs/features/persistent-agents.md`, `docs/features/workspaces-sync.md`, `docs/features/workspaces-overview.md`, `docs/features/openflow.md`, `docs/plans/repo-unit-sync.md`.

docs/features/observability.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ All six pieces are bundled in `ObservabilitySnapshot` and persisted as one JSON
4545
- **No external exporter** — the data never leaves the local machine. No OTLP, no Prometheus, no structured log shipping. That's deliberate for v1 (local-first principle), but means remote debugging requires shipping the JSON file manually.
4646
- **Feature flags are boolean only** — no percentages, no ramps, no user targeting. A flag is either on or off for the current user.
4747

48+
## Native Log File (tauri-plugin-log)
49+
50+
Separate from `ObservabilityStore`, the desktop app installs a real
51+
`log`-crate logger via tauri-plugin-log (registered in `lib.rs`),
52+
writing warn-and-above to stderr **and** to a rotating file in the
53+
platform app-log dir (`~/.local/share/com.codemux.app/logs/codemux.log`
54+
on Linux, 2 MB cap, one rotation kept). This exists because
55+
dependencies report real failures through the `log` crate — rfd's
56+
"Failed to pick folder" when no dialog backend exists (issue #95) was
57+
invisible before a logger was installed.
58+
59+
Support surface:
60+
61+
- `codemux logs [--tail <n>]` — print recent log lines, no running app
62+
required (`src-tauri/src/app_logs.rs`).
63+
- `codemux doctor` — environment diagnostics including the file-dialog
64+
backend preflight (`src-tauri/src/doctor.rs`,
65+
`src-tauri/src/dialog_preflight.rs`).
66+
4867
## Important Touch Points
4968

5069
- `src-tauri/src/observability.rs`:

docs/features/workspace-creation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ After onboarding: scripts saved to project config, worktree workspace created, w
6868
- No workspace templates or saved configurations
6969
- No multi-issue linking (one issue per workspace)
7070
- Package detection is best-effort (one pass on project open)
71+
- Native folder/file pickers on Linux need either a working XDG
72+
desktop portal (with a FileChooser backend such as
73+
xdg-desktop-portal-gtk) or zenity installed. When neither exists
74+
(minimal i3/dwm setups — issue #95), the Rust side preflights and
75+
rejects with a `NO_FILE_PICKER_BACKEND` error, and every UI call
76+
site goes through `src/lib/file-dialog.ts`, which shows an
77+
install-hint toast instead of silently doing nothing. `codemux
78+
doctor` diagnoses this from a terminal.
7179

7280
## Important Touch Points
7381

docs/reference/CONTROL.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,26 @@ codemux browser snapshot
6565
codemux memory show
6666
codemux handoff
6767
codemux index build
68+
codemux logs --tail 200
69+
codemux doctor
6870
```
6971

72+
## Local Diagnostics
73+
74+
`codemux logs` and `codemux doctor` run entirely locally — no running
75+
Codemux instance or control socket needed, so they work precisely when
76+
the app itself is misbehaving.
77+
78+
- `codemux logs [--tail <n>]` prints the last `n` lines (default 200)
79+
of the desktop app's persistent log file (written via
80+
tauri-plugin-log to the platform app-log dir, e.g.
81+
`~/.local/share/com.codemux.app/logs/codemux.log` on Linux).
82+
- `codemux doctor` checks the local environment and prints an
83+
actionable report: desktop/session info, whether the XDG desktop
84+
portal file chooser or the zenity fallback is available (file
85+
dialogs silently failed on portal-less minimal WM setups before the
86+
issue #95 fix), and where the log file lives.
87+
7088
## Browser Note
7189

7290
From agent terminals, always use explicit `codemux browser ...` subcommands. Do not use `xdg-open`, `open`, or any other system-browser launcher when the goal is to work inside Codemux.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)