Repository navigation
Machines: view and control another computer's localhost over SSH - #67
Merged
Merged
Conversation
…he Runs it starts
… --stdio`, and reach it over the system's ssh with Forwards
…cted, reconnecting after a loss
… before the apps show it
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…der doesn't exceed a Unix socket's path limit
4 tasks
…s a Machine's destination
… user, instead of retrying it forever
…ts, add a Machine only once it is reached, and open its Services through a Forward
… through a Forward, with the hosts of ~/.ssh/config
…place, and MachinesStore, a main-actor mirror
…section each, their logs, and Open through a Forward
…specta reads them
…, a sidebar section each, their logs, and Open through a Forward
… behave, and why they go through ssh
…hine over ssh run instead of skipping
… closure, keep folder commands to this Mac, and reopen a Machine's log once it reconnects
…ad of as an SSH failure, and name an incompatible shared core with what to do
… fit the column on both apps
marcellosso
marked this pull request as ready for review
November 5, 2026 02:42
…cting and every MachineProblem
…t file step, and answer the dev box question in the FAQ
…ectory and the structured data
Document Machines: docs page, guide, README, landing page and changelog
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#66, finished: the macOS app and the Linux/Windows app view and control another computer's localhost (a Machine) over the system's
ssh, with Forwards for Open in Browser. Creating and editing Projects on a Machine is #68, separate.Summary
sequenceDiagram participant App as App (Machines) participant SSH as ssh -M (ControlMaster) participant Relay as devbox: localhost remote --stdio participant Core as devbox shared core App->>SSH: ssh -T -M -S <0700 folder> devbox localhost remote --stdio SSH->>Relay: Machine protocol (JSON lines, versioned on its own) Relay->>Core: Client::Machine, changes as Origin::Machine Core-->>Relay: Projects, statuses, events, logs (no Secret values) App->>SSH: ssh -O forward -L 127.0.0.1:P:localhost:P (+ [::1])Machinesin the core now keeps each Machine's Projects and statuses across reconnects and publishes them in one stream, so both apps mirror one subscription instead of re-subscribing per connection:core/localhost-core/src/ ├── machine/ │ ├── machines.rs + the view per Machine, add-then-save, rename, controls, Open +│ ├── ssh_config.rs # ~/.ssh/config hosts, read only │ └── ssh.rs + user@host:port → ssh://…, PortConflict names the local holder ├── listener.rs + holding(port) └── ffi/ + Machines object, MachinesEvents, ssh hosts, state wording apps/macos/ ├── LocalhostCoreFFI/…/Machines.swift # typed calls, LogSource, MachinesStore (main-actor mirror) └── App/ Settings › Machines, sidebar section per Machine, logs, Open via Forward apps/desktop/ ├── src-tauri/src/machines.rs # commands + a CoreView-shaped view per Machine └── src/ machines.ts store, Sidebar sections, Settings › Machines, place-aware actions/shortcutsIn both apps a Machine's Project rows look and act like local ones (Start, Stop, Restart, Start All, logs, Open in Browser), dimmed and disabled while it isn't connected, and identity is (Machine, UUID). Editing actions are hidden for now (#68). Settings › Machines: an SSH host field suggesting
~/.ssh/confighosts (oruser@host:port), an optional Name, Add connects first and shows theMachineProblemwith its next step; each row shows the destination, its state, and ⋯ Reconnect / Rename / Remove. Settling Services are announced on both platforms; quitting asks when Services started from here on a Machine are active.When localhost on a Machine starts but can't serve (e.g. its shared core is an older version's, kept by an agent's
localhost mcp), it says why with arefusedline instead of the hello, shown asMachineProblem::CantServein that Machine's words rather than as an SSH failure; older apps still see the connection end. The shared core's version clash is now a typedLocalhostError::IncompatibleCorewith a next step, here and on the Machine. While adding, a problem names the host it tried.Also, from trying it: the first-run empty state's three actions are stacked at one width, as they overflowed the column on the desktop app and squeezed on the Mac.
Also:
MachineProblem::Other(whatever SSH says that localhost doesn't recognize, e.g. a~/.ssh/configmistake) is shown once and waits for Reconnect instead of retrying forever; a reset or closed connection counts asUnreachableand is retried.Evidence
Before: apps couldn't show a Machine;
bindings.tswas stale;Otherlooped every 30 s forever;machines_sshskipped in CI.After:
Log view on WebKitGTK (CI, 4 Services × 1000 lines/s × 30 s, 3 rounds; the first attempt hung on the runner and passed on a rerun, and it ran normally here with the same settings):
cargo test,cargo clippy --all-targets(also--features ffiand--target x86_64-pc-windows-msvc),cargo fmt --check,pnpm typecheck,pnpm test(103),pnpm build, andsrc-tauricargo test+ clippy all pass on Linux.Built and tried on the Mac against the dev box over Tailscale: Add Machine, its Projects in the sidebar, and its problems (
NotInstalledfor a host without localhost, thenCantServewhile an old 0.4.0 core ran there). The desktop GUI hasn't been run against a Machine, only its tests.Merge Danger
Door: two-way, mostly.
PROTOCOL_VERSION7 → 8: a 0.4.0 client and a core from this branch refuse each other, as with any release, and updates retire the old core. Once released,machines.json(schema 1) and Machine protocol 1 become commitments, though the protocol only grows.Blast Radius: both apps
AppModel's and the desktop's actions gained a place (default this computer), the selection amachineProjectcase, andopen_logamachine_idargument. Local behaviour should be unchanged, but those paths are touched in both UIs. Each app openssshconnections at launch for Machines the user added; with none added, nothing new runs.Left out
port_probe::tests::sees_a_listener_on_either_loopback_addressfailed once in a full run here and passed alone 5/5: it asserts a freed ephemeral port is closed, which a parallel test can rebind. Pre-existing, not touched.Also carries the docs and website for Machines (#70, for #69): README,
site/docs and guide, the landing page, and the 0.5.0 changelog entry.Closes #66