Archived
Add the close-out documentation for extension dialog support: - docs/config.md (+ synchronized config.html): extensionDialogsTimeoutMs in the config matrix, reload/restart guidance, the global config example, and a new Extension dialogs key-detail section covering the unattended-dialog safety valve (default 5 min, 0 = forever, effective deadline is the sooner of the extension's own timeout and this knob). - docs/plugins.md (+ synchronized plugins.html): new Pi extension dialogs in PI WEB behavior note for extension authors — confirm/select/ input render inline in the transcript and resolve with the real answer, answers use a dedicated daemon channel (never the prompt queue, so tool_call hooks park safely), session_start dialogs are reachable during create and open, reload rehydration, first-answer-wins across tabs, abort/runtime-replacement settlement, and the reload-mid-startup browser-local caveat. - Add the extension-dialogs changeset (patch) for the release notes.
544 lines
30 KiB
HTML
544 lines
30 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 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>
|
|
(() => {
|
|
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">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">
|
|
<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> Plugin development</p>
|
|
<h1>Customize PI WEB with UI plugins.</h1>
|
|
<p>
|
|
Plugins are trusted browser-side ES modules. They can add actions, workspace panels, and compact workspace
|
|
labels to the PI WEB UI.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section compact">
|
|
<div class="container doc-layout">
|
|
<aside class="toc" aria-label="Plugin page contents">
|
|
<strong>On this page</strong>
|
|
<a href="#extend">What can be extended</a>
|
|
<a href="#packages-vs-plugins">Pi packages, extensions, and plugins</a>
|
|
<a href="#pi-extension-dialogs">Pi extension dialogs</a>
|
|
<a href="#ask-ai">What to ask AI to build</a>
|
|
<a href="#example">Canonical example</a>
|
|
<a href="#built-in-plugins">Built-in plugins</a>
|
|
<a href="#manage-plugins">Manage PI WEB plugins</a>
|
|
<a href="#remote-machine-plugins">Remote machine plugins</a>
|
|
<a href="#production">Production usage</a>
|
|
<a href="#agent-docs">AI-friendly docs</a>
|
|
<a href="#develop">Develop and debug</a>
|
|
<a href="#trust">Trust model</a>
|
|
</aside>
|
|
|
|
<div class="doc-content">
|
|
<section id="extend">
|
|
<h2>What can be extended</h2>
|
|
<p>Plugins can add small, focused UI extensions to PI WEB:</p>
|
|
<ul>
|
|
<li><strong>Action palette commands</strong> for custom workflows.</li>
|
|
<li><strong>Workspace tools and panels</strong> next to Files, Git, and Terminal.</li>
|
|
<li><strong>Workspace labels</strong> in the workspace list, header, and status bar.</li>
|
|
<li><strong>Static assets</strong> served from the plugin folder.</li>
|
|
<li><strong>Browser-side integrations</strong> using documented PI WEB plugin context helpers.</li>
|
|
</ul>
|
|
<p>
|
|
Plugins cannot extend the session daemon or add server-side hooks. They run in the browser UI only.
|
|
Use documented context helpers for the stable API surface. Daring plugins can reach into PI WEB
|
|
internals, but those private surfaces are experimental: they may graduate into stable helpers, change
|
|
shape, or disappear.
|
|
</p>
|
|
<div class="callout">
|
|
The plugin API is intentionally limited and actively developed. Feedback is appreciated: if an extension
|
|
point is missing, unclear, or awkward, please
|
|
<a href="https://github.com/jmfederico/pi-web/issues">open a GitHub issue</a>.
|
|
</div>
|
|
</section>
|
|
|
|
<section id="packages-vs-plugins">
|
|
<h2>Pi packages, Pi extensions, and PI WEB plugins</h2>
|
|
<p>
|
|
<strong>Pi packages</strong> are distribution bundles managed by Pi (<code>pi install</code>,
|
|
<code>pi remove</code>, <code>pi update</code>). A Pi package can provide Pi extensions, skills, prompt
|
|
templates, themes, context/system prompt files, and/or PI WEB browser plugins. Many Pi packages do not
|
|
include a PI WEB plugin.
|
|
</p>
|
|
<p>
|
|
<strong>Pi extensions</strong> are runtime modules loaded by the session daemon. They can register Pi
|
|
tools, hooks, commands, and model providers. They are not PI WEB plugins.
|
|
</p>
|
|
<p>
|
|
<strong>PI WEB plugins</strong> are browser-side UI modules discovered from bundled, local, dev, and
|
|
installed Pi-package sources. They cannot register model providers or server-side hooks. Enabling or
|
|
disabling a PI WEB plugin is a PI WEB config task; installing, removing, or updating a Pi package is a
|
|
separate Pi package-manager task.
|
|
</p>
|
|
<p>
|
|
Use <strong>Settings → Pi packages</strong> to view configured Pi packages or install/remove/update a
|
|
package. Enter only the package source, such as <code>npm:@scope/package</code>, a git/URL source, or a
|
|
local path. PI WEB uses Pi's default package location, equivalent to <code>pi install <source></code>,
|
|
and does not ask for an install location.
|
|
</p>
|
|
<p>
|
|
When machine federation is enabled, <strong>Settings → Pi packages</strong> targets the currently selected
|
|
machine. The panel labels whether changes will run on the local/gateway machine or on a selected remote
|
|
PI WEB machine. If an older or unavailable remote PI WEB server does not expose package-management routes,
|
|
PI WEB reports the package management operation as unsupported or unavailable instead of silently falling
|
|
back to the gateway.
|
|
</p>
|
|
<p>
|
|
Use <strong>Settings → PI WEB plugins</strong> to enable or disable discovered PI WEB browser plugins
|
|
before the browser imports them. In a federated setup, this plugin enablement surface targets the
|
|
currently selected machine and labels where changes are saved. If an older or unavailable remote PI WEB
|
|
server does not advertise selected-machine settings support, PI WEB reports the plugin settings as
|
|
unsupported or unavailable instead of silently falling back to the gateway.
|
|
</p>
|
|
<p>
|
|
After installing, removing, or updating a Pi package, type <code>/reload</code> in each idle PI WEB
|
|
session on the target machine to refresh ordinary Pi resources such as extensions, skills, prompt
|
|
templates, themes, and context/system prompt files. Reload the browser page separately for newly
|
|
discovered or changed PI WEB browser plugins. A provider-registering Pi extension follows a separate
|
|
daemon-start policy; see
|
|
<a href="config#pi-extension-provider-baseline">Pi extension provider baseline</a>.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="pi-extension-dialogs">
|
|
<h2>Pi extension dialogs in PI WEB</h2>
|
|
<p>
|
|
Pi extensions running under PI WEB's session daemon can ask the user questions with
|
|
<code>ctx.ui.confirm()</code>, <code>ctx.ui.select()</code>, and <code>ctx.ui.input()</code>. For these
|
|
three methods <code>ctx.hasUI</code> is true in fact: the call renders a dialog card inline in the
|
|
session transcript — including from <code>session_start</code> hooks while the session is still starting
|
|
and from in-flight <code>tool_call</code> hooks — and resolves with the user's actual answer.
|
|
</p>
|
|
<p>
|
|
Answers travel over a dedicated session-daemon channel, never the prompt queue, so a parked
|
|
<code>tool_call</code> hook cannot deadlock the run. Open dialogs survive browser reloads, the first
|
|
answer wins across tabs, and unanswered dialogs settle safely: aborting the run or replacing the runtime
|
|
resolves them immediately with the kind's cancel value (<code>false</code> for confirm,
|
|
<code>undefined</code> for select and input), and the effective deadline — the sooner of the extension's
|
|
own <code>timeout</code> and the daemon's <code>extensionDialogsTimeoutMs</code> safety valve (default 5
|
|
minutes, <code>0</code> waits forever) — does the same when no one answers. Other
|
|
<code>ExtensionUIContext</code> surfaces (widgets, status, editor, <code>custom</code>) remain no-ops
|
|
despite <code>hasUI === true</code>.
|
|
</p>
|
|
<p>
|
|
For the full behavior notes and author guidance, read <a href="plugins.md">plugins.md</a>; for the
|
|
timeout key, see <a href="config#extension-dialogs">Extension dialogs</a> in the configuration reference.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="ask-ai">
|
|
<h2>What to ask AI to build</h2>
|
|
<p>
|
|
You do not need to hand-code plugins. Give an AI agent a clear goal, the workspace/project facts it
|
|
should use, and the PI WEB plugin rules.
|
|
</p>
|
|
<ul>
|
|
<li>Show a workspace badge from a repo file, environment file, branch name, container, or dev URL.</li>
|
|
<li>Add a workspace panel that summarizes project-specific health, commands, links, or runbooks.</li>
|
|
<li>Add action-palette commands for common project workflows or prompts.</li>
|
|
<li>Add links to local services, preview deployments, dashboards, CI, logs, or docs.</li>
|
|
</ul>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Prompt: create a plugin</strong>
|
|
<button class="copy-button" data-copy="#plugin-create-prompt">Copy</button>
|
|
</div>
|
|
<pre id="plugin-create-prompt"><code>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
|
|
Full API reference:
|
|
https://pi-web.dev/plugins.md
|
|
Create it as a local plugin under ~/.pi-web/plugins/<plugin-id>.
|
|
Use the appropriate extension points from the docs.
|
|
Validate by checking /pi-web-plugins/manifest.json and explain how to reload/debug it.
|
|
Do not modify PI WEB itself.</code></pre>
|
|
</div>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Prompt: improve a plugin</strong>
|
|
<button class="copy-button" data-copy="#plugin-improve-prompt">Copy</button>
|
|
</div>
|
|
<pre id="plugin-improve-prompt"><code>Improve the PI WEB plugin at <path>.
|
|
Before coding, read the PI WEB plugin docs:
|
|
https://pi-web.dev/plugins
|
|
Full API reference:
|
|
https://pi-web.dev/plugins.md
|
|
Keep the plugin compatible with the documented v1 API.
|
|
After editing, check the manifest endpoint and browser-console failure cases.</code></pre>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="example">
|
|
<h2>Canonical example</h2>
|
|
<p>
|
|
PI WEB ships a real bundled <strong>Info</strong> plugin. It is intentionally small while still using all
|
|
core contribution types: one action, one workspace label, and one workspace panel.
|
|
</p>
|
|
<p>
|
|
Bundled PI WEB plugins are developed as TypeScript in the repository, while their package metadata
|
|
points at the built JavaScript ES modules that the browser loads. <code>npm run dev:web</code> watches and
|
|
rebuilds bundled plugin TS into <code>dist/pi-web-plugins/</code> during development, and <code>npm run build</code>
|
|
emits JS before release packaging.
|
|
</p>
|
|
<ul>
|
|
<li><code>pi-web-plugins/info/package.json</code> shows the required metadata shape.</li>
|
|
<li><code>pi-web-plugins/info/pi-web-plugin.ts</code> is the skeleton: metadata and contribution definitions.</li>
|
|
<li><code>pi-web-plugins/info/infoInternals.ts</code> holds the bundled panel and action implementation, which you can ignore or replace when copying the plugin.</li>
|
|
<li><code>dist/pi-web-plugins/info/pi-web-plugin.js</code> is the built browser module in a checkout.</li>
|
|
</ul>
|
|
<p>
|
|
Read it on GitHub:
|
|
<a href="https://github.com/jmfederico/pi-web/tree/main/pi-web-plugins/info">pi-web-plugins/info</a>.
|
|
If you copy it, choose a new plugin id so it does not conflict with the bundled <code>info</code> plugin.
|
|
Its panel also doubles as an always-available PI WEB status view: it renders the host-provided
|
|
<code>context.state.piWebStatus</code> without issuing its own requests, and its action copies a
|
|
plain-text diagnostics summary suitable for bug reports.
|
|
</p>
|
|
<p>
|
|
The bundled <code>updates</code> plugin demonstrates dynamic <code>visible</code> and <code>badge</code>
|
|
callbacks for tabs that only appear when the host has status messages or needs extra install visibility.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="built-in-plugins">
|
|
<h2>Built-in plugins</h2>
|
|
<p>
|
|
PI WEB ships core, discoverable plugins in the main <code>@jmfederico/pi-web</code> npm package. No
|
|
separate <code>pi install</code> step is required: update PI WEB, reload the browser tab, and the bundled
|
|
plugins appear in <code>/pi-web-plugins/manifest.json</code>.
|
|
</p>
|
|
<p>
|
|
Built-in plugins can be managed from <strong>Settings → PI WEB plugins</strong> or with the top-level
|
|
<code>plugins</code> config key.
|
|
</p>
|
|
|
|
<h3>Updates</h3>
|
|
<p>
|
|
<strong>Updates</strong> adds a conditional <strong>Updates</strong> workspace tab with PI WEB update,
|
|
restart, and installed-service guidance, plus a <strong>Check for PI WEB Updates</strong> action. It is
|
|
built into PI WEB, enabled by default, and uses the selected machine's plugin copy when machine
|
|
federation is active.
|
|
</p>
|
|
<ul>
|
|
<li>Plugin id: <code>updates</code></li>
|
|
<li>Selected-machine status refreshes every 15 minutes while a browser tab is connected.</li>
|
|
<li>Automatic npm release lookups are cached for six hours; the action bypasses the caches and checks immediately.</li>
|
|
</ul>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Disable Updates</strong>
|
|
<button class="copy-button" data-copy="#updates-disable">Copy</button>
|
|
</div>
|
|
<pre id="updates-disable"><code>{
|
|
"plugins": {
|
|
"updates": { "enabled": false }
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
|
|
<h3>Workspace Tasks</h3>
|
|
<p>
|
|
<strong>Workspace Tasks</strong> adds a <strong>Tasks</strong> workspace tab for running configured shell
|
|
commands in dedicated PI WEB terminals. It is built into PI WEB and enabled by default.
|
|
</p>
|
|
<ul>
|
|
<li>Plugin id: <code>workspace-tasks</code></li>
|
|
<li>Config file: <code>.pi-web/tasks.json</code></li>
|
|
</ul>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Disable Workspace Tasks</strong>
|
|
<button class="copy-button" data-copy="#workspace-tasks-disable">Copy</button>
|
|
</div>
|
|
<pre id="workspace-tasks-disable"><code>{
|
|
"plugins": {
|
|
"workspace-tasks": { "enabled": false }
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Example .pi-web/tasks.json</strong>
|
|
<button class="copy-button" data-copy="#workspace-tasks-config">Copy</button>
|
|
</div>
|
|
<pre id="workspace-tasks-config"><code>{
|
|
"version": 1,
|
|
"tasks": [
|
|
{
|
|
"id": "app.start",
|
|
"title": "Start app",
|
|
"group": "Development",
|
|
"description": "Start the local development server.",
|
|
"command": "npm run dev"
|
|
},
|
|
{
|
|
"id": "db.reset",
|
|
"title": "Reset DB",
|
|
"group": "Database",
|
|
"command": "go -C klingit-go run ./cli db reset",
|
|
"confirm": true
|
|
}
|
|
]
|
|
}</code></pre>
|
|
</div>
|
|
<p>
|
|
Open a workspace, choose the <strong>Tasks</strong> tab, and click <strong>Run</strong> next to a task.
|
|
Commands run in the workspace root because PI WEB creates the terminal for that workspace.
|
|
</p>
|
|
<p>
|
|
Review task configs before running them, especially in shared projects. Workspace Tasks runs trusted
|
|
shell commands from your repositories.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="manage-plugins">
|
|
<h2>Manage PI WEB plugins</h2>
|
|
<p>
|
|
Open <strong>Settings → PI WEB plugins</strong> to review discovered bundled, local, dev, and
|
|
Pi-package-supplied PI WEB plugins for the selected PI WEB machine. When the local machine is selected,
|
|
this is the gateway plugin list; when a remote machine is selected, the list comes from that remote PI WEB
|
|
server and includes
|
|
disabled discovered plugins it exposes. PI WEB can disable any discovered selected-machine plugin before
|
|
the browser imports it. Core app contributions such as the command palette, base workspace tools, and
|
|
themes are not managed through this plugin list.
|
|
</p>
|
|
<p>
|
|
This surface is only for PI WEB plugin enablement. To install, remove, or update Pi packages that may
|
|
provide PI WEB plugins or other Pi resources, use <strong>Settings → Pi packages</strong>. In a federated
|
|
setup, both the Pi packages panel and the PI WEB plugins panel target the selected machine; plugin enablement
|
|
still writes the PI WEB <code>plugins</code> config key rather than changing Pi package-manager settings.
|
|
</p>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Plugin config shape</strong>
|
|
<button class="copy-button" data-copy="#plugin-config-shape">Copy</button>
|
|
</div>
|
|
<pre id="plugin-config-shape"><code>{
|
|
"plugins": {
|
|
"workspace-tasks": {
|
|
"enabled": true,
|
|
"settings": {}
|
|
},
|
|
"info": {
|
|
"enabled": false
|
|
}
|
|
}
|
|
}</code></pre>
|
|
</div>
|
|
<p>
|
|
Plugins are enabled by default. Set <code>enabled</code> to <code>false</code> to remove a plugin from
|
|
<code>/pi-web-plugins/manifest.json</code> so it is not imported or activated on the next page load.
|
|
The optional <code>settings</code> object is reserved for plugin-specific settings.
|
|
</p>
|
|
<p>
|
|
After changing plugin enablement, reload the PI WEB browser tab. Already-loaded plugin JavaScript is not
|
|
unloaded from the current page.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="remote-machine-plugins">
|
|
<h2>Remote machine plugins</h2>
|
|
<p>
|
|
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>
|
|
<ul>
|
|
<li>File and terminal helpers run against the selected remote machine.</li>
|
|
<li>Remote plugin code is loaded best-effort through the current gateway and cached for the page lifetime.</li>
|
|
<li>If the gateway and remote machine both have an enabled plugin with the same original id, <code>machineSpecific</code> metadata decides whether the gateway copy is reused or only the selected-machine copy can appear.</li>
|
|
<li>Remote theme contributions are ignored for now because themes are app-wide.</li>
|
|
<li>Mixed PI WEB versions across federated machines are best-effort and not guaranteed compatible.</li>
|
|
</ul>
|
|
<p>
|
|
Remote plugin enablement is controlled by the remote machine's PI WEB plugin config. To edit or disable
|
|
one, select that machine and use <strong>Settings → PI WEB plugins</strong> when the remote server exposes
|
|
selected-machine settings, or open that machine directly/update its config file.
|
|
</p>
|
|
<p>
|
|
Plugin package metadata can set <code>machineSpecific: true</code>. Use it for plugins like Updates whose
|
|
UI should come from the selected PI WEB instance; on remote machines, the gateway copy is hidden unless
|
|
the remote machine exposes its own copy.
|
|
</p>
|
|
<p>
|
|
Current PI WEB manifests publish leading application-root module references. The browser keeps them
|
|
inside the current application base, so local and federated plugins follow root or nested reverse-proxy
|
|
deployments without a prefix-specific build while remaining compatible with existing gateways.
|
|
Federated gateways also accept manifest-relative references such as
|
|
<code>./<plugin-id>/plugin.js</code> and legacy plugin-root-relative references such as
|
|
<code>nested/plugin.js</code> from remote machines.
|
|
</p>
|
|
<p>
|
|
For portable plugin assets, prefer URLs relative to the plugin module, such as
|
|
<code>new URL("./asset.json", import.meta.url)</code>. If a remote plugin constructs absolute asset URLs,
|
|
it should use the <code>pluginId</code> from <code>activate()</code>; hard-coded
|
|
<code>/pi-web-plugins/<original-id>/...</code> URLs may point at the gateway instead of the remote machine.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="production">
|
|
<h2>Production usage</h2>
|
|
<p>
|
|
Local plugins work with the production native-service install. Put each plugin under
|
|
<code>~/.pi-web/plugins/<plugin-id>/</code>, or symlink it there while developing. No PI WEB rebuild or
|
|
session-daemon restart is required.
|
|
</p>
|
|
<div class="callout warning">
|
|
If <code>PI_WEB_DATA_DIR</code> is set, use <code>$PI_WEB_DATA_DIR/plugins</code> instead of
|
|
<code>~/.pi-web/plugins</code>.
|
|
</div>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Install a local plugin folder</strong>
|
|
<button class="copy-button" data-copy="#plugin-symlink">Copy</button>
|
|
</div>
|
|
<pre id="plugin-symlink"><code><span class="prompt">$</span> mkdir -p ~/.pi-web/plugins
|
|
<span class="prompt">$</span> ln -s /path/to/plugin-folder ~/.pi-web/plugins/plugin-id</code></pre>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="agent-docs">
|
|
<h2>AI-friendly docs</h2>
|
|
<p>
|
|
The full plugin reference is available as Markdown for AI agents to read, fetch, and follow:
|
|
<a href="plugins.md">plugins.md</a>.
|
|
</p>
|
|
<p>
|
|
If you want to understand the API yourself, ask an agent to read that file and explain the relevant
|
|
public extension points for the plugin you want. Private PI WEB internals exist for the daring; treat
|
|
them as experimental surfaces that may graduate into stable helpers, change shape, or disappear.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="develop">
|
|
<h2>Develop and debug</h2>
|
|
<ul>
|
|
<li>Keep the source folder outside <code>~/.pi-web/plugins</code> and symlink it in.</li>
|
|
<li>After edits, reload or hard-reload the browser tab.</li>
|
|
<li>Check discovery with the manifest endpoint.</li>
|
|
<li>Check the browser console if a plugin fails to import or activate.</li>
|
|
</ul>
|
|
<div class="code-card">
|
|
<div class="copy-row">
|
|
<strong>Check discovered plugins</strong>
|
|
<button class="copy-button" data-copy="#plugin-manifest">Copy</button>
|
|
</div>
|
|
<pre id="plugin-manifest"><code><span class="prompt">$</span> curl http://127.0.0.1:8504/pi-web-plugins/manifest.json</code></pre>
|
|
</div>
|
|
<p>
|
|
For all contribution types and package metadata, read the
|
|
<a href="plugins.md">Plugin API reference</a>.
|
|
</p>
|
|
</section>
|
|
|
|
<section id="trust">
|
|
<h2>Trust model</h2>
|
|
<p>
|
|
Plugins are not sandboxed. They run as JavaScript in the browser, can use browser APIs, call documented
|
|
PI WEB helpers, and render arbitrary UI. If a plugin reaches beyond those helpers into private PI WEB
|
|
internals, treat that dependency as experimental: it may become stable, change shape, or disappear.
|
|
Install only plugins you trust.
|
|
</p>
|
|
<p>
|
|
Plugins do not run inside the session daemon and do not provide server-side hooks.
|
|
</p>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<footer class="site-footer">
|
|
<div class="container footer-inner">
|
|
<span>PI WEB plugin 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="faq">FAQ</a>
|
|
<a href="https://github.com/jmfederico/pi-web">GitHub</a>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
<script src="site.js"></script>
|
|
</body>
|
|
</html>
|