diff --git a/.changeset/document-config-reference.md b/.changeset/document-config-reference.md new file mode 100644 index 0000000..93e519f --- /dev/null +++ b/.changeset/document-config-reference.md @@ -0,0 +1,5 @@ +--- +"@jmfederico/pi-web": patch +--- + +Add a dedicated PI WEB configuration reference covering config-file precedence, project-local config, external path access allowlists, session daemon tools, plugins, shortcuts, upload limits, and environment variables. Custom `pi-web install --config` paths are now passed to the session daemon service as well as the web service, and the session daemon now honors config-file `maxUploadBytes` values. diff --git a/README.md b/README.md index a27f1a9..801f4b5 100644 --- a/README.md +++ b/README.md @@ -259,10 +259,16 @@ npm publish --access public PI WEB uses a single-line CalVer-inspired npm version: `MAJOR.YYYYMM.SEQUENCE`, for example `1.202605.1`. The major number signals breaking-change eras; the middle number is the release month; the final number increments for additional releases in that month. Older major eras may be deprecated rather than maintained in parallel. -PI WEB declares `@earendil-works/pi-coding-agent` as a peer dependency (`>=0.74.0 <1`) and a development dependency for local builds. This keeps published installs flexible: npm 7+ installs the peer automatically, and users can upgrade the Pi package within the compatible range without PI WEB pinning a separate copy. +PI WEB declares `@earendil-works/pi-coding-agent` as a peer dependency (`>=0.78.0 <1`) and a development dependency for local builds. This keeps published installs flexible: npm 7+ installs the peer automatically, and users can upgrade the Pi package within the compatible range without PI WEB pinning a separate copy. -The web server defaults to `127.0.0.1:8504`. Set `PI_WEB_HOST=0.0.0.0` only when you intentionally want to bind directly on all interfaces. +## Configuration + +Global PI WEB config lives at `$PI_WEB_CONFIG`, or `$XDG_CONFIG_HOME/pi-web/config.json`, or `~/.config/pi-web/config.json`. Project-local core config lives at `/.pi-web/config.json`. + +See the full [Configuration reference](docs/config.md) for config-file precedence, project-local config, external path access, session daemon settings, plugins, shortcuts, upload limits, and environment variables. + +The web server defaults to `127.0.0.1:8504`. Set `PI_WEB_HOST=0.0.0.0` only when you intentionally want to bind directly on all interfaces behind a trusted network, firewall, or authenticated proxy. The session daemon defaults to a private Unix socket at: @@ -270,18 +276,26 @@ The session daemon defaults to a private Unix socket at: ~/.pi-web/sessiond.sock ``` -Environment variables: +Common config keys: -- `PI_WEB_PORT` / `PORT` — web server port. Defaults to `8504`. -- `PI_WEB_HOST` — web server bind host. Defaults to `127.0.0.1`. -- `PI_WEB_DATA_DIR` — PI WEB data directory. Defaults to `~/.pi-web`. +- `host` / `port` — web/API bind address. Environment overrides: `PI_WEB_HOST`, `PI_WEB_PORT` / `PORT`. +- `pathAccess.allowedPaths` — external filesystem roots that PI WEB may list/read through the file explorer and absolute `@` path completions. Absolute paths are denied by default. +- `maxUploadBytes` — maximum accepted request body size. Defaults to 64 MB. Environment override: `PI_WEB_MAX_UPLOAD_BYTES`. +- `spawnSessions` — enable the `spawn_session` tool. Defaults to `true`. Environment override: `PI_WEB_SPAWN_SESSIONS`. +- `subsessions` — beta tracked-subsession tools (`spawn_subsession`, `list_subsessions`, `check_subsession`, `read_subsession`). Defaults to `false`, requires `spawnSessions`, and requires a session daemon restart after changes. Environment override: `PI_WEB_SUBSESSIONS`. +- `plugins` — plugin enablement/settings. Reload the browser after changing plugin enablement. +- `shortcuts` — keyboard shortcut overrides; use `null` to disable an action shortcut. + +Operational environment variables: + +- `PI_WEB_CONFIG` — path to the global config JSON file. +- `PI_WEB_DATA_DIR` — PI WEB-managed data directory. Defaults to `~/.pi-web`. - `PI_WEB_SESSIOND_SOCKET` — Unix socket path used by both the daemon and web process when `PI_WEB_SESSIOND_URL` is not set. Defaults to `$PI_WEB_DATA_DIR/sessiond.sock`. - `PI_WEB_SESSIOND_PORT` — optional TCP port for the daemon. If unset, the daemon listens on the Unix socket instead. - `PI_WEB_SESSIOND_HOST` — daemon TCP bind host when `PI_WEB_SESSIOND_PORT` is set. Defaults to `127.0.0.1`. - `PI_WEB_SESSIOND_URL` — daemon URL used by the web process when connecting over TCP, for example `http://127.0.0.1:3001`. If you set `PI_WEB_SESSIOND_PORT`, set this for the web process too. - `PI_WEB_PROJECTS_FILE` — optional override for the projects storage JSON file. Defaults to `$PI_WEB_DATA_DIR/projects.json`. - `PI_WEB_MACHINES_FILE` — optional override for the remote machine registry JSON file. Defaults to `$PI_WEB_DATA_DIR/machines.json`. -- `PI_WEB_MAX_UPLOAD_BYTES` — maximum accepted HTTP request body size in bytes (covers pasted/attached images). Defaults to 64 MB. Also configurable as `maxUploadBytes` in `config.json`. - `PI_CODING_AGENT_SESSION_DIR` — Pi session storage directory. PI WEB follows the same session-location priority as Pi for web sessions: this environment variable, then `sessionDir` in Pi settings for the selected workspace, then Pi's default session directory. - `PI_CODING_AGENT_DIR` — Pi agent config directory. PI WEB uses this for Pi auth, settings, resources, and default session storage, matching Pi's own configuration layout. diff --git a/docs/404.html b/docs/404.html index 2f313ac..b80d812 100644 --- a/docs/404.html +++ b/docs/404.html @@ -40,6 +40,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -90,6 +91,7 @@ @@ -305,6 +306,7 @@ Remote-first Fleet Install + Config Plugins Issues diff --git a/docs/index.html b/docs/index.html index 2fb873b..bfa5fce 100644 --- a/docs/index.html +++ b/docs/index.html @@ -66,6 +66,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -349,6 +350,7 @@ Remote-first Fleet Install + Config Plugins FAQ npm diff --git a/docs/install.html b/docs/install.html index cfddc18..a304eb0 100644 --- a/docs/install.html +++ b/docs/install.html @@ -50,6 +50,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -265,27 +266,33 @@

