Future work
Designs for parts the app does not have yet, and what it leaves out on purpose
The pages in this section keep the designs for parts that are not built yet, so the work starts from them when it is picked up. Each page says at the top what of it is built. Smaller deferrals are marked "Simpler choice" on their own pages.
The designs follow the rules of the app as it is built: herdr is the source of
truth, the app reaches each machine through run (over the relay on a remote
machine)
(Running commands), and the app
never calls herdr's focus methods. A design gets decision numbers on the
Decisions page when it is built.
Changes panel
What the agents changed: git diffs in a drawer, a git chip, the last turn
Floating pills
Agent status on the Mac screen edge while you work in another app
iPhone and iPad
One pane per page on iPhone, the Mac layout on iPad
Rex as a second multiplexer
How Rex fits behind the Multiplexer interface
Smaller items
-
herdr's machines in Add Machine. When herdr is on the Mac, the dialog lists the targets of the enabled entries of
herdr machine list --json({id, label, target, session, enabled}) that are not in the app's list, each with a checkbox. While the app's list is empty, they start checked. The app never writes herdr's list (The machine list). -
Image paste. ⌘V with an image and no text on the clipboard, in a terminal or agent card or the chat reply box: the app encodes it as PNG, copies it to the pane's machine as a dropped file is copied (
Exec.upload, at most 16 MB, over the relay on a remote machine; Drag and drop), and pastes the copy's path (or adds it to the chat draft). Agents such as Claude Code read the image from the path. A larger image shows "Image too large to paste". herdr's own remote client, uHerdr, collie, termote and roamgate do the same. Rejected: image bytes through the terminal (herdr's stream and agents do not take them); a server helper. -
Reorder the machines in the machine menu.
-
herdr inside the app (herdr-core), so the user never installs herdr or needs to know about it: no mention of herdr anywhere in the app's UI.
-
Releases and updates: CI builds a notarized Developer ID
.dmgand.appon a version tag and uploads them to GitHub (signed ad hoc now: Platform), and the app checks for updates and tells the user. -
Anonymous telemetry: daily users, error reports and other usage numbers, sent to a hosted analytics service.
-
Richer agent notifications than the needs-you and finished banners (Status).
-
Local Network privacy (macOS 15 and later). An
sshthat the app starts counts as the app, so a target on the local network fails with "No route to host" today. The plan: the app declaresNSLocalNetworkUsageDescription, resolves the target withssh -G, and opens anNWConnectionto a local address before the first SSH connection, so the system asks once. If the user says no, the page shows "Allow Local Network access for Ovvi in System Settings › Privacy & Security". Tailscale addresses are not affected. -
VoiceOver reads the terminal. A terminal card gives VoiceOver its screen text, read with
pane.read {source:"visible", format:"text"}when VoiceOver asks for it, and announces new output politely (it does not interrupt speech). Today the card gives only its grid size. -
tmux as one more implementation of the
Multiplexerinterface, after Rex. Research:tmux.md. -
Jump to the next agent that needs you with one key, in the sidebar's order. It selects space, tab and card in the app and never calls herdr's focus methods.
-
Faster git state: stat
HEAD,indexand the branch ref each second, and rungit statusonly on a change or an agent status change (Git status). On a remote machine each stat is a round trip, so batch them in onestatrun, or keep today's poll there. -
The rest of the browser pane (Browser):
- Find in the page: ⌘F, with
WKWebView's find in the same find bar. - "Open in Browser" as the palette's top row when the query is an address.
- The Web Inspector button lit (the accent on an accent circle at 0.07, as Zoom's Restore) while the inspector shows.
- An "Open :‹port›" chip on a terminal card whose screen shows a
localhostaddress. - Refresh, and the safe list in the Settings window, where the user can edit it.
- "‹machine› does not allow port forwarding": an
ssh -Wprobe after a refusal tells it from a closed port.
- Find in the page: ⌘F, with
-
The rest of the default plugins and of the plugin system: their Not built lists (default plugins, plugins), and a plugin setting with a value per machine (the browser's network is one value for new cards on every machine).
-
The rest of the chat view (Chat view):
- A host for the pill card: the chat at 360 pt, built when the floating pills land.
- Subagent rows: Claude Code's and Codex's subagents, OpenCode's child sessions.
- OpenCode 2.x, with its shared service and
/api/*routes. - A Codex fork with its parent's lines up to the fork
(
forked_from_ordinal_exclusive). Today it shows only its own lines.
-
Agents use a browser card. An agent can open a browser card and change its address (
ovvi open browser), nothing more. An agent that needs to drive a page runs its own browser on its machine (Playwright, chrome-devtools-mcp). WKWebView has no automation protocol. A later design lets an agent ask the app, through theovvicommand (Agent control), to read, run script in or capture one browser card it is allowed to. It needs its own consent design. -
Terminal keys to check against libghostty (herdr-gpui's defaults, research): ⇧↩ sent as Esc and CR, because herdr sends a bare CR for Shift-Enter to a program without kitty keys, which submits an agent's prompt. Option as Alt "auto": the left Option key is Alt on US and ABC layouts, and the right one types accents. First check what the app sends today.
-
Back and Forward through the panes the keyboard visited, and ⇧⌘T to reopen the last closed tab (a new tab in its folder: its programs ended with it). Back and Forward need their own keys: ⌘[ and ⌘] step panes, and ⌃- ⌃⇧- are a plugin card's.
-
herdr plugin values. herdr's TUI shows what herdr plugins report:
agents[].tokens,state_labelsandtab_bar_right. The app shows them too, read only, where herdr's TUI does. It never writes herdr's sharedconfig.toml. -
A remote home shown as
~in card headers, and Go to Directory on a remote machine. -
A bigger server helper. The relay already carries every run of a remote machine on one SSH session (The SSH connection). A helper of our own with more to do (a file watcher, a port forwarder) would sit behind the same
runcall. Build it only when one of these is real:- Latency: a plugin needs many small calls (a file tree, search), and users on slow links feel it.
- File watching: a plugin needs pushed file changes, not a check every 2 s.
AllowTcpForwarding no: a server refuses the port forwards that browser panes use.- Windows servers: herdr supports them; the
shenvelope does not.
Plugins, labels and state files stay the same when it comes. Research:
plugins.md.
Waiting on herdr
- herdr's popup in a floating window. On herdr 0.9.5,
plugin.pane.openwithplacement: "popup"answers onlyok. The popup's terminal runs in the server, but it has no pane or terminal id in the reply, the snapshot orpane.list, and opening or closing it (popup.close) sends no event. Theplugin_pane_openedreply comes only for the other placements, which are normal panes. The ask: the popup (its terminal id and size) insession.snapshot, events when it opens and closes, and a close by id (popup.closetakes no parameters). Ovvi then streams it by that id in a floating window, as it does a floated pane. - Panes started with a command after a cold restart come back as plain
shells, with their label. The ask: restore them with their
launch_argv, opt-in (discussion #1367). Web and plugin panes work anyway, because the label is the truth (Labels and instance ids). - Clipboard writes on the terminal stream. herdr 0.9.5 gives a pane's
OSC 52 write (
ServerMessage::Clipboard) only to its foreground TUI client, andterminal session controlprints only frames and the close. The ask: aterminal.clipboardevent on the control stream, sent to the client that streams the pane. Then the app puts it on the clipboard, and every program's copy works from a remote machine, as pi-hkandala's copy does throughovvi copy(Scrolling, queries and links). - Named keys on the terminal stream. The ask: herdr accepts named keys on
terminal.input({"type":"terminal.input","keys":["up"]}), encoded aspane.send_keysdoes. Then all input takes one path, with no request per key burst, which matters over SSH (Terminal plane). - Claude Code's transcript path. herdr's Claude hook sends
transcript_path, but herdr 0.9.5 keeps a path inagent_sessiononly for pi and omp. The ask: keep it for Claude Code. Then the chat view could take the path from herdr instead of its own SessionStart hook. - Blocked for menus, and forks. herdr 0.9.5 reports
idlewhile an agent shows a picker (Claude Code, Codex and opencode model and session pickers) or a pi extension dialog, and keeps the oldagent_sessionafter Claude Code's/branchand Codex's/fork. The ask:blockedfor those, and the new session after a fork. Then the chat view needs no screen check for Codex before a send. - OSC 7501, the Program Status Protocol: a terminal escape sequence that a
program sends to report its status
(spec). herdr
does not support it yet. Draft PR
#5172 adds
program_statustopane.getandpane.list, and a change to it alone sends no event. Once herdr ships it, the app shows itsmessageon needs-you and finished rows and in notifications, and says "failed" forerror. Another multiplexer may report it through its own API (Rex).
Left out on purpose
- Tearing a tab off into a new window: a tab belongs to its herdr space, and a window shows pages, not single tabs.
- Key sequences and custom shortcuts: macOS menus hold the shortcuts.
- Traffic lights inside the tab bar: needs private API
(
setCustomTitlebarHeight:). - Jump to prompt: needs OSC 133 marks, and herdr's frames carry none.
- A font size per pane (one text size for the app), paste confirmation (small; on request), an installer for agent integrations (herdr's own installer writes the agents' config files; it belongs with the Settings window).
- Many themes and a theme editor: the user wants only light, dark, Glass and Classic. A compact density: the user dropped it.
- A menu bar status item: the floating pills would cover it.
- A diagnostics window: not interface work.
- Decorations with a GPU cost (Rex's melt transition, selection pulse).
- Rex's theme, material or decompiled files in the repo: Ovvi copies looks by measuring, never Rex's files or icon art.