Skip to content

Run Panel

The Run tab in the right sidebar launches a project's dev servers (e.g. npm run dev, cargo run, a Makefile target) without opening a terminal and typing the command by hand. It reads the project's manifests, lists the runnable commands, runs the chosen one as a hidden background process, detects the port it binds to, and surfaces clickable URLs - localhost for the machine that runs it, plus the owning node's tailnet (Tailscale) and LAN addresses so you can open it from another device.

What it does

  • Manifest detection. On opening a project, the panel walks the project tree (up to 3 directories deep, skipping node_modules, target, dist, build, out, vendor, virtualenvs, and dotfolders) for supported manifests and lists every runnable command, grouped by ecosystem. Manifests nested in monorepo members - e.g. a Cargo workspace's crates/<app>/package.json - are found and labelled by their relative directory; running one launches it in that subdirectory. Supported manifests:
    • package.json - one entry per scripts key; the package manager is inferred from the nearest lockfile (pnpm-lock.yaml → pnpm, yarn.lock → yarn, bun.lockb/bun.lock → bun, otherwise npm), falling back to the root's manager when a nested package has no lockfile of its own.
    • Cargo.toml - cargo run, plus cargo run --bin <name> per [[bin]].
    • Makefile / makefile / GNUmakefile - make <target> per target.
    • justfile - just <recipe> per recipe.
    • pyproject.toml - [tool.poetry.scripts] / [tool.pdm.scripts] entries.
    • A free-form Run a command… input runs any ad-hoc command line. A bookmark button beside it saves the typed command as a pinned custom runner (see Save a command below) without running it.
  • Run. Starts the command as a PTY session on the project's owning node, marked hidden and tagged dev-server. Hidden sessions are kept out of the normal terminals list - they appear only under Running in this panel.
  • Pin / Unpin. Any runner, detected or custom, can be pinned. Pinned runners float to a Pinned section at the top of the list, the same idea as the Commands panel. Pins are remembered per project.
  • Save a command. The bookmark button next to Run a command… persists the typed command as a pinned custom runner instead of running it. Custom runners appear under a Custom group (or the Pinned section when pinned) and carry a trash button to remove them. Detected runners cannot be removed; they are re-derived on each manifest scan.
  • Save to Cmds. Each runner row has a button that copies its command into the Commands panel as a pinned command, so you can also type it into a terminal without submitting. Commands move both ways between the two panels - the Commands panel has a matching Save to Run button.
  • URL detection. The daemon watches the process output for the host:port it prints (e.g. Vite's http://localhost:5173/) and computes the reachable URLs on the owning node, so the tailnet/LAN addresses are correct even when you are connected to a different cluster node. Clicking a URL chip opens it in your system default browser.
  • Open. Reveals the hidden process's terminal in the focused pane so you can watch logs or interact with it. It stays hidden from the normal session list.
  • Stop. Kills the session. The daemon tears down the entire process tree (SIGTERM, then SIGKILL after a grace period), so the port is released and no orphaned node/child process is left holding it.

Remote reachability

URLs are computed from the owning node's addresses:

  • Local (http://localhost:PORT) - only reachable from the machine running the server.
  • Tailnet - the node's MagicDNS name (e.g. host.tailnet.ts.net) or its 100.x Tailscale IP.
  • LAN - the node's LAN/DHCP address.

For the tailnet/LAN URLs to actually load, the dev server must listen on a non-loopback interface (0.0.0.0). When the server only printed localhost / 127.0.0.1, the panel still shows the remote URLs but adds a hint that remote access requires binding 0.0.0.0 (e.g. Vite --host, Next -H 0.0.0.0). Hive does not inject host flags automatically, since the flag differs per tool.

Implementation notes

Dev servers reuse the normal session machinery - there is no separate process registry:

  • Protocol. ClientMessage::NewSession carries tags; a session tagged dev-server ([DEV_SERVER_TAG]) is created hidden. The detected URLs live on SessionInfo.dev_server (DevServerInfo { port, bound_host, urls }), so they flow through the existing session list / SessionUpdated / cluster replication paths - no new push or list message.
  • Daemon. SessionManager::spawn_dev_server_watcher subscribes to the session's output broadcast; session/dev_urls.rs scans each line (ANSI stripped) for a host:port and computes the URLs from local_addrs::detect_local_addresses + the Tailscale Self.DNSName. The detected info is stored on the session and announced via session_resized_tx (live push to local clients) plus a SessionUpdated cluster mutation.
  • Frontend. lib/projectRunners.ts holds the pure manifest parsers plus the depth-bounded tree walk (detectRunners) that finds nested manifests; stores/devServers.ts orchestrates detection (via the files store), start (hidden + tagged session), stop (KillSession), open (switchTab), opening URLs (lib/openUrl.ts, which uses the Tauri shell plugin on desktop and window.open in the browser), and the saved runners (togglePin, addCustom, removeSaved). The UI is components/sidebar-right/RunPanel.vue.

Persistence

Custom runners and pins are stored per project; plain detected runners are not, they are re-derived on each manifest scan. Only entries worth remembering (custom or pinned) are saved.

  • In the Tauri desktop/mobile app, they live under a runners map in the same project-ui-state.json the Commands panel uses, via the load_project_runners / save_project_runners commands (local app-state only, not the daemon protocol).
  • In browser-shim mode, the same shape is persisted in localStorage["hive:project-runners"].

Detected URLs are not persisted: after a daemon restart the process is gone, and the port is re-detected from output when a server is started again.

Hive - remote AI coding agents over WebSocket.