- Default config + Common config
{
   "host": "127.0.0.1",
   "port": 8504,
-  "allowedHosts": []
+  "pathAccess": {
+    "allowedPaths": ["~/SDKs", "/opt/reference"]
+  },
+  "spawnSessions": true,
+  "subsessions": false
 }

- The web server defaults to 127.0.0.1:8504 and stores PI WEB state in ~/.pi-web. + Use Settings → General for host, port, and external filesystem roots; Settings → Session daemon + for agent-spawn tools; Settings → Plugins for plugin enablement; and Settings → Keyboard + for shortcut overrides. +

+
+ Need the full schema, restart rules, project-local .pi-web/config.json, path access details, and + environment variable reference? Read the configuration reference. +
+

+ The web server defaults to 127.0.0.1:8504, and PI WEB-managed state defaults to + ~/.pi-web. External filesystem paths are denied by default unless listed in + pathAccess.allowedPaths.

-
@@ -334,6 +341,7 @@ Home Remote-first Fleet + Config Plugins FAQ GitHub diff --git a/docs/machines.html b/docs/machines.html index 4d7005e..665f222 100644 --- a/docs/machines.html +++ b/docs/machines.html @@ -50,6 +50,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -289,6 +290,7 @@ PI WEB gateway you opened Home Remote-first Install + Config Plugins FAQ GitHub diff --git a/docs/plugins.html b/docs/plugins.html index 53a2936..8068d5b 100644 --- a/docs/plugins.html +++ b/docs/plugins.html @@ -50,6 +50,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -430,6 +431,7 @@ After editing, check the manifest endpoint and browser-console failure cases.Remote-first Fleet Install + Config FAQ GitHub diff --git a/docs/remote-first.html b/docs/remote-first.html index 4943dce..fd7b5fd 100644 --- a/docs/remote-first.html +++ b/docs/remote-first.html @@ -50,6 +50,7 @@ Remote-first Fleet Install + Config Plugins FAQ @@ -206,6 +207,7 @@ Home Fleet Install + Config Plugins FAQ GitHub diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 6913ebc..27b7161 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -4,6 +4,7 @@ https://pi-web.dev/remote-first https://pi-web.dev/machines https://pi-web.dev/install + https://pi-web.dev/config https://pi-web.dev/plugins https://pi-web.dev/faq diff --git a/docs/styles.css b/docs/styles.css index 95b99d7..9ea31df 100644 --- a/docs/styles.css +++ b/docs/styles.css @@ -847,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; diff --git a/package.json b/package.json index ac172e4..d57a16b 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "LICENSE", "extensions", "docs/plugins.md", + "docs/config.md", "docs/assets", "plugin-api.d.ts", "plugin-api/unstable.d.ts" diff --git a/src/cli.ts b/src/cli.ts index d7f9dea..75d2c64 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -386,20 +386,21 @@ function restartOrder(refs: ServiceRef[]): ServiceRef[] { } function productionServiceDefinitions(options: InstallOptions, configPath: string, executables: ServiceExecutables): ServiceDefinition[] { + const environment = configEnvironment(options, configPath); return [ { ...serviceRefs.sessiond, description: "PI WEB session daemon", shellCommand: `exec ${executables.sessiond.command}`, restart: "on-failure", - environment: {}, + environment, }, { ...serviceRefs.web, description: "PI WEB server", shellCommand: `exec ${executables.web.command}`, restart: "on-failure", - environment: configEnvironment(options, configPath), + environment, after: ["sessiond"], wants: ["sessiond"], }, @@ -429,13 +430,14 @@ function validateDevCheckout(root: string): void { } function devServiceDefinitions(options: InstallOptions, configPath: string, root: string): ServiceDefinition[] { + const environment = configEnvironment(options, configPath); return [ { ...serviceRefs.sessiond, description: "PI WEB session daemon (dev)", shellCommand: "exec npm run start:sessiond", restart: "never", - environment: {}, + environment, workingDirectory: root, }, { @@ -443,7 +445,7 @@ function devServiceDefinitions(options: InstallOptions, configPath: string, root description: "PI WEB UI dev server", shellCommand: `exec /usr/bin/env bash -c ${serviceShellQuote('trap "kill 0" EXIT; npm run dev:web & npm run dev:client & wait')}`, restart: "never", - environment: configEnvironment(options, configPath), + environment, after: ["sessiond"], wants: ["sessiond"], workingDirectory: root, diff --git a/src/server/sessiond.ts b/src/server/sessiond.ts index 62a17b3..f4cc36e 100644 --- a/src/server/sessiond.ts +++ b/src/server/sessiond.ts @@ -21,13 +21,13 @@ import { getPiWebRuntimeComponent } from "./piWebStatus.js"; import { SESSIOND_RUNTIME_CAPABILITIES } from "../shared/capabilities.js"; import { effectivePiWebConfig, maxUploadBytes, spawnSessionsEnabled, subsessionsEnabled } from "../config.js"; -const app = Fastify({ logger: true, bodyLimit: maxUploadBytes() }); +const { config } = effectivePiWebConfig(); +const app = Fastify({ logger: true, bodyLimit: maxUploadBytes(process.env, config) }); await app.register(fastifyWebsocket); const eventHub = new SessionEventHub(); const workspaceActivity = new WorkspaceActivityService(eventHub); const auth = new AuthService(); -const { config } = effectivePiWebConfig(); const spawnTargets = spawnSessionsEnabled(process.env, config) ? new ProjectScopedSpawnTargetResolver({ projects: new ProjectService(new ProjectStore()), workspaces: new WorkspaceService() }) : undefined;