This repository has been archived on 2026-08-23. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files

307 lines
15 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PI WEB fleet — remote Pi web UI machines</title>
<meta
name="description"
content="Connect trusted PI WEB runtimes through machine federation so one web UI can supervise local and remote projects, sessions, files, git state, terminals, Pi packages, and plugins."
/>
<link rel="canonical" href="https://pi-web.dev/machines" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="PI WEB fleet — remote Pi web UI machines" />
<meta
property="og:description"
content="Use one PI WEB instance to reach trusted local and remote Pi Coding Agent machines."
/>
<meta property="og:url" content="https://pi-web.dev/machines" />
<meta property="og:image" content="https://pi-web.dev/assets/pi-web-banner.png" />
<meta property="og:image:alt" content="PI WEB browser UI for persistent Pi Coding Agent sessions" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="PI WEB fleet — remote Pi web UI machines" />
<meta
name="twitter:description"
content="Use one PI WEB instance to reach trusted local and remote Pi Coding Agent machines."
/>
<meta name="twitter:image" content="https://pi-web.dev/assets/pi-web-banner.png" />
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg" />
<script>
(() => {
const theme = window.localStorage.getItem("pi-web-theme");
if (theme === "light" || theme === "dark") document.documentElement.dataset.theme = theme;
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=IBM+Plex+Sans:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="site-header">
<nav class="container nav" aria-label="Main navigation">
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first">Remote-first</a>
<a href="machines" aria-current="page">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins">Plugins</a>
<a href="faq">FAQ</a>
</div>
<div class="nav-actions">
<a class="github-link" href="https://github.com/jmfederico/pi-web" aria-label="PI WEB on GitHub">
<svg class="github-icon" viewBox="0 0 16 16" aria-hidden="true">
<path
fill="currentColor"
d="M8 0C3.58 0 0 3.67 0 8.2c0 3.63 2.29 6.7 5.47 7.79.4.08.55-.18.55-.4 0-.2-.01-.85-.01-1.55-2.01.38-2.53-.5-2.69-.96-.09-.24-.48-.96-.82-1.16-.28-.16-.68-.56-.01-.57.63-.01 1.08.59 1.23.84.72 1.24 1.87.89 2.33.68.07-.53.28-.89.51-1.09-1.78-.21-3.64-.91-3.64-4.04 0-.89.31-1.62.82-2.2-.08-.2-.36-1.03.08-2.16 0 0 .67-.22 2.2.84A7.4 7.4 0 0 1 8 3.94c.68 0 1.36.09 2 .28 1.53-1.06 2.2-.84 2.2-.84.44 1.13.16 1.96.08 2.16.51.58.82 1.31.82 2.2 0 3.14-1.87 3.83-3.65 4.04.29.26.54.76.54 1.53 0 1.1-.01 1.99-.01 2.27 0 .22.15.49.55.4A8.12 8.12 0 0 0 16 8.2C16 3.67 12.42 0 8 0Z"
/>
</svg>
<span>GitHub</span>
</a>
<button class="theme-toggle" type="button" data-theme-toggle aria-label="Toggle light and dark theme">
<span data-theme-icon aria-hidden="true"></span>
<span data-theme-label>Theme</span>
</button>
</div>
</div>
</nav>
</header>
<main>
<section class="page-hero">
<div class="container">
<p class="eyebrow"><span class="pulse"></span> PI WEB fleet</p>
<h1>Connect trusted PI WEB runtimes when one machine is not enough.</h1>
<p>
Most PI WEB setups only need one runtime. When you do have more than one, machine federation lets the PI WEB
instance you opened act as a gateway to other trusted runtimes while each machine keeps its own repositories,
credentials, sessions, Pi package settings, and plugins.
</p>
</div>
</section>
<section class="section compact">
<div class="container doc-layout">
<aside class="toc" aria-label="Machines page contents">
<strong>On this page</strong>
<a href="#what-it-is">What Fleet does</a>
<a href="#when-to-use">When to use it</a>
<a href="#prepare-machines">Set up another runtime</a>
<a href="#add-machine">Add a machine</a>
<a href="#what-is-proxied">What works remotely</a>
<a href="#auth-credentials">Credentials</a>
<a href="#plugins">Plugins</a>
<a href="#trust-model">Trust boundaries</a>
<a href="#storage-troubleshooting">Troubleshooting</a>
</aside>
<div class="doc-content">
<section id="what-it-is">
<h2>What Fleet does</h2>
<p>
A machine is a PI WEB runtime endpoint. The local machine is synthesized automatically. Remote machines
are opt-in PI WEB runtimes that you register with a base URL and, optionally, a bearer token.
</p>
<p>
After registration, the browser keeps talking to the current PI WEB origin. The gateway contacts the
selected remote PI WEB server and routes that machine's projects, workspaces, sessions, files, git state,
activity, terminals, and Pi package-management operations to the browser UI.
</p>
<div class="code-card">
<div class="copy-row">
<strong>Fleet shape</strong>
<button class="copy-button" data-copy="#federated-shape">Copy</button>
</div>
<pre id="federated-shape"><code>Browser
PI WEB gateway you opened
├─ [ Local runtime ]
├─ [ Remote PI WEB runtime A ]
│ ↓ selected machine
│ projects, workspaces, sessions, terminals, Pi packages, plugins
└─ [ Remote PI WEB runtime B ]</code></pre>
</div>
</section>
<section id="when-to-use">
<h2>When to use it</h2>
<p>
Federation is useful when you have more than one place where agents should work, but you want one stable
browser entrypoint.
</p>
<div class="cards">
<article class="card">
<div class="card-icon"></div>
<h3>Many dev boxes</h3>
<p>Register a workstation, home server, cloud VM, or client-specific host without moving repositories.</p>
</article>
<article class="card">
<div class="card-icon"></div>
<h3>One gateway</h3>
<p>Open one trusted PI WEB URL and switch machines instead of juggling browser tabs and tunnels.</p>
</article>
<article class="card">
<div class="card-icon"></div>
<h3>Local ownership</h3>
<p>Each target machine keeps its own Pi auth, sessions, worktrees, terminal state, Pi package settings, and plugins.</p>
</article>
</div>
</section>
<section id="prepare-machines">
<h2>Set up another runtime</h2>
<p>
Install and run PI WEB on every machine you want to register. The remote URL must be reachable from the
gateway server, not just from your browser.
</p>
<div class="code-card">
<div class="copy-row">
<strong>Install on each target</strong>
<button class="copy-button" data-copy="#target-install">Copy</button>
</div>
<pre id="target-install"><code><span class="prompt">$</span> npm install -g @jmfederico/pi-web --allow-scripts=node-pty
<span class="prompt">$</span> pi-web install
<span class="prompt">$</span> pi-web doctor</code></pre>
</div>
<p>
Prefer a private path such as NetBird, Tailscale, WireGuard, private LAN, SSH tunnel, or an authenticated reverse
proxy. If the remote is behind a path prefix, include that prefix in the machine URL, for example
<code>https://devbox.example.test/pi-web</code>. The machine registry normalizes the trailing slash; when
opening that deployment directly in a browser, use its canonical <code>https://devbox.example.test/pi-web/</code>
URL and configure the proxy to redirect the slashless form.
</p>
<div class="callout danger">
Do not expose PI WEB directly to the public internet. Register machines only over trusted network paths
and only when you trust the endpoint.
</div>
</section>
<section id="add-machine">
<h2>Add a machine</h2>
<ol>
<li>Open the PI WEB instance you want to use as the gateway.</li>
<li>Open <strong>Actions → Add Machine</strong>.</li>
<li>Enter the remote PI WEB base URL, including <code>http://</code> or <code>https://</code>.</li>
<li>Accept the suggested name or enter a friendlier sidebar label.</li>
<li>Paste an optional bearer token if the remote endpoint requires one.</li>
</ol>
<p>
The Machines section appears when there is more than one machine. Select a machine, then add projects,
workspaces, and sessions on that selected machine.
</p>
<div class="callout">
Removing a remote machine only removes it from this gateway's registry. It does not stop the remote PI WEB
service or delete projects, workspaces, sessions, or credentials on the target machine.
</div>
</section>
<section id="what-is-proxied">
<h2>What works remotely</h2>
<p>
After you select a machine, the rest of the app works in that machine's scope. The gateway routes the
selected-machine work to the target PI WEB runtime.
</p>
<ul>
<li>Projects and workspaces.</li>
<li>Files, previews, git status, and diffs.</li>
<li>Pi sessions, transcripts, prompts, model controls, and commands.</li>
<li>Activity indicators and realtime updates.</li>
<li>Terminals and terminal command runs.</li>
<li>Pi package listing, install, remove, and update from <strong>Settings → Pi packages</strong> when supported by the target PI WEB runtime.</li>
<li>Remote plugins from the selected machine.</li>
</ul>
</section>
<section id="auth-credentials">
<h2>Credentials stay on the target machine</h2>
<p>
Model-provider credentials, Pi configuration, Pi package-manager settings, OAuth state, repositories, and
active session runtimes stay on the selected target machine. The gateway does not copy them into its own
Pi configuration.
</p>
<ul>
<li>API-key provider configuration can be proxied through the gateway.</li>
<li>OAuth login should be completed by opening the remote PI WEB directly.</li>
<li>The optional machine bearer token is stored by the gateway and sent to the remote while proxying requests.</li>
</ul>
<p>
Use <strong>Actions → Open Selected Machine PI WEB</strong> when you need to authenticate directly on a
remote machine or inspect it outside the gateway.
</p>
</section>
<section id="plugins">
<h2>Plugins follow the selected machine</h2>
<p>
When you select a remote machine, PI WEB tries to load that machine's discovered plugins through the
gateway. Remote plugin actions, workspace panels, and workspace labels only appear while that machine is
selected, and documented file and terminal helpers run against that machine.
</p>
<p>
Remote plugins are still trusted browser-side code. Only federate machines whose PI WEB plugins you are
comfortable loading in the browser.
</p>
<p><a href="plugins#remote-machine-plugins">Read the remote machine plugin notes →</a></p>
</section>
<section id="trust-model">
<h2>Trust boundaries</h2>
<p>
Machine federation is for trusted users, trusted PI WEB servers, and trusted network paths. Adding a
machine gives the gateway permission to contact that URL and forward user-initiated PI WEB traffic to it.
</p>
<ul>
<li>Use private networking, an SSH tunnel, or an authenticated reverse proxy.</li>
<li>Do not include credentials in the machine URL itself.</li>
<li>Use bearer tokens or proxy authentication when a remote endpoint needs an extra gate.</li>
</ul>
</section>
<section id="storage-troubleshooting">
<h2>Troubleshooting</h2>
<p>
Remote machine records are stored on the gateway in <code>~/.pi-web/machines.json</code>. If
<code>PI_WEB_DATA_DIR</code> is set, they live under <code>$PI_WEB_DATA_DIR/machines.json</code>.
</p>
<ul>
<li>Use <strong>Actions → Refresh Selected Machine</strong> to re-check health.</li>
<li>Make sure the remote URL is reachable from the gateway server.</li>
<li>Open the remote PI WEB directly to verify it is running and to complete provider login flows.</li>
<li>Check gateway logs with <code>pi-web logs</code> for proxy timeouts or upstream errors.</li>
</ul>
<div class="doc-actions">
<a class="button primary" href="install#remote-access">Review remote access setup</a>
<a class="button" href="faq#remote-machines">Read remote machine FAQ</a>
</div>
</section>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<span>PI WEB fleet</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first">Remote-first</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins">Plugins</a>
<a href="faq">FAQ</a>
<a href="https://github.com/jmfederico/pi-web">GitHub</a>
</div>
</div>
</footer>
<script src="site.js"></script>
</body>
</html>