From ee8d9e53594c7fa9c1a4c0609ac9a303ce7e367e Mon Sep 17 00:00:00 2001
From: Federico Jaramillo Martinez
Date: Wed, 22 Jul 2026 20:46:41 +0200
Subject: [PATCH] docs: document immutable provider bootstrap
---
.changeset/global-provider-policy.md | 4 ++-
README.md | 2 +-
docs/config.html | 2 +-
docs/config.md | 2 +-
docs/index.html | 2 +-
docs/install.html | 2 +-
docs/plugins.html | 41 +++++++++++++++++++++++-----
docs/plugins.md | 10 +++++--
8 files changed, 49 insertions(+), 16 deletions(-)
diff --git a/.changeset/global-provider-policy.md b/.changeset/global-provider-policy.md
index ce2b5a5..7343178 100644
--- a/.changeset/global-provider-policy.md
+++ b/.changeset/global-provider-policy.md
@@ -2,4 +2,6 @@
"@jmfederico/pi-web": patch
---
-Support providers from global sources only: Pi built-ins, environment credentials, the agent directory's `models.json`, and providers registered by globally installed (agent-dir) extensions. Provider registrations from project extensions (`pi.registerProvider` in a workspace's extensions) are ignored and reported with a session warning instead of leaking into every concurrent session; all other extension features keep working. To use such a provider, configure it globally in `models.json` or install the extension globally. Requires Pi 0.81 or newer. Session daemon code changed: after updating, restart `pi-web-sessiond.service` manually (`systemctl --user restart pi-web-sessiond`).
+Require Pi Coding Agent `>=0.81.1 <0.82` and build an immutable provider baseline at session-daemon startup. Globally installed extensions can register both config-form and native providers during startup bootstrap; every later extension registration or unregistration—including global replay, project same-ID replacement, lifecycle callbacks, and `/reload`—is ignored. Non-provider extension features still work, and ignored calls are de-duplicated in session-daemon logs by operation/provider ID without logging provider configuration or credentials or creating session warnings/notifications.
+
+After updating PI WEB, or after installing, removing, or updating a globally installed extension that registers providers, manually restart `pi-web-sessiond.service` (`systemctl --user restart pi-web-sessiond`). Restarting only the web/API service and running `/reload` do not rebuild the provider baseline.
diff --git a/README.md b/README.md
index ddfdff1..cbde920 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ Requirements:
- Node.js 22.19.0 or newer
- npm
-- Pi Coding Agent `>=0.80.8 <0.81`, configured for your user
+- Pi Coding Agent `>=0.81.1 <0.82`, configured for your user
- git and the development tools your agents need
Install and start PI WEB as per-user services:
diff --git a/docs/config.html b/docs/config.html
index a837f2a..e12f0d8 100644
--- a/docs/config.html
+++ b/docs/config.html
@@ -175,7 +175,7 @@
pathAccess: applies on the next request; existing file views may need a browser refresh.
uploads.defaultFolder: applies to newly opened Files upload dialogs and new direct drag/drop batches after config/workspace refresh.
plugins: reload the browser tab after changing PI WEB plugin enablement.
- Pi package install/remove/update: not a PI WEB config key; after a mutation, type /reload in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for PI WEB browser plugin changes. A routine session daemon restart is not required.
+ Pi package install/remove/update: not a PI WEB config key; after a mutation, type /reload in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for PI WEB browser plugin changes. A routine session daemon restart is not required for those ordinary resources. If a globally installed extension adds, removes, or changes a provider, manually restart pi-web-sessiond.service; /reload cannot change the startup provider baseline. See Extension provider registrations.
shortcuts: saved settings apply in the browser after config refresh/save.
diff --git a/docs/config.md b/docs/config.md
index 61b70b1..63d2586 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -43,7 +43,7 @@ Process restarts depend on the key:
- `pathAccess`: applies on the next request; existing file views may need a browser refresh.
- `uploads.defaultFolder`: applies to newly opened Files upload dialogs and new direct drag/drop batches after config/workspace refresh.
- `plugins`: reload the browser tab after changing PI WEB plugin enablement.
-- Pi package install/remove/update: not a PI WEB config key; after a mutation, type `/reload` in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for PI WEB browser plugin changes. A routine session daemon restart is not required.
+- Pi package install/remove/update: not a PI WEB config key; after a mutation, type `/reload` in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for PI WEB browser plugin changes. A routine session daemon restart is not required for those ordinary resources. If a globally installed extension adds, removes, or changes a provider, manually restart `pi-web-sessiond.service`; `/reload` cannot change the startup provider baseline. See [Extension provider registrations](https://pi-web.dev/plugins#extension-provider-registrations).
- `shortcuts`: saved settings apply in the browser after config refresh/save.
## Global config example
diff --git a/docs/index.html b/docs/index.html
index b79e41e..5debb5f 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -38,7 +38,7 @@
"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.19.0 or newer and Pi Coding Agent >=0.80.8 <0.81",
+ "softwareRequirements": "Node.js 22.19.0 or newer and Pi Coding Agent >=0.81.1 <0.82",
"license": "https://github.com/jmfederico/pi-web/blob/main/LICENSE"
}
diff --git a/docs/install.html b/docs/install.html
index c4985fc..9373721 100644
--- a/docs/install.html
+++ b/docs/install.html
@@ -107,7 +107,7 @@
Requirements
- Node.js 22.19.0 or newer and npm.
- - Pi Coding Agent
>=0.80.8 <0.81 installed/configured so the pi command works for your user.
+ - Pi Coding Agent
>=0.81.1 <0.82 installed/configured so the pi command works for your user.
- A shell login environment that exposes Node, npm, Pi, git, and any tools your agents need.
- For the automatic installer: a supported per-user service manager.
diff --git a/docs/plugins.html b/docs/plugins.html
index e39d718..a36761a 100644
--- a/docs/plugins.html
+++ b/docs/plugins.html
@@ -160,16 +160,43 @@
updating a Pi package, type /reload in each idle PI WEB session on the target machine to
refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system
prompt files as supported by Pi. Reload the browser page separately for newly discovered or changed
- PI WEB browser plugins. A routine session daemon restart is not required.
+ PI WEB browser plugins. For these ordinary resources, a routine session daemon restart is not required.
+ Extension-provided global provider changes are the exception described below.
+
+ Extension provider registrations
+
+ PI WEB builds one provider baseline for the lifetime of the session daemon. At daemon startup, before any
+ project resources load, it initializes globally installed, agent-dir extensions through Pi's
+ session-services factory. Both config-form registrations
+ (pi.registerProvider("id", config)) and native-provider registrations
+ (pi.registerProvider(provider)) made during that initialization join the shared baseline,
+ alongside Pi built-ins, environment credentials, and providers declared in the agent directory's
+ models.json.
- One exception applies to Pi package extensions: PI WEB providers come from global sources only
- (Pi built-ins, environment credentials, the agent directory's models.json, and providers
- registered by globally installed, agent-dir extensions). If a project extension calls
- pi.registerProvider, PI WEB ignores the registration and warns in the session; everything
- else the extension registers keeps working. Move such a provider to a global source: declare it in
- the agent directory's models.json, or install the extension globally.
+ After startup capture, every extension provider registration, native registration, and unregistration is
+ a no-op, regardless of source or provider ID. This includes global extensions replayed while sessions
+ load, project extensions adding a provider or replacing a global provider with the same ID, late lifecycle
+ calls such as session_start, and /reload. The captured provider remains unchanged,
+ while non-provider extension features continue to load and reload normally.
+
+ Ignored mutations are written to the session-daemon log once per operation and provider ID. These entries
+ contain no provider configuration or credentials, and PI WEB does not show a session warning or
+ notification. The policy prevents accidental provider, configuration, or credential contamination between
+ projects; it is not a security boundary, because extensions remain trusted daemon code.
+
+
+ Configure providers globally before the daemon starts: use the agent directory's
+ models.json, or install the extension globally in the agent directory. Project-level
+ models.json files do not add providers to PI WEB sessions.
+
+
+ Restart required: after updating PI WEB, or after installing, removing, or updating a
+ globally installed extension that registers providers, manually restart
+ pi-web-sessiond.service (systemctl --user restart pi-web-sessiond). Restarting
+ only the web/API service and running /reload do not recapture the baseline.
+
diff --git a/docs/plugins.md b/docs/plugins.md
index 6d17269..11b8e02 100644
--- a/docs/plugins.md
+++ b/docs/plugins.md
@@ -23,13 +23,17 @@ Use **Settings → Pi packages** to view configured Pi packages or install/remov
When machine federation is enabled, **Settings → Pi packages** 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.
-Use **Settings → PI WEB plugins** 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. After installing, removing, or updating a Pi package, type `/reload` in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for newly discovered or changed PI WEB browser plugins. A routine session daemon restart is not required.
+Use **Settings → PI WEB plugins** 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. After installing, removing, or updating a Pi package, type `/reload` in each idle PI WEB session on the target machine to refresh Pi runtime resources such as extensions, skills, prompt templates, themes, and context/system prompt files as supported by Pi. Reload the browser page separately for newly discovered or changed PI WEB browser plugins. For these ordinary resources, a routine session daemon restart is not required. Extension-provided global provider changes are the exception described below.
## Extension provider registrations
-PI WEB providers come from global sources only: Pi built-ins, environment credentials, providers declared in the agent directory's `models.json` (the directory selected by `agent.dir`; see [Configuration](https://pi-web.dev/config)), and providers registered by globally installed (agent-dir) extensions. Global extensions load identically for every session, so their providers are safe on the shared daemon-wide runtime; project extensions differ per workspace and cannot add providers. If a project extension calls `pi.registerProvider(...)`, PI WEB ignores the registration and shows a warning in the session naming the provider. The extension itself still loads and everything else it registers keeps working; only the ignored provider's models never appear, so a project extension that requires its own provider may load but remain unusable.
+PI WEB builds one provider baseline for the lifetime of the session daemon. At daemon startup, before any project resources load, it initializes globally installed (agent-dir) extensions through Pi's session-services factory. Both config-form registrations (`pi.registerProvider("id", config)`) and native-provider registrations (`pi.registerProvider(provider)`) made during that initialization join the shared baseline, alongside Pi built-ins, environment credentials, and providers declared in the agent directory's `models.json` (the directory selected by `agent.dir`; see [Configuration](https://pi-web.dev/config)).
-To use a project extension's provider, move it to a global source: declare it in the agent directory's `models.json`, or install the extension globally in the agent directory. Project-level `models.json` files do not add providers to PI WEB sessions. This policy guards against accidental cross-workspace leakage; it is not a security boundary, since extensions run as trusted code inside the daemon.
+After startup capture, every extension provider registration, native registration, and unregistration is a no-op, regardless of source or provider ID. This includes global extensions replayed while sessions load, project extensions adding a provider or replacing a global provider with the same ID, late lifecycle calls such as `session_start`, and `/reload`. The captured provider remains unchanged, while non-provider extension features continue to load and reload normally.
+
+Ignored mutations are written to the session-daemon log once per operation and provider ID. These entries contain no provider configuration or credentials, and PI WEB does not show a session warning or notification. The policy prevents accidental provider, configuration, or credential contamination between projects; it is not a security boundary, because extensions remain trusted daemon code.
+
+Configure providers globally before the daemon starts: use the agent directory's `models.json`, or install the extension globally in the agent directory. Project-level `models.json` files do not add providers to PI WEB sessions. **Restart required:** after updating PI WEB, or after installing, removing, or updating a globally installed extension that registers providers, manually restart `pi-web-sessiond.service` (`systemctl --user restart pi-web-sessiond`). Restarting only the web/API service and running `/reload` do not recapture the baseline.
## Trust model