@jmfederico/pi-web 1.202606.6 → 1.202607.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -293
- package/dist/cli.js +25 -7
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/CodeViewer-tXF3UTsY.js +4 -0
- package/dist/client/assets/TerminalPanel-D_ihiWAt.js +187 -0
- package/dist/client/assets/UnifiedDiffViewer-BziirXBJ.js +39 -0
- package/dist/client/assets/index-Brfk1lwl.js +2950 -0
- package/dist/client/assets/vendor-editor-core-vUi74DnD.js +12 -0
- package/dist/client/assets/vendor-editor-languages-DoaXUodB.js +46 -0
- package/dist/client/assets/vendor-editor-legacy-CYBnW6ZU.js +1 -0
- package/dist/client/assets/vendor-terminal-BrP-ENHg.css +1 -0
- package/dist/client/assets/vendor-terminal-D8k4UKM2.js +35 -0
- package/dist/client/index.html +6 -3
- package/dist/config.js +33 -1
- package/dist/config.js.map +1 -1
- package/dist/docker/piWebDockerCommandPlan.js +211 -0
- package/dist/docker/piWebDockerCommandPlan.js.map +1 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +15 -5
- package/dist/pi-web-plugins/updates/updatesLogic.js +37 -5
- package/dist/piWebVersionReport.js +4 -0
- package/dist/piWebVersionReport.js.map +1 -1
- package/dist/plugin-api.d.ts +30 -2
- package/dist/server/app.js +32 -5
- package/dist/server/app.js.map +1 -1
- package/dist/server/browserMessageProjection.js +56 -0
- package/dist/server/browserMessageProjection.js.map +1 -0
- package/dist/server/configRoutes.js +112 -2
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/machines/machineClient.js +51 -13
- package/dist/server/machines/machineClient.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +72 -4
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +4 -26
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/piPackageRoutes.js +87 -0
- package/dist/server/piPackageRoutes.js.map +1 -0
- package/dist/server/piPackageService.js +69 -0
- package/dist/server/piPackageService.js.map +1 -0
- package/dist/server/piWebPluginService.js +43 -8
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebStatus.js +57 -0
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +2 -1
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessions/attachmentService.js +69 -11
- package/dist/server/sessions/attachmentService.js.map +1 -1
- package/dist/server/sessions/builtinCommands.js +1 -1
- package/dist/server/sessions/builtinCommands.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +20 -2
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +905 -73
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/sessionArchiveStore.js +51 -22
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionCleanup.js +157 -0
- package/dist/server/sessions/sessionCleanup.js.map +1 -0
- package/dist/server/sessions/sessionCommandService.js +16 -0
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionNameGenerator.js +27 -44
- package/dist/server/sessions/sessionNameGenerator.js.map +1 -1
- package/dist/server/sessions/sessionRoutes.js +55 -1
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/spawnSessionTool.js +9 -4
- package/dist/server/sessions/spawnSessionTool.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +28 -18
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/workspaceExplorerRoutes.js +55 -3
- package/dist/server/workspaceExplorerRoutes.js.map +1 -1
- package/dist/server/workspaces/fileContentService.js +112 -1
- package/dist/server/workspaces/fileContentService.js.map +1 -1
- package/dist/server/workspaces/fileSuggestions.js +7 -3
- package/dist/server/workspaces/fileSuggestions.js.map +1 -1
- package/dist/server/workspaces/pathSafety.js +16 -1
- package/dist/server/workspaces/pathSafety.js.map +1 -1
- package/dist/server/workspaces/projectPiWebConfig.js +6 -1
- package/dist/server/workspaces/projectPiWebConfig.js.map +1 -1
- package/dist/shared/activity.js +0 -15
- package/dist/shared/activity.js.map +1 -1
- package/dist/shared/apiTypes.d.ts +146 -7
- package/dist/shared/apiTypes.js +5 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +29 -2
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +15 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +20 -8
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/dist/shared/promptAttachments.js +30 -11
- package/dist/shared/promptAttachments.js.map +1 -1
- package/dist/shared/thinkingLevels.d.ts +1 -1
- package/dist/shared/thinkingLevels.js +1 -1
- package/dist/shared/thinkingLevels.js.map +1 -1
- package/docs/config.md +62 -14
- package/docs/plugins.md +155 -17
- package/package.json +35 -31
- package/dist/client/assets/CodeViewer-Bv8l_MFi.js +0 -4
- package/dist/client/assets/TerminalPanel-BZKsaE9s.js +0 -126
- package/dist/client/assets/index-C9oPLpm7.js +0 -2408
- package/dist/client/assets/vendor-editor-core-Bc1A7SO7.js +0 -12
- package/dist/client/assets/vendor-editor-languages-D0CnB2js.js +0 -26
- package/dist/client/assets/vendor-editor-legacy-B4QLsWF8.js +0 -1
- package/dist/client/assets/vendor-terminal-DDGTF8rc.css +0 -1
- package/dist/client/assets/vendor-terminal-DjQ08hXu.js +0 -16
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* either breaks, update this list and give the new level a label/description
|
|
6
6
|
* where thinking levels are presented.
|
|
7
7
|
*/
|
|
8
|
-
export const KNOWN_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh"];
|
|
8
|
+
export const KNOWN_THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
9
9
|
export function isKnownThinkingLevel(value) {
|
|
10
10
|
return KNOWN_THINKING_LEVELS.some((level) => level === value);
|
|
11
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thinkingLevels.js","sourceRoot":"","sources":["../../src/shared/thinkingLevels.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAA6C,CAAC;
|
|
1
|
+
{"version":3,"file":"thinkingLevels.js","sourceRoot":"","sources":["../../src/shared/thinkingLevels.ts"],"names":[],"mappings":"AAQA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAA6C,CAAC;AAE7I,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,qBAAqB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAyB;IAC1D,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AAC7D,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB,EAAE,SAA4B;IACnF,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB,CAAC;IACvE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACvD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC3B,CAAC"}
|
package/docs/config.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# PI WEB configuration reference
|
|
2
2
|
|
|
3
|
-
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.
|
|
3
|
+
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, manual upload defaults, upload limits, and session-daemon tools.
|
|
4
4
|
|
|
5
5
|
This file is the markdown reference for agents and package consumers. The website page is <https://pi-web.dev/config>.
|
|
6
6
|
|
|
@@ -11,27 +11,33 @@ PI WEB uses two config files:
|
|
|
11
11
|
- **Global PI WEB config:** `$PI_WEB_CONFIG`, or `$XDG_CONFIG_HOME/pi-web/config.json`, or `~/.config/pi-web/config.json`.
|
|
12
12
|
- **Project-local PI WEB config:** `<project>/.pi-web/config.json` for commit-able project settings.
|
|
13
13
|
|
|
14
|
-
Each PI WEB machine has its own config. When using Fleet/machine federation,
|
|
14
|
+
Each PI WEB machine has its own config. When using Fleet/machine federation, Settings uses the selected machine for config that affects work running there: session daemon tools, PI WEB plugin enablement, external path access, and upload defaults. Gateway/browser-only settings stay local to the gateway: keyboard shortcuts, remote machine registry/tokens, and gateway host/port/allowed-hosts. Remote servers that do not advertise selected-machine settings support report those settings as unavailable instead of silently falling back to the gateway.
|
|
15
|
+
|
|
16
|
+
Pi package settings are separate from PI WEB config. They live in Pi's package-manager settings on the target machine and are managed by Pi (`pi install`, `pi remove`, `pi update`) or **Settings → Pi packages**. In a federated setup, **Settings → Pi packages** targets the currently selected machine. The PI WEB `plugins` config key only enables or disables discovered PI WEB browser plugins on the machine whose config you are editing; it does not install, remove, or update Pi packages.
|
|
15
17
|
|
|
16
18
|
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`.
|
|
17
19
|
|
|
18
20
|
## Precedence and reloads
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
Machine-global runtime values are resolved as:
|
|
21
23
|
|
|
22
24
|
```text
|
|
23
|
-
defaults → config file → environment overrides
|
|
25
|
+
defaults → global config file → environment overrides
|
|
24
26
|
```
|
|
25
27
|
|
|
28
|
+
Supported project-local settings are then applied for that project's workspaces. For upload defaults, `<project>/.pi-web/config.json` overrides the global value.
|
|
29
|
+
|
|
26
30
|
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`.
|
|
27
31
|
|
|
28
32
|
Process restarts depend on the key:
|
|
29
33
|
|
|
30
|
-
- `host` / `port`: restart the web/API service or process.
|
|
31
|
-
- `maxUploadBytes`: restart both the web/API process and the session daemon.
|
|
32
|
-
- `spawnSessions` / `subsessions`: restart the session daemon.
|
|
34
|
+
- `host` / `port`: restart the gateway web/API service or process.
|
|
35
|
+
- `maxUploadBytes`: restart both the web/API process and the session daemon on that machine.
|
|
36
|
+
- `spawnSessions` / `subsessions`: restart the session daemon on that machine.
|
|
33
37
|
- `pathAccess`: applies on the next request; existing file views may need a browser refresh.
|
|
34
|
-
- `
|
|
38
|
+
- `uploads.defaultFolder`: applies to newly opened Files upload dialogs and new direct drag/drop batches after config/workspace refresh.
|
|
39
|
+
- `plugins`: reload the browser tab after changing PI WEB plugin enablement.
|
|
40
|
+
- 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.
|
|
35
41
|
- `shortcuts`: saved settings apply in the browser after config refresh/save.
|
|
36
42
|
|
|
37
43
|
## Global config example
|
|
@@ -43,6 +49,9 @@ Process restarts depend on the key:
|
|
|
43
49
|
"pathAccess": {
|
|
44
50
|
"allowedPaths": ["~/SDKs", "/opt/reference"]
|
|
45
51
|
},
|
|
52
|
+
"uploads": {
|
|
53
|
+
"defaultFolder": ".pi-web/uploads"
|
|
54
|
+
},
|
|
46
55
|
"maxUploadBytes": 67108864,
|
|
47
56
|
"spawnSessions": true,
|
|
48
57
|
"subsessions": false,
|
|
@@ -67,17 +76,22 @@ Project-local config lives at `<project>/.pi-web/config.json`. Use it for settin
|
|
|
67
76
|
"version": 1,
|
|
68
77
|
"pathAccess": {
|
|
69
78
|
"allowedPaths": ["~/SDKs", "/opt/reference"]
|
|
79
|
+
},
|
|
80
|
+
"uploads": {
|
|
81
|
+
"defaultFolder": "manual/uploads"
|
|
70
82
|
}
|
|
71
83
|
}
|
|
72
84
|
```
|
|
73
85
|
|
|
74
86
|
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.
|
|
75
87
|
|
|
88
|
+
Project-local `uploads.defaultFolder` overrides the global upload destination for workspaces in that project. Current PI WEB servers include this workspace-effective value on the existing workspace responses used locally and through machine federation. Older remote servers may omit the optional field; the browser falls back to the global/default upload folder.
|
|
89
|
+
|
|
76
90
|
Plugins may own separate project files, such as `.pi-web/tasks.json` for the built-in Workspace Tasks plugin.
|
|
77
91
|
|
|
78
92
|
## Configuration matrix
|
|
79
93
|
|
|
80
|
-
Rows with JSON key `—` are runtime-only environment variables, not config-file keys.
|
|
94
|
+
Rows with JSON key `—` are runtime-only environment variables, not config-file keys. `Global` means machine-global. In Settings, selected-machine-safe global keys (`pathAccess`, `uploads`, `maxUploadBytes`, `spawnSessions`, `subsessions`, and `plugins`) are edited for the selected machine; gateway host/port/allowed-hosts, keyboard shortcuts, and machine registry/tokens stay local.
|
|
81
95
|
|
|
82
96
|
| Config | JSON key | Env var | Scope | Project-local behavior | Applies / restart |
|
|
83
97
|
| --- | --- | --- | --- | --- | --- |
|
|
@@ -86,9 +100,10 @@ Rows with JSON key `—` are runtime-only environment variables, not config-file
|
|
|
86
100
|
| Web/API port | `port` | `PI_WEB_PORT`, `PORT` | Global | Not supported locally | Restart web/API |
|
|
87
101
|
| Dev-server allowed hosts | `allowedHosts` | `PI_WEB_ALLOWED_HOSTS` | Global | Not supported locally | Restart dev web/UI |
|
|
88
102
|
| External filesystem roots | `pathAccess.allowedPaths` | — | Global + project | **Merges**: global roots first, then project roots; duplicates removed | Next file request; refresh existing views if needed |
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
103
|
+
| Manual file upload default folder | `uploads.defaultFolder` | — | Global + project | **Overrides**: project value wins for workspaces in that project; otherwise global/default applies | New Upload dialogs and direct drag/drop batches after config/workspace refresh |
|
|
104
|
+
| Upload/body limit | `maxUploadBytes` | `PI_WEB_MAX_UPLOAD_BYTES` | Global | Not supported locally | Restart web/API and session daemon on that machine |
|
|
105
|
+
| Agent can spawn sessions | `spawnSessions` | `PI_WEB_SPAWN_SESSIONS` | Global/session daemon | Not supported locally | Restart session daemon on that machine |
|
|
106
|
+
| Tracked subsessions (beta) | `subsessions` | `PI_WEB_SUBSESSIONS` | Global/session daemon | Not supported locally; also requires `spawnSessions` | Restart session daemon on that machine |
|
|
92
107
|
| Plugin enablement/settings | `plugins.<id>.enabled`, `plugins.<id>.settings` | — | Global | Not core local config; plugins may read their own project files | Reload browser tab |
|
|
93
108
|
| Keyboard shortcuts | `shortcuts.<actionId>` | — | Global | Not supported locally | Applies after settings save/config refresh |
|
|
94
109
|
| Project config version | `version` | — | Project | Project-local only; must be `1` when present | Next project-config read |
|
|
@@ -121,19 +136,52 @@ Accepted root forms:
|
|
|
121
136
|
|
|
122
137
|
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.
|
|
123
138
|
|
|
139
|
+
In **Settings → General**, external filesystem roots are saved on the selected machine. Gateway host, port, and allowed-hosts fields stay on the gateway config.
|
|
140
|
+
|
|
124
141
|
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.
|
|
125
142
|
|
|
143
|
+
### Manual upload defaults
|
|
144
|
+
|
|
145
|
+
The Files panel can upload one or more files in two ways:
|
|
146
|
+
|
|
147
|
+
- Drop files onto the Files panel to upload immediately to the workspace-effective default folder.
|
|
148
|
+
- Use the toolbar **Upload** button to open the review dialog, edit the destination, and opt into upload options.
|
|
149
|
+
|
|
150
|
+
`uploads.defaultFolder` sets the workspace-effective default destination. The built-in default is `.pi-web/uploads`; a global config value applies to every project unless `<project>/.pi-web/config.json` sets a project-local override.
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"uploads": {
|
|
155
|
+
"defaultFolder": "manual/uploads"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The value must be a non-empty workspace-relative folder. PI WEB normalizes repeated separators and backslashes to `/`, and rejects absolute paths or `..` traversal. In the upload dialog only, clearing the destination field uploads that batch to the workspace root.
|
|
161
|
+
|
|
162
|
+
Manual uploads use the workspace file-write path: paths stay workspace-relative, parent folder creation is enabled by default, and overwrite is disabled by default. Direct drag/drop always keeps `overwrite` off; the review dialog lets you explicitly enable overwrite when needed. Browser-owned XHR progress is shown per batch/file, conflicts and errors stay visible in the upload progress UI, and the final file-write response is the source of truth.
|
|
163
|
+
|
|
164
|
+
For machine federation, Settings saves the global upload default on the selected machine. Current remote PI WEB servers also return `workspace.effectiveConfig.uploads.defaultFolder` on the existing workspace-list response. Older remote servers can omit that optional field without breaking clients; the Files panel falls back to the global/default upload folder.
|
|
165
|
+
|
|
166
|
+
The per-request size limit is still controlled by `maxUploadBytes` / `PI_WEB_MAX_UPLOAD_BYTES` on the machine serving the upload.
|
|
167
|
+
|
|
126
168
|
### Session daemon tools
|
|
127
169
|
|
|
128
170
|
`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.
|
|
129
171
|
|
|
130
172
|
`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.
|
|
131
173
|
|
|
132
|
-
Tracked subsessions let an agent delegate work to child sessions,
|
|
174
|
+
Tracked subsessions let an agent delegate work to child sessions, receive a notification when each child stops working, and inspect their status and transcripts. Calling `spawn_subsession` returns immediately. The parent can continue independent work while treating every child whose result it needs as pending. Before producing work that depends on those results, the parent reaches a join point and yields until every required child has sent a completion notice.
|
|
175
|
+
|
|
176
|
+
A completion notice wakes an idle parent. If the parent is busy, the notice queues until the current turn ends rather than interrupting in-flight work. For multiple required children, each notice resolves one pending child; after processing it, the parent yields again if another required child is pending. `list_subsessions`, `check_subsession`, and `read_subsession` provide on-demand status and transcript inspection for deliberate progress checks or recovery. Completion notifications, rather than polling these tools, are the normal synchronization mechanism.
|
|
177
|
+
|
|
178
|
+
In **Settings → Session daemon**, these keys are saved on the selected machine. Restart the session daemon on that machine after changing them.
|
|
133
179
|
|
|
134
180
|
### Plugin config
|
|
135
181
|
|
|
136
|
-
|
|
182
|
+
The `plugins` key is only for PI WEB browser plugin enablement/settings on the machine whose config you are editing. It does not install, remove, or update Pi packages; use **Settings → Pi packages** or Pi's package manager for package operations. In a federated setup, **Settings → PI WEB plugins** and **Settings → Pi packages** both target the currently selected machine, and each panel labels where changes will be saved or run.
|
|
183
|
+
|
|
184
|
+
Plugins are enabled by default. Set `plugins.<id>.enabled` to `false` to remove a plugin from that machine's `/pi-web-plugins/manifest.json` before the browser imports it. Settings lists discovered plugins from the selected machine, including disabled entries exposed by that machine.
|
|
137
185
|
|
|
138
186
|
```json
|
|
139
187
|
{
|
package/docs/plugins.md
CHANGED
|
@@ -13,6 +13,18 @@ Plugins can currently:
|
|
|
13
13
|
|
|
14
14
|
They do **not** run in the session daemon, do not get a server-side hook API, and are not sandboxed.
|
|
15
15
|
|
|
16
|
+
## Pi packages vs PI WEB plugins
|
|
17
|
+
|
|
18
|
+
**Pi packages** are packages managed by Pi (`pi install`, `pi remove`, `pi update`). A Pi package can provide 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.
|
|
19
|
+
|
|
20
|
+
**PI WEB plugins** are browser-side PI WEB UI modules discovered from bundled, local, dev, and installed Pi-package sources. Enabling or disabling a PI WEB plugin is a PI WEB config task; installing, removing, or updating a Pi package is a Pi package-manager task.
|
|
21
|
+
|
|
22
|
+
Use **Settings → Pi packages** to view configured Pi packages or install/remove/update a package. Enter only the package source, such as `npm:@scope/package`, a git/URL source, or a local path. PI WEB uses Pi's default package location, equivalent to `pi install <source>`, and does not ask for an install location.
|
|
23
|
+
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
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.
|
|
27
|
+
|
|
16
28
|
## Trust model
|
|
17
29
|
|
|
18
30
|
Plugins run as JavaScript in the browser app. Treat them as trusted code:
|
|
@@ -140,7 +152,7 @@ When [machine federation](https://pi-web.dev/machines) is enabled, PI WEB also l
|
|
|
140
152
|
- remote theme contributions are ignored for now because themes are app-wide;
|
|
141
153
|
- mixed PI WEB versions across federated machines are best-effort and not guaranteed compatible.
|
|
142
154
|
|
|
143
|
-
Remote plugin enablement is controlled by the remote machine's PI WEB plugin config. To edit or disable a remote machine plugin,
|
|
155
|
+
Remote plugin enablement is controlled by the remote machine's PI WEB plugin config. To edit or disable a remote machine plugin, select that machine and use **Settings → PI WEB plugins** when the remote server exposes selected-machine settings, or open that machine directly/update its config file.
|
|
144
156
|
|
|
145
157
|
Plugin package metadata may set `machineSpecific: true` when the plugin's meaning is tied to the selected PI WEB machine:
|
|
146
158
|
|
|
@@ -155,9 +167,11 @@ const url = new URL("./asset.json", import.meta.url);
|
|
|
155
167
|
|
|
156
168
|
If a remote plugin constructs absolute asset URLs, it should use the `pluginId` from `activate()` because PI WEB gives remote plugins a gateway-scoped runtime id. Hard-coded `/pi-web-plugins/<original-id>/...` URLs may point at the gateway instead of the remote machine.
|
|
157
169
|
|
|
158
|
-
## Manage plugins
|
|
170
|
+
## Manage PI WEB plugins
|
|
159
171
|
|
|
160
|
-
Open **Settings →
|
|
172
|
+
Open **Settings → PI WEB plugins** to review discovered bundled, local, dev, and Pi package 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 built-in command palette, base workspace tools, and themes are not managed through this plugin list.
|
|
173
|
+
|
|
174
|
+
This surface is only for PI WEB plugin enablement. To install, remove, or update Pi packages that may provide plugins or other Pi resources, use **Settings → Pi packages**. 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 `plugins` config key rather than changing Pi package-manager settings.
|
|
161
175
|
|
|
162
176
|
Plugin preferences are stored under the top-level `plugins` config key in the PI WEB config file:
|
|
163
177
|
|
|
@@ -183,14 +197,14 @@ After changing plugin enablement, reload the PI WEB browser tab. Already-loaded
|
|
|
183
197
|
|
|
184
198
|
PI WEB ships core, discoverable plugins in the main `@jmfederico/pi-web` npm package. No separate `pi install` step is required: update PI WEB, reload the browser tab, and the bundled plugins appear in `/pi-web-plugins/manifest.json`.
|
|
185
199
|
|
|
186
|
-
Built-in plugins can be managed from **Settings →
|
|
200
|
+
Built-in plugins can be managed from **Settings → PI WEB plugins** or with the top-level `plugins` config key.
|
|
187
201
|
|
|
188
202
|
### Updates
|
|
189
203
|
|
|
190
204
|
**Plugin id:** `updates`
|
|
191
205
|
**What it does:** adds a conditional **Updates** workspace tab with PI WEB update, restart, and installed-service guidance.
|
|
192
206
|
|
|
193
|
-
Updates is enabled by default. It declares `machineSpecific: true` so the gateway Updates tab only appears for the local machine; while a remote machine is selected, that remote machine's Updates plugin is used if available. To hide it, disable `updates` in **Settings →
|
|
207
|
+
Updates is enabled by default. It declares `machineSpecific: true` so the gateway Updates tab only appears for the local machine; while a remote machine is selected, that remote machine's Updates plugin is used if available. To hide it, disable `updates` in **Settings → PI WEB plugins** or set:
|
|
194
208
|
|
|
195
209
|
```json
|
|
196
210
|
{
|
|
@@ -206,7 +220,7 @@ Updates is enabled by default. It declares `machineSpecific: true` so the gatewa
|
|
|
206
220
|
**Config file:** `.pi-web/tasks.json`
|
|
207
221
|
**What it does:** adds a **Tasks** workspace tab for running configured shell commands in dedicated PI WEB terminals.
|
|
208
222
|
|
|
209
|
-
Workspace Tasks is enabled by default. To hide it, disable `workspace-tasks` in **Settings →
|
|
223
|
+
Workspace Tasks is enabled by default. To hide it, disable `workspace-tasks` in **Settings → PI WEB plugins** or set:
|
|
210
224
|
|
|
211
225
|
```json
|
|
212
226
|
{
|
|
@@ -223,11 +237,11 @@ Configure workspace tasks in `.pi-web/tasks.json`:
|
|
|
223
237
|
"version": 1,
|
|
224
238
|
"tasks": [
|
|
225
239
|
{
|
|
226
|
-
"id": "
|
|
227
|
-
"title": "Start
|
|
228
|
-
"group": "
|
|
229
|
-
"description": "Start the local
|
|
230
|
-
"command": "
|
|
240
|
+
"id": "app.start",
|
|
241
|
+
"title": "Start app",
|
|
242
|
+
"group": "Development",
|
|
243
|
+
"description": "Start the local development server.",
|
|
244
|
+
"command": "npm run dev"
|
|
231
245
|
},
|
|
232
246
|
{
|
|
233
247
|
"id": "db.reset",
|
|
@@ -273,7 +287,7 @@ PI WEB builds the gateway `/pi-web-plugins/manifest.json` from these sources:
|
|
|
273
287
|
|
|
274
288
|
Entries may be real directories or symlinks. This is the recommended development workflow.
|
|
275
289
|
|
|
276
|
-
3. Installed Pi packages that expose PI WEB plugin metadata. Pi packages may be user or project scoped.
|
|
290
|
+
3. Installed Pi packages that expose PI WEB plugin metadata. Pi packages may be user or project scoped. Installing/removing/updating Pi packages is done from **Settings → Pi packages** (or Pi's package manager), not from the PI WEB plugin enable/disable list.
|
|
277
291
|
|
|
278
292
|
Remote machines expose their own manifests through the gateway at `/api/machines/<machine-id>/pi-web-plugins/manifest.json`. Those plugin modules are rewritten to gateway-scoped asset URLs and registered under machine-scoped runtime ids so duplicate plugin ids on different machines do not collide.
|
|
279
293
|
|
|
@@ -426,10 +440,13 @@ interface PluginAction {
|
|
|
426
440
|
shortcut?: string;
|
|
427
441
|
group?: string;
|
|
428
442
|
enabled?: (context: PluginRuntimeContext) => boolean;
|
|
443
|
+
disabledReason?: (context: PluginRuntimeContext) => string | undefined;
|
|
429
444
|
run: (context: PluginRuntimeContext) => void | Promise<void>;
|
|
430
445
|
}
|
|
431
446
|
```
|
|
432
447
|
|
|
448
|
+
If an action is disabled and returns `disabledReason`, PI WEB can keep it visible in the action palette with that explanation instead of hiding it.
|
|
449
|
+
|
|
433
450
|
Stable runtime context fields:
|
|
434
451
|
|
|
435
452
|
```ts
|
|
@@ -439,6 +456,7 @@ interface PluginRuntimeContext {
|
|
|
439
456
|
selectedSession?: unknown;
|
|
440
457
|
piWebStatus?: PiWebStatusResponse;
|
|
441
458
|
};
|
|
459
|
+
prompt: PluginPromptEditor;
|
|
442
460
|
openActionPalette: () => void;
|
|
443
461
|
focusPrompt: () => void;
|
|
444
462
|
addProject: () => void | Promise<void>;
|
|
@@ -464,6 +482,29 @@ Notes:
|
|
|
464
482
|
- `openTerminal()` switches to the built-in terminal panel. Pass `{ terminalId }` to deep-link to a specific terminal.
|
|
465
483
|
- Only fields documented here and declared in `plugin-api.d.ts` are stable public plugin API. Anything else is experimental: it may become public API later, change shape, or disappear.
|
|
466
484
|
|
|
485
|
+
### Prompt editor API
|
|
486
|
+
|
|
487
|
+
The `prompt` helper on `PluginRuntimeContext` and `WorkspacePanelContext` provides stable access to the chat prompt editor:
|
|
488
|
+
|
|
489
|
+
| Method | Description |
|
|
490
|
+
| --- | --- |
|
|
491
|
+
| `insertText(text)` | Insert text at cursor position. When text is selected, replaces the selection. Focuses the editor first if not focused. |
|
|
492
|
+
| `getText()` | Returns the full prompt text. |
|
|
493
|
+
| `getSelection()` | Returns `{ start, end, text }` if text is selected, or `null`. |
|
|
494
|
+
|
|
495
|
+
Usage:
|
|
496
|
+
|
|
497
|
+
```js
|
|
498
|
+
// Insert text at the cursor (e.g. a file mention)
|
|
499
|
+
context.prompt.insertText("@file.txt");
|
|
500
|
+
|
|
501
|
+
// Read the current prompt and selection
|
|
502
|
+
const text = context.prompt.getText();
|
|
503
|
+
const selection = context.prompt.getSelection(); // { start, end, text } | null
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
Use `focusPrompt()` on `PluginRuntimeContext` to move focus to the prompt editor. Workspace panels can call `context.prompt.insertText()` from explicit user interactions such as button clicks; panel contexts target the currently selected session's mounted prompt editor.
|
|
507
|
+
|
|
467
508
|
#### Keyboard shortcuts
|
|
468
509
|
|
|
469
510
|
- App-level keyboard shortcuts must be attached to actions. PI WEB does not support standalone plugin keyboard commands; contribute an action first, then add a `shortcut` if it needs a keybinding.
|
|
@@ -521,7 +562,11 @@ interface WorkspacePanelContext {
|
|
|
521
562
|
state?: PluginRuntimeState;
|
|
522
563
|
files: {
|
|
523
564
|
readFile(path: string): Promise<FileContentResponse>;
|
|
565
|
+
writeFile(path: string, content: string | Uint8Array, options?: WriteWorkspaceFileOptions): Promise<WriteWorkspaceFileResponse>;
|
|
566
|
+
deleteFile(path: string): Promise<DeleteWorkspaceFileResponse>;
|
|
567
|
+
moveFile(fromPath: string, toPath: string, options?: MoveWorkspaceFileOptions): Promise<MoveWorkspaceFileResponse>;
|
|
524
568
|
};
|
|
569
|
+
prompt: PluginPromptEditor;
|
|
525
570
|
terminal: {
|
|
526
571
|
open(options?: { terminalId?: string }): void;
|
|
527
572
|
runCommand(input: {
|
|
@@ -539,7 +584,7 @@ interface WorkspacePanelContext {
|
|
|
539
584
|
|
|
540
585
|
`icon` is optional and is used in the compact mobile tab bar. Prefer an SVG rendered with the `svg` helper from `PluginActivationContext`; use `currentColor` so PI WEB themes can style it. If `icon` is omitted, mobile tabs fall back to initials from the panel title, or to the full title when initials collide.
|
|
541
586
|
|
|
542
|
-
`machine`, `workspace`, `files`, `terminal`, and `host` are documented as stable for panel callbacks. Use `terminal.open()` to switch to the built-in terminal panel; pass `{ terminalId }` to deep-link to a specific terminal. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate panel callbacks such as `badge`, `visible`, or `render`.
|
|
587
|
+
`machine`, `workspace`, `files`, `prompt`, `terminal`, and `host` are documented as stable for panel callbacks. The `files` helper supports `readFile`, `writeFile`, `deleteFile`, and `moveFile` — see [Reading workspace files](#reading-workspace-files) and [Writing workspace files](#writing-workspace-files). The `prompt` helper supports panel interactions that insert workspace context into the current prompt — see [Prompt editor API](#prompt-editor-api). Use `terminal.open()` to switch to the built-in terminal panel; pass `{ terminalId }` to deep-link to a specific terminal. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate panel callbacks such as `badge`, `visible`, or `render`.
|
|
543
588
|
|
|
544
589
|
For compatibility, PI WEB still provides the old `context.openTerminal()` workspace-panel helper at runtime. It is deprecated, intentionally omitted from the public TypeScript declarations, and planned for removal in v2. Existing JavaScript plugins keep working, while typed plugins should migrate to `context.terminal.open()`.
|
|
545
590
|
|
|
@@ -607,6 +652,9 @@ interface WorkspaceLabelContext {
|
|
|
607
652
|
state?: PluginRuntimeState;
|
|
608
653
|
files: {
|
|
609
654
|
readFile(path: string): Promise<FileContentResponse>;
|
|
655
|
+
writeFile(path: string, content: string | Uint8Array, options?: WriteWorkspaceFileOptions): Promise<WriteWorkspaceFileResponse>;
|
|
656
|
+
deleteFile(path: string): Promise<DeleteWorkspaceFileResponse>;
|
|
657
|
+
moveFile(fromPath: string, toPath: string, options?: MoveWorkspaceFileOptions): Promise<MoveWorkspaceFileResponse>;
|
|
610
658
|
};
|
|
611
659
|
host: {
|
|
612
660
|
requestRender(): void;
|
|
@@ -614,7 +662,7 @@ interface WorkspaceLabelContext {
|
|
|
614
662
|
}
|
|
615
663
|
```
|
|
616
664
|
|
|
617
|
-
`machine`, `workspace`, `files`, and `host` are documented as stable for label callbacks. Include `machine.id` in any label caches that depend on workspace data. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate label `visible` or `items` callbacks.
|
|
665
|
+
`machine`, `workspace`, `files`, and `host` are documented as stable for label callbacks. The `files` helper supports `readFile`, `writeFile`, `deleteFile`, and `moveFile` — see [Reading workspace files](#reading-workspace-files) and [Writing workspace files](#writing-workspace-files). Include `machine.id` in any label caches that depend on workspace data. Call `host.requestRender()` when async plugin-owned state changes should make PI WEB re-evaluate label `visible` or `items` callbacks.
|
|
618
666
|
|
|
619
667
|
Items are sorted by `order` and then id. Return an empty array to render nothing. Keep callbacks synchronous and lightweight; start async work from the callback, return cached items, then call `host.requestRender()` when the cache changes.
|
|
620
668
|
|
|
@@ -712,7 +760,7 @@ Labels should use the same helper through a plugin-owned cache because `items()`
|
|
|
712
760
|
const envCache = new Map();
|
|
713
761
|
|
|
714
762
|
function envKey(machine, workspace) {
|
|
715
|
-
return `${machine.id}:${workspace.id}
|
|
763
|
+
return `${machine.id}:${workspace.id}:.env.local`;
|
|
716
764
|
}
|
|
717
765
|
|
|
718
766
|
function loadEnvLabel(context) {
|
|
@@ -722,7 +770,7 @@ function loadEnvLabel(context) {
|
|
|
722
770
|
|
|
723
771
|
const pending = { status: "loading", label: undefined };
|
|
724
772
|
envCache.set(key, pending);
|
|
725
|
-
context.files.readFile("
|
|
773
|
+
context.files.readFile(".env.local")
|
|
726
774
|
.then((file) => {
|
|
727
775
|
pending.status = "ready";
|
|
728
776
|
pending.label = file.content.match(/^DEV_URL=(.+)$/m)?.[1];
|
|
@@ -753,6 +801,96 @@ workspaceLabels: [
|
|
|
753
801
|
|
|
754
802
|
The file response includes fields such as `path`, `content`, `truncated`, and `binary`. Be careful with sensitive files such as `.env`: plugins are trusted browser code, and file contents are exposed to the plugin.
|
|
755
803
|
|
|
804
|
+
## Writing, deleting, and moving workspace files
|
|
805
|
+
|
|
806
|
+
Workspace panels and workspace labels can write, delete, and move files through the documented `files` helper. Like `readFile`, PI WEB binds these helpers to the callback's machine and workspace, so they work the same for local and federated machines.
|
|
807
|
+
|
|
808
|
+
### Writing files
|
|
809
|
+
|
|
810
|
+
```js
|
|
811
|
+
workspacePanels: [
|
|
812
|
+
{
|
|
813
|
+
id: "workspace.generate",
|
|
814
|
+
title: "Generate",
|
|
815
|
+
render: ({ files }) => html`
|
|
816
|
+
<button @click=${async () => {
|
|
817
|
+
const result = await files.writeFile("output/result.txt", "Generated content\n");
|
|
818
|
+
console.log("Wrote", result.path, result.size, "bytes");
|
|
819
|
+
}}>Generate</button>
|
|
820
|
+
`,
|
|
821
|
+
},
|
|
822
|
+
]
|
|
823
|
+
```
|
|
824
|
+
|
|
825
|
+
### Binary writes
|
|
826
|
+
|
|
827
|
+
Pass a `Uint8Array` for binary content such as images:
|
|
828
|
+
|
|
829
|
+
```js
|
|
830
|
+
const png = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a]);
|
|
831
|
+
await files.writeFile("screenshots/thumb.png", png);
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
### Options
|
|
835
|
+
|
|
836
|
+
`files.writeFile` accepts an optional third argument:
|
|
837
|
+
|
|
838
|
+
- `createDirs` (default `true`): create intermediate directories, like `mkdir -p`.
|
|
839
|
+
- `overwrite` (default `true`): overwrite existing files. Set to `false` to throw if the file already exists.
|
|
840
|
+
|
|
841
|
+
```js
|
|
842
|
+
// Create only — throw if the file already exists
|
|
843
|
+
await files.writeFile("config/new-config.json", jsonContent, { overwrite: false });
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### Deleting files
|
|
847
|
+
|
|
848
|
+
`files.deleteFile` removes a workspace file. It is idempotent: deleting a file that does not exist returns `{ existed: false }` instead of throwing.
|
|
849
|
+
|
|
850
|
+
```js
|
|
851
|
+
const result = await files.deleteFile("temp/cache.json");
|
|
852
|
+
console.log(result.existed ? "File deleted" : "File did not exist");
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
### Moving files
|
|
856
|
+
|
|
857
|
+
`files.moveFile` renames or moves a file within the workspace, like `mv`. The default is safe: it will not overwrite an existing target file.
|
|
858
|
+
|
|
859
|
+
```js
|
|
860
|
+
// Rename a file
|
|
861
|
+
await files.moveFile("old-name.txt", "new-name.txt");
|
|
862
|
+
|
|
863
|
+
// Move into a subdirectory (creates intermediate dirs by default)
|
|
864
|
+
await files.moveFile("file.txt", "archive/file.txt");
|
|
865
|
+
|
|
866
|
+
// Overwrite an existing target
|
|
867
|
+
await files.moveFile("incoming.txt", "current.txt", { overwrite: true });
|
|
868
|
+
|
|
869
|
+
// Move without creating intermediate directories
|
|
870
|
+
await files.moveFile("file.txt", "deep/nested/file.txt", { createDirs: false }); // throws if dirs don't exist
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
`files.moveFile` accepts an optional third argument:
|
|
874
|
+
|
|
875
|
+
- `createDirs` (default `true`): create intermediate directories for the target path.
|
|
876
|
+
- `overwrite` (default `false`): overwrite the target file if it exists. The default is safer than `writeFile` because moving is a more destructive operation.
|
|
877
|
+
|
|
878
|
+
### Error handling
|
|
879
|
+
|
|
880
|
+
All file mutations share the same safety layer:
|
|
881
|
+
|
|
882
|
+
- `overwrite: false` on `writeFile` or existing target on `moveFile` (default) throws if the file already exists.
|
|
883
|
+
- Path traversal (e.g., `../../etc/passwd`) is blocked by the workspace safety layer.
|
|
884
|
+
- Writing to or moving to a path that is a directory returns an error.
|
|
885
|
+
- Deleting a directory returns an error.
|
|
886
|
+
- Intermediate directory creation with `createDirs: false` fails if the parent directory does not exist.
|
|
887
|
+
|
|
888
|
+
After any mutation (`writeFile`, `deleteFile`, or `moveFile`), the File Explorer updates automatically. No explicit `refreshFiles()` call is needed from plugin code. For label and badge updates, call `context.host.requestRender()` if the UI should reflect the change.
|
|
889
|
+
|
|
890
|
+
### Security
|
|
891
|
+
|
|
892
|
+
Plugins are trusted browser code. File writes go through the same path safety validation as reads — paths are resolved and checked to stay inside the workspace root.
|
|
893
|
+
|
|
756
894
|
## Running workspace terminal commands
|
|
757
895
|
|
|
758
896
|
Workspace panels can start terminal commands through the documented `terminal` helper. Commands run in the current workspace on the panel's machine.
|
|
@@ -801,7 +939,7 @@ If you are an AI agent building or editing a PI WEB plugin, follow this checklis
|
|
|
801
939
|
9. Add workspace panels for larger workspace UI.
|
|
802
940
|
10. Add workspace labels for compact inline metadata.
|
|
803
941
|
11. Return arrays from workspace label `items()`; return an empty array to render nothing.
|
|
804
|
-
12. Use documented context helpers first: `files`, `terminal`, `host.requestRender`, `workspace`, `machine`, `state.selectedWorkspace`, `state.selectedSession`,
|
|
942
|
+
12. Use documented context helpers first: `files`, `terminal`, `host.requestRender`, `workspace`, `machine`, `state.selectedWorkspace`, `state.selectedSession`, `state.piWebStatus`, and `prompt`.
|
|
805
943
|
13. Do not fetch PI WEB `/api/...` endpoints directly unless you intentionally accept private API churn; prefer documented helpers.
|
|
806
944
|
14. Treat plugins as trusted code and avoid reading or displaying secrets unless intentional.
|
|
807
945
|
15. After local edits, tell the user to hard reload the browser and check the console for plugin errors.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jmfederico/pi-web",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.202607.0",
|
|
4
4
|
"description": "Web UI for persistent Pi Coding Agent sessions in real workspaces.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Federico Jaramillo Martinez",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"dist",
|
|
15
|
+
"!dist/**/*.testSupport.*",
|
|
15
16
|
"install.sh",
|
|
16
17
|
"README.md",
|
|
17
18
|
"LICENSE",
|
|
@@ -29,18 +30,20 @@
|
|
|
29
30
|
"dev:server": "npm run dev:web",
|
|
30
31
|
"dev:client": "vite --host 0.0.0.0",
|
|
31
32
|
"dev:plugins": "node scripts/build-plugins.mjs --watch",
|
|
32
|
-
"build": "tsc -p tsconfig.build.json && npm run build:plugin-api && npm run build:plugins && vite build",
|
|
33
|
+
"build": "npm run clean && tsc -p tsconfig.build.json && npm run build:plugin-api && npm run build:plugins && vite build",
|
|
33
34
|
"build:plugin-api": "tsc -p tsconfig.plugin-api.json",
|
|
34
35
|
"build:plugins": "tsc -p tsconfig.plugins.json && node scripts/build-plugins.mjs",
|
|
35
36
|
"capture:screenshots": "node scripts/capture-screenshots.mjs",
|
|
36
37
|
"typecheck": "tsc --noEmit",
|
|
38
|
+
"typecheck:cached": "tsc --noEmit --incremental --tsBuildInfoFile node_modules/.cache/pi-web/typecheck.tsbuildinfo",
|
|
37
39
|
"knip": "knip",
|
|
38
40
|
"lint": "eslint \"src/**/*.ts\" \"extensions/**/*.ts\" \"pi-web-plugins/**/*.ts\" vite.config.ts vitest.config.ts",
|
|
39
41
|
"test": "vitest run --config vitest.config.ts",
|
|
40
42
|
"verify": "npm run typecheck && npm run lint && npm run knip && npm test",
|
|
43
|
+
"verify:staged": "node scripts/verify-staged.mjs",
|
|
41
44
|
"start": "tsx src/server/index.ts",
|
|
42
45
|
"start:sessiond": "tsx src/server/sessiond.ts",
|
|
43
|
-
"clean": "
|
|
46
|
+
"clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
44
47
|
"prepack": "npm run build",
|
|
45
48
|
"pack:dry": "npm pack --dry-run",
|
|
46
49
|
"prepublishOnly": "npm run verify",
|
|
@@ -51,7 +54,7 @@
|
|
|
51
54
|
"changelog:status": "changeset status"
|
|
52
55
|
},
|
|
53
56
|
"dependencies": {
|
|
54
|
-
"@codemirror/commands": "^6.10.
|
|
57
|
+
"@codemirror/commands": "^6.10.4",
|
|
55
58
|
"@codemirror/lang-css": "^6.3.1",
|
|
56
59
|
"@codemirror/lang-go": "^6.0.1",
|
|
57
60
|
"@codemirror/lang-html": "^6.4.11",
|
|
@@ -60,38 +63,39 @@
|
|
|
60
63
|
"@codemirror/lang-markdown": "^6.5.0",
|
|
61
64
|
"@codemirror/lang-python": "^6.2.1",
|
|
62
65
|
"@codemirror/lang-rust": "^6.0.2",
|
|
63
|
-
"@codemirror/language": "^6.12.
|
|
64
|
-
"@codemirror/legacy-modes": "^6.5.
|
|
65
|
-
"@codemirror/state": "^6.
|
|
66
|
-
"@codemirror/view": "^6.
|
|
67
|
-
"@fastify/
|
|
68
|
-
"@fastify/
|
|
66
|
+
"@codemirror/language": "^6.12.4",
|
|
67
|
+
"@codemirror/legacy-modes": "^6.5.3",
|
|
68
|
+
"@codemirror/state": "^6.7.1",
|
|
69
|
+
"@codemirror/view": "^6.43.6",
|
|
70
|
+
"@fastify/compress": "^9.0.0",
|
|
71
|
+
"@fastify/static": "^9.3.0",
|
|
72
|
+
"@fastify/websocket": "^11.3.0",
|
|
69
73
|
"@xterm/addon-fit": "^0.11.0",
|
|
70
74
|
"@xterm/xterm": "^6.0.0",
|
|
71
|
-
"diff": "^
|
|
72
|
-
"fastify": "^5.
|
|
73
|
-
"lit": "^3.3.
|
|
74
|
-
"marked": "^18.0.
|
|
75
|
+
"diff": "^9.0.0",
|
|
76
|
+
"fastify": "^5.10.0",
|
|
77
|
+
"lit": "^3.3.3",
|
|
78
|
+
"marked": "^18.0.6",
|
|
75
79
|
"node-pty": "^1.1.0",
|
|
76
|
-
"typebox": "1.
|
|
77
|
-
"ws": "^8.
|
|
80
|
+
"typebox": "1.3.6",
|
|
81
|
+
"ws": "^8.21.0"
|
|
78
82
|
},
|
|
79
83
|
"devDependencies": {
|
|
80
84
|
"@changesets/cli": "^2.31.0",
|
|
81
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
82
|
-
"@earendil-works/pi-ai": "^0.
|
|
83
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
85
|
+
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
86
|
+
"@earendil-works/pi-ai": "^0.80.6",
|
|
87
|
+
"@earendil-works/pi-coding-agent": "^0.80.6",
|
|
84
88
|
"@eslint/js": "^10.0.1",
|
|
85
|
-
"@types/node": "^24.
|
|
89
|
+
"@types/node": "^24.13.3",
|
|
86
90
|
"@types/ws": "^8.18.1",
|
|
87
|
-
"eslint": "^10.
|
|
88
|
-
"globals": "^17.
|
|
89
|
-
"knip": "^6.
|
|
90
|
-
"tsx": "^4.
|
|
91
|
-
"typescript": "^
|
|
92
|
-
"typescript-eslint": "^8.
|
|
93
|
-
"vite": "^
|
|
94
|
-
"vitest": "^4.1.
|
|
91
|
+
"eslint": "^10.6.0",
|
|
92
|
+
"globals": "^17.7.0",
|
|
93
|
+
"knip": "^6.25.0",
|
|
94
|
+
"tsx": "^4.23.0",
|
|
95
|
+
"typescript": "^6.0.3",
|
|
96
|
+
"typescript-eslint": "^8.63.0",
|
|
97
|
+
"vite": "^8.1.4",
|
|
98
|
+
"vitest": "^4.1.10"
|
|
95
99
|
},
|
|
96
100
|
"publishConfig": {
|
|
97
101
|
"access": "public"
|
|
@@ -109,9 +113,9 @@
|
|
|
109
113
|
"homepage": "https://pi-web.dev/",
|
|
110
114
|
"packageManager": "npm@11.11.0",
|
|
111
115
|
"peerDependencies": {
|
|
112
|
-
"@earendil-works/pi-agent-core": ">=0.
|
|
113
|
-
"@earendil-works/pi-ai": ">=0.
|
|
114
|
-
"@earendil-works/pi-coding-agent": ">=0.
|
|
116
|
+
"@earendil-works/pi-agent-core": ">=0.80.0 <1",
|
|
117
|
+
"@earendil-works/pi-ai": ">=0.80.0 <1",
|
|
118
|
+
"@earendil-works/pi-coding-agent": ">=0.80.0 <1"
|
|
115
119
|
},
|
|
116
120
|
"keywords": [
|
|
117
121
|
"pi-package",
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{w as a,J as p,$ as h,A as m,X as g,U as f,_ as v,a0 as b}from"./vendor-editor-core-Bc1A7SO7.js";import{g as y,r as w,p as C,h as x,c as j,m as _,j as k,a as u}from"./vendor-editor-languages-D0CnB2js.js";import{d as E}from"./vendor-editor-legacy-B4QLsWF8.js";import{i as H,b as O,a as S,n as d,e as P,t as L}from"./index-C9oPLpm7.js";var D=Object.defineProperty,F=Object.getOwnPropertyDescriptor,i=(e,o,n,s)=>{for(var t=s>1?void 0:s?F(o,n):o,c=e.length-1,l;c>=0;c--)(l=e[c])&&(t=(s?l(o,n,t):l(t))||t);return s&&t&&D(o,n,t),t};let r=class extends H{constructor(){super(...arguments),this.content=""}firstUpdated(){this.recreateEditor()}updated(e){(e.has("content")||e.has("language"))&&this.recreateEditor()}disconnectedCallback(){this.view?.destroy(),this.view=void 0,super.disconnectedCallback()}render(){return O`<div class="host"></div>`}recreateEditor(){this.editorHost&&(this.view?.destroy(),this.view=new a({parent:this.editorHost,state:p.create({doc:this.content,extensions:[h(),m.of(g),f(v,{fallback:!0}),p.readOnly.of(!0),a.editable.of(!1),a.lineWrapping,M,...R(this.language)]})}))}};r.styles=S`
|
|
2
|
-
:host { display: block; min-height: 0; height: 100%; }
|
|
3
|
-
.host { height: 100%; min-height: 0; overflow: auto; }
|
|
4
|
-
`;i([d()],r.prototype,"content",2);i([d()],r.prototype,"language",2);i([P(".host")],r.prototype,"editorHost",2);r=i([L("code-viewer")],r);const M=a.theme({"&":{height:"100%",color:"var(--pi-text)",backgroundColor:"var(--pi-bg)",fontSize:"12px"},".cm-scroller":{fontFamily:"ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",lineHeight:"1.45"},".cm-gutters":{backgroundColor:"var(--pi-bg)",color:"var(--pi-dim)",borderRight:"1px solid var(--pi-border-muted)"},".cm-activeLineGutter":{backgroundColor:"transparent"},".cm-activeLine":{backgroundColor:"transparent"},".cm-content":{caretColor:"transparent"},"&.cm-focused":{outline:"none"}});function R(e){if(e===void 0)return[];switch(e){case"typescript":return[u({typescript:!0})];case"javascript":return[u()];case"json":return[k()];case"markdown":return[_()];case"css":return[j()];case"html":return[x()];case"python":return[C()];case"rust":return[w()];case"go":return[y()];case"diff":return[b.define(E)];default:return[]}}export{r as CodeViewer};
|