Merge branch 'main' into cleanup/plugin-api-scope

This commit is contained in:
Federico Jaramillo Martinez
2026-06-24 08:49:49 +02:00
102 changed files with 7292 additions and 1406 deletions
+20 -10
View File
@@ -6,8 +6,16 @@
<title>Page not found — PI WEB</title>
<meta name="description" content="The PI WEB page you requested does not exist." />
<meta name="robots" content="noindex" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="Page not found — PI WEB" />
<meta property="og:image" content="/assets/pi-web-banner.png" />
<meta property="og:url" content="https://pi-web.dev/404" />
<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="Page not found — PI WEB" />
<meta name="twitter:description" content="The PI WEB page you requested does not exist." />
<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>
(() => {
@@ -29,11 +37,12 @@
<a class="brand" href="/" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="/remote-first.html">Remote-first</a>
<a href="/machines.html">Fleet</a>
<a href="/install.html">Install</a>
<a href="/plugins.html">Plugins</a>
<a href="/faq.html">FAQ</a>
<a href="/remote-first">Remote-first</a>
<a href="/machines">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">
@@ -80,10 +89,11 @@
<div class="container footer-inner">
<span>PI WEB · remote control for persistent Pi Coding Agent sessions.</span>
<div class="footer-links">
<a href="/machines.html">Fleet</a>
<a href="/install.html">Install</a>
<a href="/plugins.html">Plugins</a>
<a href="/faq.html">FAQ</a>
<a href="/machines">Fleet</a>
<a href="/install">Install</a>
<a href="/config">Config</a>
<a href="/plugins">Plugins</a>
<a href="/faq">FAQ</a>
<a href="https://www.npmjs.com/package/@jmfederico/pi-web">npm</a>
</div>
</div>
+3
View File
@@ -0,0 +1,3 @@
# Canonical SEO redirects supported by Cloudflare Workers static assets.
# Host and scheme redirects need Cloudflare Redirect Rules or custom Worker routing.
/index.html / 301
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

+481
View File
@@ -0,0 +1,481 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Configure PI WEB — config files, paths, and session tools</title>
<meta
name="description"
content="Configure PI WEB config files, external path access, session daemon tools, plugins, shortcuts, uploads, and runtime environment variables."
/>
<link rel="canonical" href="https://pi-web.dev/config" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="Configure PI WEB" />
<meta
property="og:description"
content="Reference for PI WEB config files, path access allowlists, session daemon options, plugins, shortcuts, uploads, and environment variables."
/>
<meta property="og:url" content="https://pi-web.dev/config" />
<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="Configure PI WEB" />
<meta
name="twitter:description"
content="Reference for PI WEB config files, path access allowlists, session daemon options, plugins, shortcuts, uploads, and environment variables."
/>
<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">Fleet</a>
<a href="install">Install</a>
<a href="config" aria-current="page">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> Configuration reference</p>
<h1>Configure PI WEB where your agents work.</h1>
<p>
PI WEB configuration covers the machine-local and project-local settings you usually need: bind address,
trusted development-host settings, UI preferences, plugin enablement, file-explorer path access, upload
limits, and session-daemon tools.
</p>
</div>
</section>
<section class="section compact">
<div class="container doc-layout">
<aside class="toc" aria-label="Config page contents">
<strong>On this page</strong>
<a href="#files">Config files</a>
<a href="#precedence">Precedence and reloads</a>
<a href="#global-config">Global config</a>
<a href="#project-config">Project config</a>
<a href="#keys">Config matrix</a>
<a href="#path-access">External path access</a>
<a href="#session-tools">Session tools</a>
<a href="#completion-tools">Completion tools</a>
</aside>
<div class="doc-content">
<section id="files">
<h2>Config files</h2>
<p>PI WEB uses a global config file for machine-local settings and a project-local file for repository settings.</p>
<ul>
<li><strong>Global config:</strong> <code>$PI_WEB_CONFIG</code>, or <code>$XDG_CONFIG_HOME/pi-web/config.json</code>, or <code>~/.config/pi-web/config.json</code>.</li>
<li><strong>Project config:</strong> <code>&lt;project&gt;/.pi-web/config.json</code> for commit-able project settings.</li>
</ul>
<p>
Each PI WEB machine has its own config. When using Fleet/machine federation, edit a remote machine's
config by opening that machine directly or changing files on that machine.
</p>
<p>
If you installed services with a custom config path, rerun
<code>pi-web install --config /path/to/config.json</code> after changing that path or after upgrading from
a version that only applied the custom path to the web service. This regenerates service files so the
web/API and session daemon use the same <code>PI_WEB_CONFIG</code>.
</p>
</section>
<section id="precedence">
<h2>Precedence and reloads</h2>
<p>Runtime values are resolved in this order:</p>
<div class="code-card">
<pre><code>defaults → config file → environment overrides</code></pre>
</div>
<p>
Environment overrides include <code>PI_WEB_HOST</code>, <code>PI_WEB_PORT</code> / <code>PORT</code>,
<code>PI_WEB_ALLOWED_HOSTS</code>, <code>PI_WEB_MAX_UPLOAD_BYTES</code>, <code>PI_WEB_SPAWN_SESSIONS</code>,
and <code>PI_WEB_SUBSESSIONS</code>.
</p>
<ul>
<li><code>host</code> / <code>port</code>: restart the web/API service or process.</li>
<li><code>maxUploadBytes</code>: restart both the web/API process and the session daemon.</li>
<li><code>spawnSessions</code> / <code>subsessions</code>: restart the session daemon.</li>
<li><code>pathAccess</code>: applies on the next request; existing file views may need a browser refresh.</li>
<li><code>plugins</code>: reload the browser tab after changing plugin enablement.</li>
<li><code>shortcuts</code>: saved settings apply in the browser after config refresh/save.</li>
</ul>
</section>
<section id="global-config">
<h2>Global config example</h2>
<p>
<code>pi-web install</code> creates the initial file. You can also save settings from
<strong>Settings → General</strong>, <strong>Settings → Plugins</strong>, <strong>Settings → Keyboard</strong>,
and <strong>Settings → Session daemon</strong>.
</p>
<div class="code-card">
<div class="copy-row">
<strong>Example config.json</strong>
<button class="copy-button" data-copy="#global-config-example">Copy</button>
</div>
<pre id="global-config-example"><code>{
"host": "127.0.0.1",
"port": 8504,
"pathAccess": {
"allowedPaths": ["~/SDKs", "/opt/reference"]
},
"maxUploadBytes": 67108864,
"spawnSessions": true,
"subsessions": false,
"plugins": {
"workspace-tasks": { "enabled": true },
"updates": { "enabled": true },
"info": { "enabled": false }
},
"shortcuts": {
"core:view.chat": "mod+1",
"core:session.stop": null
}
}</code></pre>
</div>
</section>
<section id="project-config">
<h2>Project-local config</h2>
<p>
Project-local config lives at <code>&lt;project&gt;/.pi-web/config.json</code>. Use it for settings that should
follow a repository. When a project config defines <code>pathAccess</code>, PI WEB merges it after the
global path list.
</p>
<div class="code-card">
<div class="copy-row">
<strong>.pi-web/config.json</strong>
<button class="copy-button" data-copy="#project-config-example">Copy</button>
</div>
<pre id="project-config-example"><code>{
"version": 1,
"pathAccess": {
"allowedPaths": ["~/SDKs", "/opt/reference"]
}
}</code></pre>
</div>
<p>
Project-local <code>pathAccess.allowedPaths</code> entries must still be host-absolute or
<code>~</code>-prefixed; relative roots are not supported. Plugins may own separate project files, such as
<code>.pi-web/tasks.json</code> for the built-in Workspace Tasks plugin.
</p>
</section>
<section id="keys">
<h2>Config matrix</h2>
<p>
Use this table as the quick reference for where a setting can live, which environment variable overrides
it, and whether project-local config overrides or merges with global config. Rows with JSON key
<code></code> are runtime-only environment variables, not config-file keys.
</p>
<div class="table-scroll" role="region" aria-label="PI WEB configuration matrix" tabindex="0">
<table class="config-matrix">
<thead>
<tr>
<th scope="col">Config</th>
<th scope="col">JSON key</th>
<th scope="col">Env var</th>
<th scope="col">Scope</th>
<th scope="col">Project-local behavior</th>
<th scope="col">Applies / restart</th>
</tr>
</thead>
<tbody>
<tr class="table-section"><th scope="rowgroup" colspan="6">Config-file keys</th></tr>
<tr>
<td>Web/API bind host</td>
<td><code>host</code></td>
<td><code>PI_WEB_HOST</code></td>
<td>Global</td>
<td>Not supported locally</td>
<td>Restart web/API</td>
</tr>
<tr>
<td>Web/API port</td>
<td><code>port</code></td>
<td><code>PI_WEB_PORT</code>, <code>PORT</code></td>
<td>Global</td>
<td>Not supported locally</td>
<td>Restart web/API</td>
</tr>
<tr>
<td>Dev-server allowed hosts</td>
<td><code>allowedHosts</code></td>
<td><code>PI_WEB_ALLOWED_HOSTS</code></td>
<td>Global</td>
<td>Not supported locally</td>
<td>Restart dev web/UI</td>
</tr>
<tr>
<td>External filesystem roots</td>
<td><code>pathAccess.allowedPaths</code></td>
<td></td>
<td>Global + project</td>
<td><strong>Merges:</strong> global roots first, then project roots; duplicates removed</td>
<td>Next file request; refresh existing views if needed</td>
</tr>
<tr>
<td>Upload/body limit</td>
<td><code>maxUploadBytes</code></td>
<td><code>PI_WEB_MAX_UPLOAD_BYTES</code></td>
<td>Global</td>
<td>Not supported locally</td>
<td>Restart web/API and session daemon</td>
</tr>
<tr>
<td>Agent can spawn sessions</td>
<td><code>spawnSessions</code></td>
<td><code>PI_WEB_SPAWN_SESSIONS</code></td>
<td>Global/session daemon</td>
<td>Not supported locally</td>
<td>Restart session daemon</td>
</tr>
<tr>
<td>Tracked subsessions (beta)</td>
<td><code>subsessions</code></td>
<td><code>PI_WEB_SUBSESSIONS</code></td>
<td>Global/session daemon</td>
<td>Not supported locally; also requires <code>spawnSessions</code></td>
<td>Restart session daemon</td>
</tr>
<tr>
<td>Plugin enablement/settings</td>
<td><code>plugins.&lt;id&gt;.enabled</code>, <code>plugins.&lt;id&gt;.settings</code></td>
<td></td>
<td>Global</td>
<td>Not core local config; plugins may read their own project files</td>
<td>Reload browser tab</td>
</tr>
<tr>
<td>Keyboard shortcuts</td>
<td><code>shortcuts.&lt;actionId&gt;</code></td>
<td></td>
<td>Global</td>
<td>Not supported locally</td>
<td>Applies after settings save/config refresh</td>
</tr>
<tr>
<td>Project config version</td>
<td><code>version</code></td>
<td></td>
<td>Project</td>
<td>Project-local only; must be <code>1</code> when present</td>
<td>Next project-config read</td>
</tr>
<tr class="table-section"><th scope="rowgroup" colspan="6">Runtime-only environment variables</th></tr>
<tr>
<td>Global config file path</td>
<td></td>
<td><code>PI_WEB_CONFIG</code> (<code>XDG_CONFIG_HOME</code> affects the default path)</td>
<td>Process/env</td>
<td>Selects the global config file; not a project config</td>
<td>Restart services/processes after changing env</td>
</tr>
<tr>
<td>Managed data directory</td>
<td></td>
<td><code>PI_WEB_DATA_DIR</code></td>
<td>Process/env</td>
<td>Not supported locally</td>
<td>Restart services before changing; moves managed state location</td>
</tr>
<tr>
<td>Session daemon socket</td>
<td></td>
<td><code>PI_WEB_SESSIOND_SOCKET</code></td>
<td>Web/API + session daemon env</td>
<td>Not supported locally</td>
<td>Restart daemon and web/API; both must match</td>
</tr>
<tr>
<td>Session daemon TCP port</td>
<td></td>
<td><code>PI_WEB_SESSIOND_PORT</code></td>
<td>Session daemon env</td>
<td>Not supported locally</td>
<td>Restart session daemon; set <code>PI_WEB_SESSIOND_URL</code> for web/API too</td>
</tr>
<tr>
<td>Session daemon TCP host</td>
<td></td>
<td><code>PI_WEB_SESSIOND_HOST</code></td>
<td>Session daemon env</td>
<td>Not supported locally</td>
<td>Restart session daemon</td>
</tr>
<tr>
<td>Web-to-daemon URL</td>
<td></td>
<td><code>PI_WEB_SESSIOND_URL</code></td>
<td>Web/API env</td>
<td>Not supported locally</td>
<td>Restart web/API</td>
</tr>
<tr>
<td>Projects storage file</td>
<td></td>
<td><code>PI_WEB_PROJECTS_FILE</code></td>
<td>Web/API + session daemon env</td>
<td>Not supported locally</td>
<td>Restart services; advanced state override</td>
</tr>
<tr>
<td>Remote machines storage file</td>
<td></td>
<td><code>PI_WEB_MACHINES_FILE</code></td>
<td>Web/API env</td>
<td>Not supported locally</td>
<td>Restart web/API; advanced state override</td>
</tr>
<tr>
<td>Pi session storage directory</td>
<td></td>
<td><code>PI_CODING_AGENT_SESSION_DIR</code></td>
<td>Pi/session daemon env</td>
<td>Not supported locally</td>
<td>Restart session daemon; follows Pi session priority</td>
</tr>
<tr>
<td>Pi agent config directory</td>
<td></td>
<td><code>PI_CODING_AGENT_DIR</code></td>
<td>Pi/Web/API/session daemon env</td>
<td>Not supported locally</td>
<td>Restart services</td>
</tr>
<tr>
<td>Skip update checks</td>
<td></td>
<td><code>PI_WEB_SKIP_VERSION_CHECK</code>, <code>PI_WEB_OFFLINE</code>, <code>PI_SKIP_VERSION_CHECK</code>, <code>PI_OFFLINE</code></td>
<td>Web/API env</td>
<td>Not supported locally</td>
<td>Restart web/API after env changes</td>
</tr>
</tbody>
</table>
</div>
</section>
<section id="path-access">
<h2>External path access</h2>
<p>
<code>pathAccess.allowedPaths</code> grants PI WEB's file explorer and absolute <code>@</code> path
completions access to specific filesystem roots outside the current workspace. By default,
workspace-relative file reads stay inside the workspace and absolute paths are denied.
</p>
<p>Accepted root forms:</p>
<ul>
<li>Unix absolute paths, for example <code>/opt/reference</code>.</li>
<li>Home-relative paths, for example <code>~/SDKs</code>.</li>
<li>Windows absolute paths on Windows hosts, for example <code>C:\Users\dev\SDKs</code>.</li>
</ul>
<p>
When an absolute request is served, PI WEB expands <code>~</code>, canonicalizes configured roots with
<code>realpath</code>, requires roots to be existing directories, and rejects symlink escapes outside the
allowed roots.
</p>
<div class="callout warning">
This is not a sandbox for the underlying Pi Coding Agent or your OS user. It only controls PI WEB UI/API
file exposure outside a workspace. Add only roots you trust PI WEB to list and read through the browser UI.
</div>
</section>
<section id="session-tools">
<h2>Session daemon tools</h2>
<h3><code>spawnSessions</code></h3>
<p>
Boolean. Controls whether agents receive the <code>spawn_session</code> tool. Defaults to
<code>true</code>. Set it to <code>false</code> if you do not want an agent to start independent PI WEB sessions.
</p>
<p>Environment override: <code>PI_WEB_SPAWN_SESSIONS=0|1|true|false</code>.</p>
<h3><code>subsessions</code></h3>
<p>
Boolean. Beta. Controls whether agents receive the tracked-subsession tools:
<code>spawn_subsession</code>, <code>list_subsessions</code>, <code>check_subsession</code>, and
<code>read_subsession</code>. Defaults to <code>false</code> and also requires <code>spawnSessions</code>
to be enabled.
</p>
<p>
Tracked subsessions let an agent delegate work to child sessions, get notified when children stop
working, and inspect their transcripts. Restart the session daemon after changing this setting.
</p>
<p>Environment override: <code>PI_WEB_SUBSESSIONS=0|1|true|false</code>.</p>
</section>
<section id="completion-tools">
<h2>Optional completion tools</h2>
<p>
File and path <code>@</code> completions work without extra tools. If <code>fzf</code> is available on the
PI WEB server's <code>PATH</code>, PI WEB uses it to improve completion filtering and ranking; otherwise it
falls back to built-in ranking.
</p>
<div class="doc-actions">
<a class="button primary" href="install">Install guide</a>
<a class="button" href="config.md">Markdown reference</a>
</div>
</section>
</div>
</div>
</section>
</main>
<footer class="site-footer">
<div class="container footer-inner">
<span>PI WEB docs</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</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>
+166
View File
@@ -0,0 +1,166 @@
# PI WEB configuration reference
PI WEB configuration covers the machine-local and project-local settings you usually need: the web/API bind address, trusted development-host settings, UI preferences, plugin enablement, file-explorer path access, upload limits, and session-daemon tools.
This file is the markdown reference for agents and package consumers. The website page is <https://pi-web.dev/config>.
## Config files
PI WEB uses two config files:
- **Global PI WEB config:** `$PI_WEB_CONFIG`, or `$XDG_CONFIG_HOME/pi-web/config.json`, or `~/.config/pi-web/config.json`.
- **Project-local PI WEB config:** `<project>/.pi-web/config.json` for commit-able project settings.
Each PI WEB machine has its own config. When using Fleet/machine federation, edit a remote machine's config by opening that machine directly or changing files on that machine.
If you installed services with a custom config path, rerun `pi-web install --config /path/to/config.json` after changing that path or after upgrading from a version that only applied the custom path to the web service. This regenerates service files so the web/API and session daemon use the same `PI_WEB_CONFIG`.
## Precedence and reloads
Runtime values are resolved as:
```text
defaults → config file → environment overrides
```
Environment overrides include `PI_WEB_HOST`, `PI_WEB_PORT` / `PORT`, `PI_WEB_ALLOWED_HOSTS`, `PI_WEB_MAX_UPLOAD_BYTES`, `PI_WEB_SPAWN_SESSIONS`, and `PI_WEB_SUBSESSIONS`.
Process restarts depend on the key:
- `host` / `port`: restart the web/API service or process.
- `maxUploadBytes`: restart both the web/API process and the session daemon.
- `spawnSessions` / `subsessions`: restart the session daemon.
- `pathAccess`: applies on the next request; existing file views may need a browser refresh.
- `plugins`: reload the browser tab after changing plugin enablement.
- `shortcuts`: saved settings apply in the browser after config refresh/save.
## Global config example
```json
{
"host": "127.0.0.1",
"port": 8504,
"pathAccess": {
"allowedPaths": ["~/SDKs", "/opt/reference"]
},
"maxUploadBytes": 67108864,
"spawnSessions": true,
"subsessions": false,
"plugins": {
"workspace-tasks": { "enabled": true },
"updates": { "enabled": true },
"info": { "enabled": false }
},
"shortcuts": {
"core:view.chat": "mod+1",
"core:session.stop": null
}
}
```
## Project-local config
Project-local config lives at `<project>/.pi-web/config.json`. Use it for settings that should follow a repository.
```json
{
"version": 1,
"pathAccess": {
"allowedPaths": ["~/SDKs", "/opt/reference"]
}
}
```
Project-local `pathAccess.allowedPaths` entries are merged after the global list and deduplicated. Paths must still be host-absolute or `~`-prefixed; relative roots are not supported.
Plugins may own separate project files, such as `.pi-web/tasks.json` for the built-in Workspace Tasks plugin.
## Configuration matrix
Rows with JSON key `—` are runtime-only environment variables, not config-file keys.
| Config | JSON key | Env var | Scope | Project-local behavior | Applies / restart |
| --- | --- | --- | --- | --- | --- |
| **Config-file keys** | | | | | |
| Web/API bind host | `host` | `PI_WEB_HOST` | Global | Not supported locally | Restart web/API |
| Web/API port | `port` | `PI_WEB_PORT`, `PORT` | Global | Not supported locally | Restart web/API |
| Dev-server allowed hosts | `allowedHosts` | `PI_WEB_ALLOWED_HOSTS` | Global | Not supported locally | Restart dev web/UI |
| External filesystem roots | `pathAccess.allowedPaths` | — | Global + project | **Merges**: global roots first, then project roots; duplicates removed | Next file request; refresh existing views if needed |
| Upload/body limit | `maxUploadBytes` | `PI_WEB_MAX_UPLOAD_BYTES` | Global | Not supported locally | Restart web/API and session daemon |
| Agent can spawn sessions | `spawnSessions` | `PI_WEB_SPAWN_SESSIONS` | Global/session daemon | Not supported locally | Restart session daemon |
| Tracked subsessions (beta) | `subsessions` | `PI_WEB_SUBSESSIONS` | Global/session daemon | Not supported locally; also requires `spawnSessions` | Restart session daemon |
| Plugin enablement/settings | `plugins.<id>.enabled`, `plugins.<id>.settings` | — | Global | Not core local config; plugins may read their own project files | Reload browser tab |
| Keyboard shortcuts | `shortcuts.<actionId>` | — | Global | Not supported locally | Applies after settings save/config refresh |
| Project config version | `version` | — | Project | Project-local only; must be `1` when present | Next project-config read |
| **Runtime-only environment variables** | | | | | |
| Global config file path | — | `PI_WEB_CONFIG` (`XDG_CONFIG_HOME` affects the default path) | Process/env | Selects the global config file; not a project config | Restart services/processes after changing env |
| Managed data directory | — | `PI_WEB_DATA_DIR` | Process/env | Not supported locally | Restart services before changing; moves managed state location |
| Session daemon socket | — | `PI_WEB_SESSIOND_SOCKET` | Web/API + session daemon env | Not supported locally | Restart daemon and web/API; both must match |
| Session daemon TCP port | — | `PI_WEB_SESSIOND_PORT` | Session daemon env | Not supported locally | Restart session daemon; set `PI_WEB_SESSIOND_URL` for web/API too |
| Session daemon TCP host | — | `PI_WEB_SESSIOND_HOST` | Session daemon env | Not supported locally | Restart session daemon |
| Web-to-daemon URL | — | `PI_WEB_SESSIOND_URL` | Web/API env | Not supported locally | Restart web/API |
| Projects storage file | — | `PI_WEB_PROJECTS_FILE` | Web/API + session daemon env | Not supported locally | Restart services; advanced state override |
| Remote machines storage file | — | `PI_WEB_MACHINES_FILE` | Web/API env | Not supported locally | Restart web/API; advanced state override |
| Pi session storage directory | — | `PI_CODING_AGENT_SESSION_DIR` | Pi/session daemon env | Not supported locally | Restart session daemon; follows Pi session priority |
| Pi agent config directory | — | `PI_CODING_AGENT_DIR` | Pi/Web/API/session daemon env | Not supported locally | Restart services |
| Skip update checks | — | `PI_WEB_SKIP_VERSION_CHECK`, `PI_WEB_OFFLINE`, `PI_SKIP_VERSION_CHECK`, `PI_OFFLINE` | Web/API env | Not supported locally | Restart web/API after env changes |
## Key details
### External path access
`pathAccess.allowedPaths` grants PI WEB's file explorer and absolute `@` path completions access to specific filesystem roots outside the current workspace.
By default, workspace-relative file reads stay inside the workspace and absolute paths are denied. Add only roots you trust PI WEB to list and read through the browser UI.
Accepted root forms:
- Unix absolute paths: `/opt/reference`
- Home-relative paths: `~/SDKs`
- Windows absolute paths on Windows hosts: `C:\Users\dev\SDKs`
When an absolute request is served, PI WEB expands `~`, canonicalizes the configured roots with `realpath`, requires roots to be existing directories, and rejects symlink escapes outside the allowed roots.
This is not a sandbox for the underlying Pi Coding Agent or your OS user. It only controls PI WEB UI/API file exposure outside a workspace.
### Session daemon tools
`spawnSessions` controls whether agents receive the `spawn_session` tool. It defaults to `true`; set it to `false` if you do not want an agent to start independent PI WEB sessions.
`subsessions` is beta and controls whether agents receive the tracked-subsession tools: `spawn_subsession`, `list_subsessions`, `check_subsession`, and `read_subsession`. It defaults to `false` and also requires `spawnSessions` to be enabled.
Tracked subsessions let an agent delegate work to child sessions, get notified when children stop working, and inspect their transcripts.
### Plugin config
Plugins are enabled by default. Set `plugins.<id>.enabled` to `false` to remove a plugin from `/pi-web-plugins/manifest.json` before the browser imports it.
```json
{
"plugins": {
"workspace-tasks": { "enabled": true, "settings": {} },
"updates": { "enabled": false }
}
}
```
Reload the browser tab after changing plugin enablement. Already-loaded plugin JavaScript is not unloaded from the current page.
### Shortcut config
Shortcut values are keyed by action id. Values are shortcut strings such as `mod+k` or `mod+g p`; `null` disables that action's shortcut.
```json
{
"shortcuts": {
"core:view.chat": "mod+1",
"core:session.stop": null
}
}
```
Prefer Settings → Keyboard for editing shortcuts interactively.
## Optional completion tools
File and path `@` completions work without extra tools. If `fzf` is available on the PI WEB server's `PATH`, PI WEB uses it to improve completion filtering/ranking; otherwise it falls back to built-in ranking.
+46 -15
View File
@@ -3,10 +3,29 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PI WEB FAQ</title>
<meta name="description" content="Answers for common PI WEB install and runtime issues." />
<meta property="og:title" content="PI WEB FAQ" />
<meta property="og:image" content="assets/pi-web-banner.png" />
<title>PI WEB FAQ — Pi web UI troubleshooting</title>
<meta
name="description"
content="Troubleshoot PI WEB, the web UI for Pi Coding Agent, including install, PATH, services, remote access, and runtime issues."
/>
<link rel="canonical" href="https://pi-web.dev/faq" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="PI WEB FAQ — Pi web UI troubleshooting" />
<meta
property="og:description"
content="Fix common PI WEB install, service, PATH, remote access, and session issues."
/>
<meta property="og:url" content="https://pi-web.dev/faq" />
<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 FAQ — Pi web UI troubleshooting" />
<meta
name="twitter:description"
content="Fix common PI WEB install, service, PATH, remote access, and session issues."
/>
<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>
(() => {
@@ -28,11 +47,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html" aria-current="page">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins">Plugins</a>
<a href="faq" aria-current="page">FAQ</a>
</div>
<div class="nav-actions">
<a class="github-link" href="https://github.com/jmfederico/pi-web" aria-label="PI WEB on GitHub">
@@ -70,6 +90,7 @@
<aside class="toc" aria-label="FAQ contents">
<strong>Questions</strong>
<a href="#is-this-linux-only">What platforms are supported?</a>
<a href="#is-pi-web-a-web-ui">Is PI WEB a Pi web UI?</a>
<a href="#tools-are-not-found">Tools are failing / node not found</a>
<a href="#doctor-fails">What does doctor check?</a>
<a href="#nvm-fnm-asdf">nvm, fnm, or asdf issues</a>
@@ -97,6 +118,15 @@
</ul>
</article>
<article id="is-pi-web-a-web-ui" class="faq-item">
<h2>Is PI WEB a Pi web UI?</h2>
<p>
Yes. PI WEB is a web UI for Pi Coding Agent that runs and supervises persistent sessions from a browser.
Unlike simple session viewers, PI WEB is built around real server-side workspaces, long-running session
daemons, git worktrees, remote machines, terminals, files, and multi-device supervision.
</p>
</article>
<article id="tools-are-not-found" class="faq-item">
<h2>Tools are failing, node is not found, or Pi cannot find commands</h2>
<p>
@@ -209,7 +239,7 @@
<li>Remote plugins are trusted browser code and only appear while that machine is selected.</li>
<li>If the remote reports offline, check that the gateway server can reach the remote URL and try <strong>Actions → Refresh Selected Machine</strong>.</li>
</ul>
<p><a href="machines.html">Read the fleet guide →</a></p>
<p><a href="machines">Read the fleet guide →</a></p>
</article>
<article id="laptop-or-server" class="faq-item">
@@ -233,7 +263,7 @@
development folder there. Reload the browser tab after edits. If <code>PI_WEB_DATA_DIR</code> is set, use
<code>$PI_WEB_DATA_DIR/plugins</code> instead.
</p>
<p><a href="plugins.html">Read the plugin guide →</a></p>
<p><a href="plugins">Read the plugin guide →</a></p>
</article>
<article id="sessions-stop" class="faq-item">
@@ -273,10 +303,11 @@
<span>PI WEB FAQ</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins">Plugins</a>
<a href="https://github.com/jmfederico/pi-web/issues">Issues</a>
</div>
</div>
+83 -37
View File
@@ -3,17 +3,45 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PI WEB — persistent AI coding agents in your browser</title>
<title>PI WEB — web UI for Pi Coding Agent</title>
<meta
name="description"
content="PI WEB makes AI coding work persistent by default: agents keep running outside your browser while you supervise from any device."
content="PI WEB is a web UI for Pi Coding Agent that keeps agent sessions running in real workspaces on your machine or server."
/>
<meta property="og:title" content="PI WEB" />
<link rel="canonical" href="https://pi-web.dev/" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="PI WEB — web UI for Pi Coding Agent" />
<meta
property="og:description"
content="Run persistent AI coding agents in real workspaces, keep them alive outside your device, and supervise everything from a browser."
content="Run persistent Pi Coding Agent sessions in real workspaces and supervise them from any browser."
/>
<meta property="og:image" content="assets/pi-web-banner.png" />
<meta property="og:url" content="https://pi-web.dev/" />
<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 — web UI for Pi Coding Agent" />
<meta
name="twitter:description"
content="Run persistent Pi Coding Agent sessions in real workspaces and supervise them from any browser."
/>
<meta name="twitter:image" content="https://pi-web.dev/assets/pi-web-banner.png" />
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "PI WEB",
"alternateName": ["Pi web UI", "Pi Coding Agent web UI"],
"applicationCategory": "DeveloperApplication",
"operatingSystem": "Linux, macOS, Windows WSL",
"url": "https://pi-web.dev/",
"downloadUrl": "https://www.npmjs.com/package/@jmfederico/pi-web",
"codeRepository": "https://github.com/jmfederico/pi-web",
"description": "PI WEB is a web UI for Pi Coding Agent that keeps persistent agent sessions running in real workspaces on your machine or server.",
"softwareRequirements": "Node.js 22 or newer and Pi Coding Agent",
"license": "https://github.com/jmfederico/pi-web/blob/main/LICENSE"
}
</script>
<link rel="icon" type="image/svg+xml" href="assets/favicon.svg" />
<script>
(() => {
@@ -35,11 +63,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">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">
@@ -64,20 +93,22 @@
<section class="hero">
<div class="container hero-grid">
<div>
<p class="eyebrow"><span class="pulse"></span> A cockpit for agentic development</p>
<p class="eyebrow"><span class="pulse"></span> Pi Coding Agent web UI</p>
<h1>
<span class="title-context">Your agents keep working.</span>
<span class="gradient-text intro-target" aria-label="You just need a browser.">
<span class="intro-word" style="--i: 0">You</span>
<span class="intro-word" style="--i: 1">just</span>
<span class="intro-word" style="--i: 2">need</span>
<span class="intro-word" style="--i: 3">a</span>
<span class="intro-word" style="--i: 4">browser.</span>
<span class="title-context">The web UI for</span>
<span class="gradient-text intro-target" aria-label="Pi Coding Agent sessions that keep working.">
<span class="intro-word" style="--i: 0">Pi</span>
<span class="intro-word" style="--i: 1">Coding</span>
<span class="intro-word" style="--i: 2">Agent</span>
<span class="intro-word" style="--i: 3">sessions</span>
<span class="intro-word" style="--i: 4">that</span>
<span class="intro-word" style="--i: 5">keep</span>
<span class="intro-word" style="--i: 6">working.</span>
</span>
</h1>
<p class="hero-lede">
PI WEB runs Pi Coding Agent sessions in real server-side workspaces, keeps them alive when your browser
leaves, and gives you a fast web surface to supervise, redirect, and review the work.
PI WEB keeps Pi Coding Agent sessions running in real server-side workspaces, even after your browser
leaves, and gives you a fast web UI to supervise, redirect, and review work from any device.
</p>
<p class="hero-manifesto">
Local development made sense when humans drove every keystroke. Agentic development works better when the
@@ -85,7 +116,7 @@
</p>
<div class="hero-actions">
<a class="button primary" href="#quick-install">Install in minutes</a>
<a class="button" href="install.html">Read the docs</a>
<a class="button" href="install">Read the docs</a>
</div>
<div class="hero-stats" aria-label="Highlights">
<div class="stat"><strong>Persistent</strong><span>sessions survive browser disconnects</span></div>
@@ -118,10 +149,23 @@
<div class="container">
<div class="demo-frame">
<div class="demo-caption">
<strong>Workspaces, sessions, transcripts, terminals — one agent control plane.</strong>
<strong>Workspaces, sessions, transcripts, files — one Pi web UI on every screen.</strong>
<span>Bring your own repositories.</span>
</div>
<img src="assets/pi-web-demo.gif" alt="PI WEB browser UI demo" />
<div class="demo-gallery" aria-label="PI WEB screenshots">
<figure class="demo-shot demo-shot-desktop">
<img src="assets/pi-web-desktop.png" alt="PI WEB desktop screenshot showing an agent-created pi-web.dev screenshot selected in the file preview" />
<figcaption>Desktop: chat beside workspace file preview.</figcaption>
</figure>
<figure class="demo-shot">
<img src="assets/pi-web-tablet.png" alt="PI WEB tablet screenshot" />
<figcaption>Tablet: the same session from a wider touch screen.</figcaption>
</figure>
<figure class="demo-shot demo-shot-mobile">
<img src="assets/pi-web-mobile.png" alt="PI WEB mobile chat screenshot" />
<figcaption>Mobile: the chat stays readable on the go.</figcaption>
</figure>
</div>
</div>
</div>
</section>
@@ -170,10 +214,11 @@
</article>
<article class="card">
<div class="card-icon"></div>
<h3>The browser becomes the control plane</h3>
<h3>Any browser can supervise the work</h3>
<p>
Your device is replaceable. The sessions are not. Move between laptop, phone, tablet, and desktop
without moving the development environment.
without moving the development environment. Under the hood, PI WEB coordinates the running sessions,
files, terminals, and remote machines like a browser-based control plane.
</p>
</article>
<article class="card">
@@ -186,7 +231,7 @@
</article>
</div>
<div class="doc-actions">
<a class="button" href="remote-first.html">Read the remote-first philosophy</a>
<a class="button" href="remote-first">Read the remote-first philosophy</a>
</div>
</div>
</section>
@@ -249,8 +294,8 @@
<li>Open the local URL, or tunnel it from a remote machine.</li>
</ol>
<div class="doc-actions">
<a class="button primary" href="install.html">Complete installation guide</a>
<a class="button" href="faq.html">Troubleshooting FAQ</a>
<a class="button primary" href="install">Complete installation guide</a>
<a class="button" href="faq">Troubleshooting FAQ</a>
</div>
</div>
@@ -276,7 +321,7 @@
Use <code>pi-web install</code> where a supported per-user service manager is available. WSL works with the
installer when systemd is enabled; otherwise use the manual run path.
</p>
<a href="faq.html#is-this-linux-only">Read compatibility notes →</a>
<a href="faq#is-this-linux-only">Read compatibility notes →</a>
</article>
<article class="doc-card">
<h3>Local UI plugins?</h3>
@@ -284,7 +329,7 @@
Ask AI agents to add trusted local UI plugins from <code>~/.pi-web/plugins</code> without rebuilding or
restarting the session daemon.
</p>
<a href="plugins.html">Build a plugin →</a>
<a href="plugins">Build a plugin →</a>
</article>
<article class="doc-card">
<h3>Node or tools not found?</h3>
@@ -292,7 +337,7 @@
Services run login shells. If tools work in your interactive terminal but not in PI WEB, fix PATH in your
login shell startup files and run the doctor command.
</p>
<a href="faq.html#tools-are-not-found">Fix PATH issues →</a>
<a href="faq#tools-are-not-found">Fix PATH issues →</a>
</article>
</div>
</section>
@@ -300,13 +345,14 @@
<footer class="site-footer">
<div class="container footer-inner">
<span>PI WEB · remote control for persistent Pi Coding Agent sessions.</span>
<span>PI WEB · web UI for persistent Pi Coding Agent sessions.</span>
<div class="footer-links">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins">Plugins</a>
<a href="faq">FAQ</a>
<a href="https://www.npmjs.com/package/@jmfederico/pi-web">npm</a>
</div>
</div>
+53 -26
View File
@@ -3,10 +3,29 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Install PI WEB</title>
<meta name="description" content="Complete installation guide for PI WEB on Linux, macOS, and Windows WSL." />
<meta property="og:title" content="Install PI WEB" />
<meta property="og:image" content="assets/pi-web-banner.png" />
<title>Install PI WEB — web UI for Pi Coding Agent</title>
<meta
name="description"
content="Install PI WEB, the web UI for Pi Coding Agent, on Linux, macOS, or Windows WSL with persistent user services."
/>
<link rel="canonical" href="https://pi-web.dev/install" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="Install PI WEB — web UI for Pi Coding Agent" />
<meta
property="og:description"
content="Install PI WEB with npm, Pi, or manual service commands and keep Pi Coding Agent sessions running."
/>
<meta property="og:url" content="https://pi-web.dev/install" />
<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="Install PI WEB — web UI for Pi Coding Agent" />
<meta
name="twitter:description"
content="Install PI WEB with npm, Pi, or manual service commands and keep Pi Coding Agent sessions running."
/>
<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>
(() => {
@@ -28,11 +47,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html" aria-current="page">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install" aria-current="page">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">
@@ -213,7 +233,7 @@
remote runtime.
</p>
<div class="doc-actions">
<a class="button" href="machines.html">Read the fleet guide</a>
<a class="button" href="machines">Read the fleet guide</a>
</div>
</section>
@@ -246,27 +266,33 @@
</p>
<div class="code-card">
<div class="copy-row">
<strong>Default config</strong>
<strong>Common config</strong>
<button class="copy-button" data-copy="#config-example">Copy</button>
</div>
<pre id="config-example"><code>{
"host": "127.0.0.1",
"port": 8504,
"allowedHosts": []
"pathAccess": {
"allowedPaths": ["~/SDKs", "/opt/reference"]
},
"spawnSessions": true,
"subsessions": false
}</code></pre>
</div>
<p>
The web server defaults to <code>127.0.0.1:8504</code> and stores PI WEB state in <code>~/.pi-web</code>.
Use <strong>Settings → General</strong> for host, port, and external filesystem roots; <strong>Settings → Session daemon</strong>
for agent-spawn tools; <strong>Settings → Plugins</strong> for plugin enablement; and <strong>Settings → Keyboard</strong>
for shortcut overrides.
</p>
<div class="callout">
Need the full schema, restart rules, project-local <code>.pi-web/config.json</code>, path access details, and
environment variable reference? Read the <a href="config">configuration reference</a>.
</div>
<p>
The web server defaults to <code>127.0.0.1:8504</code>, and PI WEB-managed state defaults to
<code>~/.pi-web</code>. External filesystem paths are denied by default unless listed in
<code>pathAccess.allowedPaths</code>.
</p>
<ul>
<li><code>PI_WEB_CONFIG</code>: path to a config JSON file. Defaults to <code>~/.config/pi-web/config.json</code>.</li>
<li><code>PI_WEB_PORT</code> or <code>PORT</code>: web server port. Overrides the config file.</li>
<li><code>PI_WEB_HOST</code>: web server bind host. Overrides the config file. Use <code>127.0.0.1</code> for local/tunnel-only access, or a specific VPN/private-network IP for trusted remote access.</li>
<li><code>PI_WEB_DATA_DIR</code>: data directory, default <code>~/.pi-web</code>.</li>
<li><code>PI_WEB_SESSIOND_SOCKET</code>: Unix socket path for daemon communication.</li>
<li><code>PI_CODING_AGENT_SESSION_DIR</code>: Pi session storage directory. PI WEB follows Pi's priority for sessions: this environment variable, then <code>sessionDir</code> in Pi settings for the selected workspace, then Pi's default session directory.</li>
<li><code>PI_CODING_AGENT_DIR</code>: Pi agent config directory for auth, settings, resources, and default session storage.</li>
</ul>
</section>
<section id="uninstall">
@@ -313,10 +339,11 @@
<span>PI WEB docs</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</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>
+34 -16
View File
@@ -3,13 +3,29 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PI WEB fleet</title>
<title>PI WEB fleet — remote Pi web UI machines</title>
<meta
name="description"
content="Connect trusted PI WEB runtimes through machine federation so one browser control plane can supervise local and remote projects, sessions, files, git state, terminals, and plugins."
content="Connect trusted PI WEB runtimes through machine federation so one web UI can supervise local and remote projects, sessions, files, git state, terminals, and plugins."
/>
<meta property="og:title" content="PI WEB fleet" />
<meta property="og:image" content="assets/pi-web-banner.png" />
<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>
(() => {
@@ -31,11 +47,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html" aria-current="page">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<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">
@@ -228,7 +245,7 @@ PI WEB gateway you opened
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.html#remote-machine-plugins">Read the remote machine plugin notes →</a></p>
<p><a href="plugins#remote-machine-plugins">Read the remote machine plugin notes →</a></p>
</section>
<section id="trust-model">
@@ -257,8 +274,8 @@ PI WEB gateway you opened
<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.html#remote-access">Review remote access setup</a>
<a class="button" href="faq.html#remote-machines">Read remote machine FAQ</a>
<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>
@@ -271,10 +288,11 @@ PI WEB gateway you opened
<span>PI WEB fleet</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first.html">Remote-first</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</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>
+37 -16
View File
@@ -3,10 +3,29 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PI WEB plugins</title>
<meta name="description" content="Use built-in PI WEB plugins and develop trusted local UI plugins." />
<meta property="og:title" content="PI WEB plugins" />
<meta property="og:image" content="assets/pi-web-banner.png" />
<title>PI WEB plugins — extend the Pi web UI</title>
<meta
name="description"
content="Use built-in PI WEB plugins and develop trusted local UI plugins for the Pi Coding Agent web UI."
/>
<link rel="canonical" href="https://pi-web.dev/plugins" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="PI WEB plugins — extend the Pi web UI" />
<meta
property="og:description"
content="Customize PI WEB with trusted browser-side plugins for actions, workspace panels, labels, terminals, and files."
/>
<meta property="og:url" content="https://pi-web.dev/plugins" />
<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 plugins — extend the Pi web UI" />
<meta
name="twitter:description"
content="Customize PI WEB with trusted browser-side plugins for actions, workspace panels, labels, terminals, and files."
/>
<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>
(() => {
@@ -28,11 +47,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html" aria-current="page">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="plugins" aria-current="page">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">
@@ -125,7 +145,7 @@
<pre id="plugin-create-prompt"><code>Build a PI WEB plugin for this project.
Goal: &lt;describe the UI behavior&gt;.
Before coding, read the PI WEB plugin docs:
https://pi-web.dev/plugins.html
https://pi-web.dev/plugins
Full API reference:
https://pi-web.dev/plugins.md
Create it as a local plugin under ~/.pi-web/plugins/&lt;plugin-id&gt;.
@@ -140,7 +160,7 @@ Do not modify PI WEB itself.</code></pre>
</div>
<pre id="plugin-improve-prompt"><code>Improve the PI WEB plugin at &lt;path&gt;.
Before coding, read the PI WEB plugin docs:
https://pi-web.dev/plugins.html
https://pi-web.dev/plugins
Full API reference:
https://pi-web.dev/plugins.md
Keep the plugin compatible with the documented v1 API.
@@ -303,7 +323,7 @@ After editing, check the manifest endpoint and browser-console failure cases.</c
<section id="remote-machine-plugins">
<h2>Remote machine plugins</h2>
<p>
With <a href="machines.html">machine federation</a>, PI WEB also loads discovered plugins from the selected
With <a href="machines">machine federation</a>, PI WEB also loads discovered plugins from the selected
remote machine. Remote plugins are trusted browser-side code like local plugins, but their actions,
workspace panels, and workspace labels only appear while that machine is selected.
</p>
@@ -408,10 +428,11 @@ After editing, check the manifest endpoint and browser-console failure cases.</c
<span>PI WEB plugin docs</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="remote-first.html">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="faq.html">FAQ</a>
<a href="remote-first">Remote-first</a>
<a href="machines">Fleet</a>
<a href="install">Install</a>
<a href="config">Config</a>
<a href="faq">FAQ</a>
<a href="https://github.com/jmfederico/pi-web">GitHub</a>
</div>
</div>
+3 -3
View File
@@ -42,7 +42,7 @@ Copy-paste prompt for creating a plugin:
Build a PI WEB plugin for this project.
Goal: <describe the UI behavior>.
Before coding, read the PI WEB plugin docs:
https://pi-web.dev/plugins.html
https://pi-web.dev/plugins
Full API reference:
https://pi-web.dev/plugins.md
Create it as a local plugin under ~/.pi-web/plugins/<plugin-id>.
@@ -56,7 +56,7 @@ Copy-paste prompt for modifying a plugin:
```text
Improve the PI WEB plugin at <path>.
Before coding, read the PI WEB plugin docs:
https://pi-web.dev/plugins.html
https://pi-web.dev/plugins
Full API reference:
https://pi-web.dev/plugins.md
Keep the plugin compatible with the documented v1 API.
@@ -131,7 +131,7 @@ Reload the PI WEB browser tab. PI WEB serves plugin modules with an mtime-based
## Remote machine plugins
When [machine federation](https://pi-web.dev/machines.html) is enabled, PI WEB also loads discovered plugins from the selected remote machine. Remote plugins are trusted browser-side code like local plugins, but their contributions are machine-scoped:
When [machine federation](https://pi-web.dev/machines) is enabled, PI WEB also loads discovered plugins from the selected remote machine. Remote plugins are trusted browser-side code like local plugins, but their contributions are machine-scoped:
- actions, workspace panels, and workspace labels only appear while that machine is selected;
- plugin file and terminal helpers run against that machine;
+37 -18
View File
@@ -3,13 +3,29 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Remote-first development with PI WEB</title>
<title>Remote-first Pi web UI — PI WEB</title>
<meta
name="description"
content="Why PI WEB makes AI coding work persistent by default: agents keep running outside your device while the browser becomes the control plane."
content="Why PI WEB keeps Pi Coding Agent sessions running outside your device while any browser becomes a web UI for supervision and review."
/>
<meta property="og:title" content="Remote-first development with PI WEB" />
<meta property="og:image" content="assets/pi-web-banner.png" />
<link rel="canonical" href="https://pi-web.dev/remote-first" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content="PI WEB" />
<meta property="og:title" content="Remote-first Pi web UI — PI WEB" />
<meta
property="og:description"
content="Run Pi Coding Agent where work can persist, then supervise sessions from any device with PI WEB."
/>
<meta property="og:url" content="https://pi-web.dev/remote-first" />
<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="Remote-first Pi web UI — PI WEB" />
<meta
name="twitter:description"
content="Run Pi Coding Agent where work can persist, then supervise sessions from any device with PI WEB."
/>
<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>
(() => {
@@ -31,11 +47,12 @@
<a class="brand" href="./" aria-label="PI WEB home">PI WEB</a>
<div class="nav-links">
<div class="nav-pages">
<a href="remote-first.html" aria-current="page">Remote-first</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="remote-first" aria-current="page">Remote-first</a>
<a href="machines">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">
@@ -75,7 +92,7 @@
<a href="#why-local-blocks">The old assumption</a>
<a href="#persistence-first">Persistence first-class</a>
<a href="#what-remote-unlocks">What remote unlocks</a>
<a href="#browser-control">Browser as control plane</a>
<a href="#browser-control">Browser as web UI</a>
<a href="#human-role">The human role</a>
<a href="#recommended-shape">Recommended shape</a>
</aside>
@@ -138,11 +155,12 @@
</section>
<section id="browser-control">
<h2>The browser becomes the control plane</h2>
<h2>The browser becomes your Pi web UI</h2>
<p>
Your device should not have to be the editor, terminal, build server, and agent runtime. In PI WEB, the
browser is the cockpit: supervise sessions, redirect agents, inspect transcripts, and review progress
while the development environment stays remote and stable.
while the development environment stays remote and stable. Under the hood, PI WEB still coordinates the
running work like a browser-based control plane.
</p>
<p>
Laptop, phone, tablet, desktop: they are just windows into the same running work. You remain in control,
@@ -173,8 +191,8 @@
keep working even when the laptop is gone.
</div>
<div class="doc-actions">
<a class="button primary" href="install.html">Install PI WEB</a>
<a class="button" href="faq.html#laptop-or-server">Laptop or server FAQ</a>
<a class="button primary" href="install">Install PI WEB</a>
<a class="button" href="faq#laptop-or-server">Laptop or server FAQ</a>
</div>
</section>
</div>
@@ -187,10 +205,11 @@
<span>PI WEB · remote-first control for persistent AI agents.</span>
<div class="footer-links">
<a href="./">Home</a>
<a href="machines.html">Fleet</a>
<a href="install.html">Install</a>
<a href="plugins.html">Plugins</a>
<a href="faq.html">FAQ</a>
<a href="machines">Fleet</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>
+5
View File
@@ -0,0 +1,5 @@
User-agent: *
Content-Signal: search=yes,ai-input=yes,ai-train=yes
Allow: /
Sitemap: https://pi-web.dev/sitemap.xml
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://pi-web.dev/</loc></url>
<url><loc>https://pi-web.dev/remote-first</loc></url>
<url><loc>https://pi-web.dev/machines</loc></url>
<url><loc>https://pi-web.dev/install</loc></url>
<url><loc>https://pi-web.dev/config</loc></url>
<url><loc>https://pi-web.dev/plugins</loc></url>
<url><loc>https://pi-web.dev/faq</loc></url>
</urlset>
+100
View File
@@ -618,6 +618,44 @@ code .comment,
color: var(--muted);
}
.demo-gallery {
display: grid;
grid-template-columns: minmax(0, 1.25fr) minmax(220px, 0.72fr);
gap: 18px;
padding: 18px;
}
.demo-shot {
display: grid;
gap: 10px;
align-content: start;
margin: 0;
}
.demo-shot-desktop {
grid-row: span 2;
}
.demo-shot img {
overflow: hidden;
width: 100%;
border: 1px solid var(--line);
border-radius: 16px;
background: var(--panel-strong);
box-shadow: 0 18px 46px rgba(0, 0, 0, 0.2);
}
.demo-shot-mobile img {
width: min(100%, 250px);
margin-inline: auto;
}
.demo-shot figcaption {
color: var(--muted-2);
font-size: 0.9rem;
line-height: 1.45;
}
.manifesto-section {
padding-top: 46px;
}
@@ -809,6 +847,60 @@ code .comment,
font-size: 1.25rem;
}
.table-scroll {
overflow-x: auto;
margin: 16px 0;
border: 1px solid var(--line);
background: var(--panel);
}
.doc-content table {
width: 100%;
min-width: 860px;
border-collapse: collapse;
}
.doc-content th,
.doc-content td {
padding: 12px 14px;
border-bottom: 1px solid var(--line);
text-align: left;
vertical-align: top;
}
.doc-content th {
background: var(--panel-strong);
color: var(--text);
font-size: 0.78rem;
letter-spacing: 0.05em;
text-transform: uppercase;
}
.doc-content .table-section th {
border-top: 2px solid var(--line-bright);
border-bottom-color: var(--line-bright);
background: var(--panel-strong);
color: var(--text);
letter-spacing: 0.08em;
}
.doc-content td {
color: var(--muted);
}
.doc-content td:first-child {
color: var(--text);
font-weight: 700;
}
.doc-content tr:last-child td {
border-bottom: 0;
}
.doc-content table code {
white-space: nowrap;
}
.code-card {
overflow: hidden;
margin: 16px 0;
@@ -1076,6 +1168,14 @@ html[data-theme="light"] .comment {
.manifesto-lines {
align-content: start;
}
.demo-gallery {
grid-template-columns: 1fr;
}
.demo-shot-desktop {
grid-row: auto;
}
}
@media (max-width: 820px) {