@firstpick/pi-package-webui 0.2.0 → 0.2.1
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 +80 -136
- package/package.json +1 -1
- package/start-webui.ps1 +45 -0
- package/start-webui.sh +50 -1
package/README.md
CHANGED
|
@@ -1,115 +1,59 @@
|
|
|
1
1
|
# @firstpick/pi-package-webui
|
|
2
2
|
|
|
3
|
-
Local browser
|
|
3
|
+
Local browser UI for [Pi coding agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent).
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Pi Web UI gives you a local browser companion for Pi: multi-tab chat, streaming output, model controls, uploads, slash-command helpers, workspace navigation, and optional extension widgets.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- `/webui-start`: a Pi slash command that launches `pi-webui` for the current Pi working directory and opens the browser.
|
|
11
|
-
- `/webui-status`: a Pi slash command that reports the Web UI URL, online state, network exposure, and optional detailed runtime info.
|
|
12
|
-
- A no-build web app in `public/` with no runtime frontend dependencies.
|
|
13
|
-
|
|
14
|
-
> **Security:** Pi Web UI has no authentication. It can control the spawned Pi session, including any tools Pi is allowed to run. It binds to `127.0.0.1` by default; do not expose it on untrusted networks.
|
|
9
|
+
> **Security:** Pi Web UI has no authentication. It can control the spawned Pi session and run anything that session is allowed to run. It binds to `127.0.0.1` by default; only expose it on trusted networks.
|
|
15
10
|
|
|
16
11
|
## Requirements
|
|
17
12
|
|
|
18
13
|
- Node.js `>=22.19.0`
|
|
19
|
-
- Pi
|
|
14
|
+
- Pi installed and configured
|
|
20
15
|
- A modern browser with Server-Sent Events support
|
|
21
16
|
|
|
22
|
-
##
|
|
23
|
-
|
|
24
|
-
The Web UI declares its companion Pi packages as npm `optionalDependencies`. A normal npm/Pi install will install them, while minimal installs can skip them with npm's optional-dependency controls such as `npm install --omit=optional`.
|
|
25
|
-
|
|
26
|
-
At startup, the browser checks loaded Pi capabilities directly through RPC-visible commands and live widget events; it does not inspect npm package folders. That means locally symlinked/dev packages and separately installed Pi packages work as long as their commands/widgets are loaded in the active Pi tab.
|
|
27
|
-
|
|
28
|
-
The side panel shows each optional feature as enabled, disabled, or install-needed. Disabling a feature is Web UI-local and hides Web UI affordances/specialized renderers without uninstalling or unloading the underlying Pi package. Installing a missing feature is an explicit, warned action: the server runs npm install for the whitelisted package from localhost only, then prompts you to `/reload` the active Pi tab so newly installed resources can load.
|
|
29
|
-
|
|
30
|
-
Optional companions:
|
|
31
|
-
|
|
32
|
-
- `@firstpick/pi-prompts-git-pr` for the guided Git workflow's `/git-staged-msg` prompt.
|
|
33
|
-
- `@firstpick/pi-extension-release-npm` and `@firstpick/pi-extension-release-aur` for Publish menu commands and live release widgets.
|
|
34
|
-
- `@firstpick/pi-extension-todo-progress` for the specialized todo-progress widget.
|
|
35
|
-
- `@firstpick/pi-extension-git-footer-status` and `@firstpick/pi-extension-stats` for richer Pi status/footer and stats commands.
|
|
36
|
-
- `@firstpick/pi-themes-bundle` for theme resources used by the browser theme picker and Pi themes.
|
|
37
|
-
|
|
38
|
-
## Quick start
|
|
17
|
+
## Install
|
|
39
18
|
|
|
40
|
-
Install the package
|
|
19
|
+
Install the package into Pi:
|
|
41
20
|
|
|
42
21
|
```bash
|
|
43
22
|
pi install npm:@firstpick/pi-package-webui
|
|
44
23
|
```
|
|
45
24
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
```text
|
|
49
|
-
/webui-start
|
|
50
|
-
```
|
|
25
|
+
Restart Pi after installation so the Web UI commands are loaded.
|
|
51
26
|
|
|
52
|
-
|
|
27
|
+
## Start from Pi
|
|
53
28
|
|
|
54
|
-
|
|
29
|
+
Run this inside Pi:
|
|
55
30
|
|
|
56
|
-
```
|
|
57
|
-
|
|
31
|
+
```text
|
|
32
|
+
/webui-start
|
|
58
33
|
```
|
|
59
34
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
./start-webui.sh --dev --cwd /path/to/project
|
|
64
|
-
```
|
|
35
|
+
Open the printed URL, usually <http://127.0.0.1:31415/>. The command opens your browser automatically unless you pass `--no-open`.
|
|
65
36
|
|
|
66
|
-
|
|
37
|
+
Check a running Web UI with:
|
|
67
38
|
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
|
|
39
|
+
```text
|
|
40
|
+
/webui-status
|
|
41
|
+
/webui-status detailed
|
|
71
42
|
```
|
|
72
43
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Local browser chat over Pi RPC with isolated terminal tabs; each tab has its own `pi --mode rpc` subprocess, event stream, session state, prompt draft, cwd, and activity indicator.
|
|
76
|
-
- Automatic tab naming from the first prompt on default-named tabs, plus `/name <title>` to manually sync the Pi session and browser tab name.
|
|
77
|
-
- Live transcript with streamed assistant text/thinking, Markdown output, active-run status, tool/bash cards, queue/compaction events, jump-to-latest, sticky last-prompt navigation, and abort by button, Esc, or long press.
|
|
78
|
-
- Prompt composer for prompts, steer/follow-up, busy-session behavior, model/thinking controls, manual compact/new session, uploads by button/drag/drop/paste, slash-command autocomplete, and `@` file/path references with live suggestions.
|
|
79
|
-
- Browser-native selector dialogs for `/model`, `/settings`, `/theme`, `/fork`, `/clone`, `/resume`, `/tree`, and `/scoped-models`; `/login`/`/logout` show non-secret guidance instead of accepting credentials in the browser.
|
|
80
|
-
- Native TUI parity tracking through `WEBUI_TUI_NATIVE_PARITY.json`, used as the source of truth for native command discovery and exposed at `GET /api/native-parity`.
|
|
81
|
-
- Initial `/export` parity: `/export` creates an HTML browser download through a short-lived opaque token, while explicit new `.html`/`.jsonl` paths write server-side from localhost only.
|
|
82
|
-
- Initial `!` / `!!` bash parity: leading `!cmd` runs queued RPC bash and includes output in the next LLM context; `!!cmd` runs with `excludeFromContext`; the active bash can be aborted from the Web UI.
|
|
83
|
-
- Initial native shortcut parity for Ctrl/Cmd+L model selector, Ctrl/Cmd+P and Shift+Ctrl/Cmd+P model cycling, Shift+Tab thinking cycling, Ctrl/Cmd+T thinking visibility, Ctrl/Cmd+O tool/bash expansion, Alt+Enter follow-up, degraded Alt+Up queue restore, and Ctrl/Cmd+C prompt clear when no text is selected.
|
|
84
|
-
- Session/workspace helpers for per-tab cwd changes, a clickable footer cwd picker with server-persisted fast picks, fork/clone/resume/tree navigation, and restart-safe restoration of currently open tabs.
|
|
85
|
-
- Collapsible side-panel control deck for model/thinking/settings, optional features, Codex usage, session/queue/commands/events, local-network exposure, browser notifications, and Web UI themes/custom backgrounds.
|
|
86
|
-
- Pi-style footer with token/cache/context/cost/speed telemetry, estimated Pi-context tokens, cwd/git/runtime/model/thinking metadata, and a scoped-model picker.
|
|
87
|
-
- Optional companion management with capability-based enabled/disabled/install-needed status, localhost-only warned installs, Side-panel theme picker backed by optional `@firstpick/pi-themes-bundle` themes when loaded, guided Git commit/push workflow, NPM/AUR Publish menu, todo-progress rendering, and richer git/status/stats widgets.
|
|
88
|
-
- Extension UI bridge for `notify`, `setStatus`, `setWidget`, `setTitle`, `set_editor_text`, `select`, `confirm`, `input`, and `editor`, with browser notifications when a tab needs an extension UI response and an optional side-panel toggle for agent-done notifications.
|
|
89
|
-
- Feedback reactions (`👍`, `👎`, `?`) on final assistant output plus tool/bash action cards, with queued post-run submission that asks Pi to create/update a LEARNING.
|
|
90
|
-
- Mobile/PWA support: installable app shell, service worker/icons, backend-offline recovery panel, touch-friendly composer/tabs/footer, and a static frontend with no bundler or frontend install step.
|
|
91
|
-
|
|
92
|
-
## Mobile/PWA notes
|
|
93
|
-
|
|
94
|
-
- The mobile composer starts as a one-line `Ask Pi…` input, grows with user-entered lines, and scrolls the transcript to the latest output when focused.
|
|
95
|
-
- When Pi is idle, `Steer` and `Follow-up` live inside `Actions`; while a run is active, they move back into the main composer row for quick steering/follow-up.
|
|
96
|
-
- PWA install support, blocked-tab browser notifications, and optional agent-done notifications require browser service-worker/notification support and usually HTTPS or `localhost`. Plain `http://<LAN-IP>` may show the app but may not offer install or notifications on Chrome/Safari.
|
|
97
|
-
|
|
98
|
-
## Pi slash commands
|
|
44
|
+
### `/webui-start` options
|
|
99
45
|
|
|
100
46
|
```text
|
|
101
47
|
/webui-start [port] [options] [-- <pi args...>]
|
|
102
48
|
```
|
|
103
49
|
|
|
104
|
-
Options:
|
|
105
|
-
|
|
106
50
|
```text
|
|
107
|
-
[port]
|
|
51
|
+
[port] Port shortcut
|
|
108
52
|
--host <host> HTTP bind host (default: 127.0.0.1)
|
|
109
53
|
--port <port> HTTP port (default: 31415)
|
|
110
54
|
--no-open Do not open the browser automatically
|
|
111
55
|
--no-session Start Pi RPC with --no-session
|
|
112
|
-
--name <name> Initial Web UI tab
|
|
56
|
+
--name <name> Initial Web UI tab name
|
|
113
57
|
-- <pi args...> Extra arguments forwarded to Pi RPC
|
|
114
58
|
```
|
|
115
59
|
|
|
@@ -122,33 +66,36 @@ Examples:
|
|
|
122
66
|
/webui-start --name browser -- --model anthropic/claude-sonnet-4-5:high
|
|
123
67
|
```
|
|
124
68
|
|
|
125
|
-
|
|
69
|
+
Running `/webui-start` again on the same URL restarts the server and restores currently open Web UI tabs from their session files when possible.
|
|
126
70
|
|
|
127
|
-
|
|
71
|
+
### `/webui-status` options
|
|
128
72
|
|
|
129
73
|
```text
|
|
130
|
-
/webui-status
|
|
131
|
-
/webui-status detailed
|
|
132
|
-
/webui-status detailed --port 31500
|
|
74
|
+
/webui-status [detailed] [port] [--port N] [--host HOST]
|
|
133
75
|
```
|
|
134
76
|
|
|
135
|
-
`/webui-status` reports the
|
|
77
|
+
`/webui-status` reports the URL, online state, and network exposure. `detailed` adds tabs, sessions, models/providers, and recent backend events.
|
|
136
78
|
|
|
137
|
-
## CLI
|
|
79
|
+
## Standalone CLI
|
|
80
|
+
|
|
81
|
+
Use the CLI when you want to start the Web UI without first opening terminal Pi:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npm install -g @firstpick/pi-package-webui
|
|
85
|
+
pi-webui --cwd ~/src/my-project
|
|
86
|
+
```
|
|
138
87
|
|
|
139
88
|
```text
|
|
140
89
|
pi-webui [options] [-- <pi args...>]
|
|
141
90
|
```
|
|
142
91
|
|
|
143
|
-
Options:
|
|
144
|
-
|
|
145
92
|
```text
|
|
146
93
|
--host <host> HTTP bind host (default: 127.0.0.1)
|
|
147
94
|
--port <port> HTTP port (default: 31415)
|
|
148
95
|
--cwd <path> Default working directory for Pi tabs (default: current dir)
|
|
149
96
|
--pi <command> Pi executable to spawn (default: bundled dependency, then "pi")
|
|
150
97
|
--no-session Start Pi RPC with --no-session
|
|
151
|
-
--name <name> Initial Web UI tab
|
|
98
|
+
--name <name> Initial Web UI tab name
|
|
152
99
|
-h, --help Show help
|
|
153
100
|
-v, --version Print version
|
|
154
101
|
```
|
|
@@ -165,66 +112,63 @@ Environment variables:
|
|
|
165
112
|
|
|
166
113
|
- `PI_WEBUI_HOST`
|
|
167
114
|
- `PI_WEBUI_PORT`
|
|
168
|
-
- `PI_WEBUI_PI_BIN`
|
|
115
|
+
- `PI_WEBUI_PI_BIN`
|
|
169
116
|
|
|
170
|
-
##
|
|
117
|
+
## Main features
|
|
171
118
|
|
|
172
|
-
|
|
119
|
+
- Multi-tab Pi sessions with isolated processes, working directories, prompt drafts, and activity state.
|
|
120
|
+
- Streaming chat transcript with Markdown, thinking output, tool/bash cards, queue and compaction events, and abort controls.
|
|
121
|
+
- Prompt composer with uploads, drag/drop/paste, inline image support, slash-command autocomplete, and `@` file/path references.
|
|
122
|
+
- Browser dialogs for common Pi selectors such as `/model`, `/settings`, `/theme`, `/fork`, `/clone`, `/resume`, `/tree`, and `/scoped-models`.
|
|
123
|
+
- Model, thinking, session, workspace, theme, optional-feature, Codex usage, network, event, and notification controls in the side panel.
|
|
124
|
+
- Per-tab cwd changes, a clickable footer cwd picker, saved path fast picks, and restart-safe restoration of open tabs.
|
|
125
|
+
- Browser support for Pi extension UI prompts, widgets, status updates, and notifications.
|
|
126
|
+
- Feedback reactions (`👍`, `👎`, `?`) on assistant output and action cards, which can ask Pi to create or update a LEARNING.
|
|
127
|
+
- Mobile-friendly layout and PWA install support where the browser allows it.
|
|
173
128
|
|
|
174
|
-
|
|
175
|
-
2. Send `/git-staged-msg` to Pi.
|
|
176
|
-
3. Read `dev/COMMIT/staged-commit-short.txt` and `dev/COMMIT/staged-commit-long.txt` from the git root.
|
|
177
|
-
4. Commit with either the short message (`git commit -m ...`) or the long message (`git commit -F ...`).
|
|
178
|
-
5. Run `git push`.
|
|
129
|
+
## Optional companion features
|
|
179
130
|
|
|
180
|
-
|
|
131
|
+
A normal Pi/npm install includes the optional companion packages unless optional dependencies are disabled. If a feature is missing, the side panel shows it as install-needed. Installing from the side panel is localhost-only, limited to known packages, and requires reloading the active Pi tab after installation.
|
|
181
132
|
|
|
182
|
-
|
|
133
|
+
Optional companions:
|
|
183
134
|
|
|
184
|
-
|
|
135
|
+
- `@firstpick/pi-prompts-git-pr` — guided Git commit/push workflow.
|
|
136
|
+
- `@firstpick/pi-extension-release-npm` — NPM publish menu and release widgets.
|
|
137
|
+
- `@firstpick/pi-extension-release-aur` — AUR publish menu and release widgets.
|
|
138
|
+
- `@firstpick/pi-extension-todo-progress` — todo-progress rendering.
|
|
139
|
+
- `@firstpick/pi-extension-git-footer-status` — richer git/footer status.
|
|
140
|
+
- `@firstpick/pi-extension-stats` — stats commands and status data.
|
|
141
|
+
- `@firstpick/pi-themes-bundle` — Web UI and Pi theme resources.
|
|
185
142
|
|
|
186
|
-
|
|
187
|
-
pi --mode rpc
|
|
188
|
-
```
|
|
143
|
+
## Guided Git workflow
|
|
189
144
|
|
|
190
|
-
|
|
145
|
+
The Git workflow button runs local git commands in the active Pi working directory:
|
|
191
146
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
147
|
+
1. `git add .`
|
|
148
|
+
2. Send `/git-staged-msg` to Pi
|
|
149
|
+
3. Read the generated commit message files from `dev/COMMIT/`
|
|
150
|
+
4. Commit with the selected message
|
|
151
|
+
5. Run `git push`
|
|
195
152
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
-
|
|
201
|
-
-
|
|
202
|
-
- `
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
- `POST /api/attachments` for browser-selected, pasted, or dropped files; files are stored under the OS temp directory and referenced in the prompt, while supported images can also be sent inline via RPC `images`
|
|
206
|
-
- `GET /api/themes` for optional theme data from `@firstpick/pi-themes-bundle` when available
|
|
207
|
-
- `GET /api/native-parity` for the machine-readable native TUI parity matrix that drives native command discovery
|
|
208
|
-
- `GET /api/native-download/<token>` for short-lived opaque native command artifacts such as browser `/export` downloads
|
|
209
|
-
- `GET /api/fork-messages`, `POST /api/fork`, `POST /api/clone`, `GET /api/sessions`, `POST /api/switch-session`, `GET /api/session-tree`, and `POST /api/tree-navigate` for browser-native native slash selectors
|
|
210
|
-
- localhost-only `POST /api/optional-feature-install` for explicit, warned installation of whitelisted optional feature packages
|
|
211
|
-
- `GET /api/network` and localhost-only `POST /api/network/open` for local-network exposure status/control
|
|
212
|
-
- `GET /api/webui-status?detailed=1` for slash-command status reporting
|
|
213
|
-
- `POST /api/shutdown` for localhost-only graceful restarts from `/webui-start`; restart captures detailed open-tab status first so currently open tabs can be restored with their session files
|
|
214
|
-
- HTTP endpoints for prompt/session/model/thinking/compact/git actions; tab-scoped calls use `?tab=<tabId>`
|
|
215
|
-
- `POST /api/bash?tab=<tabId>` and `POST /api/abort-bash?tab=<tabId>` for leading `!` / `!!` user bash parity with server-side one-active-per-tab FIFO queuing
|
|
216
|
-
- `POST /api/model-cycle?tab=<tabId>` and `POST /api/thinking-cycle?tab=<tabId>` for native shortcut model/thinking cycling
|
|
217
|
-
- `POST /api/action-feedback?tab=<tabId>` to turn queued action/final-output reactions into a Pi prompt that creates/updates a LEARNING after the run is idle
|
|
218
|
-
- `/api/events?tab=<tabId>` as a per-tab Server-Sent Events stream for Pi RPC events
|
|
219
|
-
- `/api/extension-ui-response?tab=<tabId>` for browser responses to extension UI prompts
|
|
220
|
-
|
|
221
|
-
Pi stdout is read as JSONL and split only on `\n`, matching Pi RPC framing.
|
|
222
|
-
|
|
223
|
-
## Network and safety notes
|
|
153
|
+
This requires `/git-staged-msg` from `@firstpick/pi-prompts-git-pr`. Review the generated commit message before committing or pushing.
|
|
154
|
+
|
|
155
|
+
## Mobile and PWA notes
|
|
156
|
+
|
|
157
|
+
- The mobile composer starts as a compact `Ask Pi…` input and grows as you type.
|
|
158
|
+
- Installable PWA support and notifications depend on browser support and usually require `localhost` or HTTPS.
|
|
159
|
+
- Plain `http://<LAN-IP>` can show the app, but some browsers disable PWA install and notifications there.
|
|
160
|
+
|
|
161
|
+
## Network safety
|
|
224
162
|
|
|
225
163
|
- Default bind is localhost-only: `127.0.0.1:31415`.
|
|
226
|
-
- The side-panel
|
|
227
|
-
- `--host 0.0.0.0` also
|
|
228
|
-
-
|
|
229
|
-
-
|
|
230
|
-
|
|
164
|
+
- The side-panel **Open to network** button rebinds the server to `0.0.0.0` and shows LAN URLs when available.
|
|
165
|
+
- `--host 0.0.0.0` also exposes the Web UI to the local network.
|
|
166
|
+
- Any connected browser client can control Pi and run Web UI bash actions as the Web UI process user.
|
|
167
|
+
- Treat Pi Web UI as a local companion, not a hardened multi-user web service.
|
|
168
|
+
|
|
169
|
+
## Troubleshooting
|
|
170
|
+
|
|
171
|
+
- **`/webui-start` is missing:** restart Pi after installing the package.
|
|
172
|
+
- **Wrong port or existing server:** use `/webui-status detailed`, or start on another port with `/webui-start --port 31500`.
|
|
173
|
+
- **Optional feature is disabled or missing:** check the side panel, install the companion package if needed, then run `/reload` in the active Pi tab.
|
|
174
|
+
- **PWA install or notifications are unavailable:** use `localhost` or HTTPS; browser support varies on LAN HTTP URLs.
|
package/package.json
CHANGED
package/start-webui.ps1
CHANGED
|
@@ -32,7 +32,52 @@ function Get-LaunchCwd {
|
|
|
32
32
|
return $cwd
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function Get-PiManagedPiWebui {
|
|
36
|
+
$node = Get-Command "node" -ErrorAction SilentlyContinue
|
|
37
|
+
if (-not $node) {
|
|
38
|
+
return $null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
$script = @'
|
|
42
|
+
const { homedir } = require("node:os");
|
|
43
|
+
const { join } = require("node:path");
|
|
44
|
+
|
|
45
|
+
let agentDir = process.env.PI_CODING_AGENT_DIR || join(homedir(), ".pi", "agent");
|
|
46
|
+
if (agentDir === "~") {
|
|
47
|
+
agentDir = homedir();
|
|
48
|
+
} else if (agentDir.startsWith("~/") || (process.platform === "win32" && agentDir.startsWith("~\\"))) {
|
|
49
|
+
agentDir = join(homedir(), agentDir.slice(2));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const binName = process.platform === "win32" ? "pi-webui.cmd" : "pi-webui";
|
|
53
|
+
for (const candidate of [
|
|
54
|
+
join(agentDir, "npm", "node_modules", ".bin", binName),
|
|
55
|
+
join(agentDir, "npm", "node_modules", ".bin", "pi-webui"),
|
|
56
|
+
]) {
|
|
57
|
+
process.stdout.write(`${candidate}\n`);
|
|
58
|
+
}
|
|
59
|
+
'@
|
|
60
|
+
|
|
61
|
+
$candidates = @(& $node.Source -e $script 2>$null)
|
|
62
|
+
if ($LASTEXITCODE -ne 0) {
|
|
63
|
+
return $null
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
foreach ($candidate in $candidates) {
|
|
67
|
+
if (-not [string]::IsNullOrWhiteSpace($candidate) -and (Test-Path -LiteralPath $candidate -PathType Leaf)) {
|
|
68
|
+
return $candidate
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return $null
|
|
73
|
+
}
|
|
74
|
+
|
|
35
75
|
function Ensure-PiWebui {
|
|
76
|
+
$managed = Get-PiManagedPiWebui
|
|
77
|
+
if ($managed) {
|
|
78
|
+
return $managed
|
|
79
|
+
}
|
|
80
|
+
|
|
36
81
|
$command = Get-Command "pi-webui" -ErrorAction SilentlyContinue
|
|
37
82
|
if ($command) {
|
|
38
83
|
return $command.Source
|
package/start-webui.sh
CHANGED
|
@@ -6,6 +6,7 @@ PACKAGE_NAME="@firstpick/pi-package-webui"
|
|
|
6
6
|
DEFAULT_HOST="127.0.0.1"
|
|
7
7
|
DEFAULT_PORT="31415"
|
|
8
8
|
SERVER_PID=""
|
|
9
|
+
PI_WEBUI_COMMAND=""
|
|
9
10
|
|
|
10
11
|
script_dir() {
|
|
11
12
|
local source dir
|
|
@@ -37,6 +38,44 @@ local_pi_webui_bin() {
|
|
|
37
38
|
printf '%s\n' "$candidate"
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
pi_managed_pi_webui_bin() {
|
|
42
|
+
local candidates candidate
|
|
43
|
+
|
|
44
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
45
|
+
return 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
candidates="$(node <<'NODE'
|
|
49
|
+
const { homedir } = require("node:os");
|
|
50
|
+
const { join } = require("node:path");
|
|
51
|
+
|
|
52
|
+
let agentDir = process.env.PI_CODING_AGENT_DIR || join(homedir(), ".pi", "agent");
|
|
53
|
+
if (agentDir === "~") {
|
|
54
|
+
agentDir = homedir();
|
|
55
|
+
} else if (agentDir.startsWith("~/") || (process.platform === "win32" && agentDir.startsWith("~\\"))) {
|
|
56
|
+
agentDir = join(homedir(), agentDir.slice(2));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const binName = process.platform === "win32" ? "pi-webui.cmd" : "pi-webui";
|
|
60
|
+
for (const candidate of [
|
|
61
|
+
join(agentDir, "npm", "node_modules", ".bin", "pi-webui"),
|
|
62
|
+
join(agentDir, "npm", "node_modules", ".bin", binName),
|
|
63
|
+
]) {
|
|
64
|
+
process.stdout.write(`${candidate.replace(/\\/g, "/")}\n`);
|
|
65
|
+
}
|
|
66
|
+
NODE
|
|
67
|
+
)"
|
|
68
|
+
|
|
69
|
+
while IFS= read -r candidate; do
|
|
70
|
+
if [[ -n "$candidate" && -f "$candidate" ]]; then
|
|
71
|
+
printf '%s\n' "$candidate"
|
|
72
|
+
return 0
|
|
73
|
+
fi
|
|
74
|
+
done <<< "$candidates"
|
|
75
|
+
|
|
76
|
+
return 1
|
|
77
|
+
}
|
|
78
|
+
|
|
40
79
|
cleanup() {
|
|
41
80
|
if [[ -n "${SERVER_PID:-}" ]] && kill -0 "$SERVER_PID" 2>/dev/null; then
|
|
42
81
|
kill "$SERVER_PID" 2>/dev/null || true
|
|
@@ -66,7 +105,15 @@ choose_cwd() {
|
|
|
66
105
|
}
|
|
67
106
|
|
|
68
107
|
ensure_pi_webui() {
|
|
108
|
+
local managed_bin
|
|
109
|
+
|
|
110
|
+
if managed_bin="$(pi_managed_pi_webui_bin 2>/dev/null)" && [[ -n "$managed_bin" ]]; then
|
|
111
|
+
PI_WEBUI_COMMAND="$managed_bin"
|
|
112
|
+
return 0
|
|
113
|
+
fi
|
|
114
|
+
|
|
69
115
|
if command -v pi-webui >/dev/null 2>&1; then
|
|
116
|
+
PI_WEBUI_COMMAND="$(command -v pi-webui)"
|
|
70
117
|
return 0
|
|
71
118
|
fi
|
|
72
119
|
|
|
@@ -105,6 +152,8 @@ ensure_pi_webui() {
|
|
|
105
152
|
echo "Installed, but pi-webui is still not on PATH. Check your npm global bin directory." >&2
|
|
106
153
|
return 1
|
|
107
154
|
fi
|
|
155
|
+
|
|
156
|
+
PI_WEBUI_COMMAND="$(command -v pi-webui)"
|
|
108
157
|
}
|
|
109
158
|
|
|
110
159
|
browser_host_for_url() {
|
|
@@ -428,7 +477,7 @@ main() {
|
|
|
428
477
|
echo "Dev mode: using local Pi Web UI server: $local_webui_bin"
|
|
429
478
|
else
|
|
430
479
|
ensure_pi_webui
|
|
431
|
-
webui_cmd=(
|
|
480
|
+
webui_cmd=("$PI_WEBUI_COMMAND")
|
|
432
481
|
fi
|
|
433
482
|
|
|
434
483
|
echo "Starting Pi Web UI in: $cwd"
|