Skip to content

feat(workspace): native OS directory picker (#3074) + per-host recents - #3246

Open
ptr-syrto wants to merge 1 commit into
omnigent-ai:mainfrom
ptr-syrto:feature/native-workspace-picker-recents
Open

feat(workspace): native OS directory picker (#3074) + per-host recents#3246
ptr-syrto wants to merge 1 commit into
omnigent-ai:mainfrom
ptr-syrto:feature/native-workspace-picker-recents

Conversation

@ptr-syrto

Copy link
Copy Markdown

Native workspace picker: recents + system directory dialog

Summary

The new-session workspace chip opens a popover that jumps straight into the
in-app folder browser, with no memory of where you worked last and no way to
use the OS's own directory picker. This adds:

  • A per-host Recents list (most-recent-first) above the picker, populated
    as workspaces are selected.
  • A "Use system dialog…" button, shown only when the selected host is the
    local Electron desktop host and that host advertises the
    native_directory_dialog capability. Clicking it asks the local host to
    open the macOS-native directory chooser (NSOpenPanel via osascript) and
    fills the workspace path with the chosen absolute directory.
  • The existing in-app WorkspacePicker remains directly below, unchanged, as
    the fallback for every other host/platform combination.

Closes #3074

Key design decisions

  • Background dialog task + keepalive safety. The native dialog runs as a
    background task on the host so a long-lived osascript picker dialog can't
    block or time out the request; the host connection keepalive is tracked
    independently so a slow user pick doesn't get treated as a dead host.
  • Server-side capability enforcement + client-side locality gate. The
    server only allows the native-dialog call when the target host's advertised
    capabilities include native_directory_dialog; the client only shows the
    button when the selected host is additionally the local Electron desktop
    host (capability alone isn't sufficient — see nit below).
  • Host-switch race guard. Switching the selected host while a native
    dialog request is in flight discards the stale response instead of
    populating the workspace path for the wrong host.
  • Record-on-selection recents. Recents are recorded when a workspace is
    actually selected (not just browsed to), keyed per host, most-recent-first,
    capped and persisted in localStorage under omnigent:recent-workspaces.
  • macOS-only native dialog. The native dialog is macOS-only for now;
    Windows/Linux hosts report the capability as unsupported and always fall
    back to the in-app picker.

Demo

Screenshots attached below in the GitHub PR editor. Captions:

  • Workspace popover (full): Recents list and "Use system dialog…" button above the in-app WorkspacePicker fallback.
  • Workspace popover (focused): focused crop of the popover.
  • Recents list: the Recents section on its own, most-recent-first.

Manual repro steps

  1. Run the Electron desktop app (or the web app pointed at a host that
    advertises native_directory_dialog) and open New session.
  2. Click the workspace chip to open the popover.
  3. Confirm the Recent section lists previously-selected workspace paths
    for the current host, most-recent-first, and that clicking an entry
    selects it.
  4. On the local Electron host, confirm Use system dialog… appears above
    the in-app picker; click it, choose a folder in the native macOS chooser,
    and confirm the workspace path updates to the chosen absolute path.
  5. Switch to a non-local host (or a platform without the capability) and
    confirm the button disappears, leaving only Recents + the in-app picker.

Verification

  • pytest (host/server suites touched by this change):
    203 passed. One unrelated pre-existing failure,
    tests/host/test_connect.py::test_run_host_process_announces_session_log_dir_on_start,
    is a log-ordering assertion untouched by this diff and reproduces the same
    way on main.
  • web: tsc -b clean, no type errors.
  • web: lint clean on all files touched by this change except the
    pre-existing index-key warning noted below.
  • web unit tests (NewChatDialog.test.tsx and friends) exercise the new
    recents/native-dialog behavior directly; full-suite validation happens in
    CI because this machine's local Vitest run hits a pre-existing
    jsdom/localStorage environment bug affecting ~40 unrelated test files.

Known nits

  • Pre-existing index-key warning: NewChatDialog.tsx uses an array index as
    a React key in one list render, flagged by no-array-index-key; this
    predates this change and isn't introduced by it.
  • Locality is intentionally capability + ownership, not capability alone:
    a host can advertise native_directory_dialog without being the local
    Electron desktop host (e.g. a remote macOS host), and the button should
    only appear when the user's own machine can show a native dialog. This
    is by design, not an oversight.

Type of change

  • New feature
  • Bug fix
  • Refactor
  • Documentation
  • Other

Test coverage

  • Unit tests
  • Manual verification completed
  • Not applicable

Coverage notes

Manual verification: captured live screenshots of the popover (Recents list +
"Use system dialog" button + fallback picker) via a Playwright script against
the real Vite dev server, with a test-harness-only Electron identity stub and
localStorage seed (see Demo section). Backend behavior (capability
enforcement, background dialog task, keepalive, host-switch race guard) is
covered by tests/server/integration/test_hosts_native_directory_dialog.py
and the updated tests/host/test_connect.py / tests/host/test_frames.py /
tests/server/test_host_registry.py suites (203 passing, see Verification).

…host recents

Add an OS-native directory chooser for local workspace selection in the
new-session dialog and surface per-host recents as a clickable list.

Native dialog:
- Host advertises a `native_directory_dialog` capability (macOS + GUI
  session only); Windows/Linux report unsupported and fall back.
- macOS opens an NSOpenPanel-style `choose folder` via osascript and
  returns the chosen absolute path over the authenticated host tunnel.
- Dialog runs as a background task so host keepalives keep flowing;
  concurrent requests are rejected; disconnect fails pending futures
  fast (502, not a 300s hang).
- Server enforces the capability (422 if absent); client additionally
  gates on the local Electron desktop host identity (capability alone
  is insufficient).
- Host-switch race: the result is discarded unless the selected host
  still matches when the promise resolves.
- Absolute-path invariant enforced at the frame decode boundary.

Recents:
- Per-host most-recent-first list in the workspace popover, capped at 8,
  persisted under `omnigent:recent-workspaces`. Recorded on selection
  (native pick + recent click) and on session create. Existing schema
  and ForkSessionDialog usage unchanged.

The in-app WorkspacePicker remains the always-available fallback for
remote/headless/unsupported/older hosts; no protocol-compatibility break.

Co-authored-by: penny (Omnigent) <penny@omnigent.ai>
@github-actions github-actions Bot added the size/XL Pull request size: XL label Jul 24, 2026
@github-actions
github-actions Bot requested a review from daniellok-db July 24, 2026 15:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Pull request size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Use the OS-native directory picker for local workspace selection

2 participants