pi-web-ui 0.2.13 → 0.2.15
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
CHANGED
|
@@ -140,8 +140,10 @@ pi-web-ui server uninstall # remove the service entirely
|
|
|
140
140
|
`/etc/systemd/system/pi-web-ui.service` and runs `systemctl enable --now`,
|
|
141
141
|
logs via `journalctl -u pi-web-ui -f`.
|
|
142
142
|
- **Windows** → Task Scheduler (no admin): creates a user task that starts at
|
|
143
|
-
logon (same as a launchd agent). It runs a
|
|
144
|
-
`%APPDATA%\pi-web-ui\pi-web-ui.
|
|
143
|
+
logon (same as a launchd agent). It runs a PowerShell launcher generated at
|
|
144
|
+
`%APPDATA%\pi-web-ui\pi-web-ui.ps1` via `powershell.exe -WindowStyle
|
|
145
|
+
Hidden` — no black console window stays open, so there's nothing to
|
|
146
|
+
accidentally close/kill. The launcher sets env, cd's to the workspace,
|
|
145
147
|
launches node, appends logs to `%USERPROFILE%\pi-web-ui.log`). The task XML
|
|
146
148
|
is saved next to it; restarts on failure.
|
|
147
149
|
- Options: `--port` (default 8787 or `$PORT`), `--cwd` (default `$PI_WEB_CWD`
|
|
@@ -336,12 +338,14 @@ pi-web-ui server stop :: stop the running instance (auto-start stays)
|
|
|
336
338
|
pi-web-ui server uninstall :: remove the task entirely
|
|
337
339
|
```
|
|
338
340
|
|
|
339
|
-
What it does: writes `%APPDATA%\pi-web-ui\pi-web-ui.
|
|
341
|
+
What it does: writes `%APPDATA%\pi-web-ui\pi-web-ui.ps1` (a PowerShell launcher
|
|
340
342
|
that sets `PORT`/`PI_WEB_CWD`, cd's to the workspace, launches node and
|
|
341
343
|
appends output to `%USERPROFILE%\pi-web-ui.log`) plus the Task Scheduler XML,
|
|
342
344
|
then registers a **logon** task (`schtasks /Create /XML` — the task runs when
|
|
343
|
-
you log in, same as a launchd agent; no admin needed).
|
|
344
|
-
|
|
345
|
+
you log in, same as a launchd agent; no admin needed). The task invokes
|
|
346
|
+
`powershell.exe -WindowStyle Hidden`, so the server runs with **no black
|
|
347
|
+
console window** — there is nothing to accidentally close or kill. Preview
|
|
348
|
+
both generated files without installing: `pi-web-ui server install --print`.
|
|
345
349
|
|
|
346
350
|
Manual alternative with `deploy/pi-web-ui-task.xml`: edit the paths, save the
|
|
347
351
|
file as **UTF-16 LE** (schtasks requires it), then
|
package/bin/pi-web-ui.mjs
CHANGED
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* (--name 自定义时 com.<name>.server),无需 sudo
|
|
15
15
|
* - Linux → systemd 单元 <name>.service(/etc/systemd/system/,自动 sudo)
|
|
16
16
|
* - Windows → 计划任务(Task Scheduler / schtasks,登录后自启,无需管理员),
|
|
17
|
-
*
|
|
17
|
+
* 隐藏窗口启动(无黑窗);PowerShell 启动脚本与任务 XML 生成在
|
|
18
|
+
* %APPDATA%\pi-web-ui\
|
|
18
19
|
*
|
|
19
20
|
* 环境变量(前台与系统服务均适用):PORT / PI_WEB_CWD / PI_WEB_DATA_DIR /
|
|
20
21
|
* PI_CODING_AGENT_DIR。
|
|
@@ -62,7 +63,7 @@ server 选项:
|
|
|
62
63
|
--print 只打印将生成的配置文件,不实际安装
|
|
63
64
|
|
|
64
65
|
平台: macOS → launchd 用户代理 · Linux → systemd · Windows → 计划任务(schtasks)
|
|
65
|
-
(Windows
|
|
66
|
+
(Windows 任务登录后自启、无需管理员、隐藏窗口运行;stop 停止,uninstall 移除)
|
|
66
67
|
|
|
67
68
|
环境变量(前台与系统服务均适用):
|
|
68
69
|
PORT / PI_WEB_CWD / PI_WEB_DATA_DIR / PI_CODING_AGENT_DIR
|
|
@@ -214,6 +215,10 @@ function winCmdPath(name) {
|
|
|
214
215
|
return join(winServiceDir(), `${name}.cmd`);
|
|
215
216
|
}
|
|
216
217
|
|
|
218
|
+
function winPs1Path(name) {
|
|
219
|
+
return join(winServiceDir(), `${name}.ps1`);
|
|
220
|
+
}
|
|
221
|
+
|
|
217
222
|
function winTaskXmlPath(name) {
|
|
218
223
|
return join(winServiceDir(), `${name}.xml`);
|
|
219
224
|
}
|
|
@@ -230,17 +235,30 @@ function winTaskExists(name) {
|
|
|
230
235
|
);
|
|
231
236
|
}
|
|
232
237
|
|
|
233
|
-
/**
|
|
234
|
-
function
|
|
238
|
+
/** Single-quote a string for embedding in a generated PowerShell script. */
|
|
239
|
+
function psQuote(s) {
|
|
240
|
+
return "'" + s.replace(/'/g, "''") + "'";
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Build the PowerShell launcher the scheduled task runs. Task Scheduler
|
|
245
|
+
* launches it with -WindowStyle Hidden, so the console window is created
|
|
246
|
+
* hidden (SW_HIDE) — no black cmd window stays open while the server runs,
|
|
247
|
+
* and there is nothing to accidentally close/kill. The script sets the env,
|
|
248
|
+
* cd's to the workspace, then runs node in the foreground with output
|
|
249
|
+
* appended to the log, so the task instance IS the powershell process and
|
|
250
|
+
* `schtasks /End` still stops the whole tree.
|
|
251
|
+
*/
|
|
252
|
+
function buildWinStartPs1(env, cwd, logPath) {
|
|
235
253
|
const sets = Object.entries(env)
|
|
236
|
-
.map(([k, v]) =>
|
|
254
|
+
.map(([k, v]) => `$env:${k} = ${psQuote(v)}`)
|
|
237
255
|
.join("\r\n");
|
|
238
256
|
return [
|
|
239
|
-
"
|
|
240
|
-
"
|
|
257
|
+
"# Generated by: pi-web-ui server install (rerun to change)",
|
|
258
|
+
"# Starts the server with a hidden console window (no black cmd box).",
|
|
241
259
|
sets,
|
|
242
|
-
`
|
|
243
|
-
|
|
260
|
+
`Set-Location ${psQuote(cwd)}`,
|
|
261
|
+
`& ${psQuote(NODE)} ${psQuote(SERVER_ENTRY)} *>> ${psQuote(logPath)}`,
|
|
244
262
|
"",
|
|
245
263
|
].join("\r\n");
|
|
246
264
|
}
|
|
@@ -248,13 +266,16 @@ function buildWinCmd(cwd, env, logPath) {
|
|
|
248
266
|
/**
|
|
249
267
|
* Build the Task Scheduler XML for a user task: LogonTrigger (starts at logon,
|
|
250
268
|
* like a launchd agent — no admin needed), InteractiveToken, auto-restart on
|
|
251
|
-
* failure. The task runs the
|
|
269
|
+
* failure. The task runs the PowerShell launcher via
|
|
270
|
+
* powershell.exe -WindowStyle Hidden, so no console window ever appears.
|
|
252
271
|
*/
|
|
253
|
-
function buildWinTaskXml(
|
|
254
|
-
const
|
|
272
|
+
function buildWinTaskXml(ps1Path, cwd) {
|
|
273
|
+
const powershell = join(
|
|
255
274
|
process.env.SystemRoot ?? "C:\\Windows",
|
|
256
275
|
"System32",
|
|
257
|
-
"
|
|
276
|
+
"WindowsPowerShell",
|
|
277
|
+
"v1.0",
|
|
278
|
+
"powershell.exe",
|
|
258
279
|
);
|
|
259
280
|
return `<?xml version="1.0" encoding="UTF-16"?>
|
|
260
281
|
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
|
|
@@ -297,8 +318,8 @@ function buildWinTaskXml(cmdPath, cwd) {
|
|
|
297
318
|
</Settings>
|
|
298
319
|
<Actions Context="Author">
|
|
299
320
|
<Exec>
|
|
300
|
-
<Command>${esc(
|
|
301
|
-
<Arguments
|
|
321
|
+
<Command>${esc(powershell)}</Command>
|
|
322
|
+
<Arguments>-NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "${esc(ps1Path)}"</Arguments>
|
|
302
323
|
<WorkingDirectory>${esc(cwd)}</WorkingDirectory>
|
|
303
324
|
</Exec>
|
|
304
325
|
</Actions>
|
|
@@ -502,17 +523,20 @@ function uninstallSystemd(opts) {
|
|
|
502
523
|
function installWindows(opts) {
|
|
503
524
|
const { name, port, cwd, dataDir } = serviceOptions(opts);
|
|
504
525
|
const env = serviceEnv(port, cwd, dataDir);
|
|
505
|
-
const
|
|
526
|
+
const ps1Path = winPs1Path(name);
|
|
506
527
|
const xmlPath = winTaskXmlPath(name);
|
|
507
|
-
const
|
|
508
|
-
const xml = buildWinTaskXml(
|
|
528
|
+
const ps1 = buildWinStartPs1(env, cwd, winLogPath());
|
|
529
|
+
const xml = buildWinTaskXml(ps1Path, cwd);
|
|
509
530
|
if (opts.print) {
|
|
510
|
-
console.log(`# ${
|
|
531
|
+
console.log(`# ${ps1Path}\n${ps1}`);
|
|
511
532
|
console.log(`# ${xmlPath}\n${xml}`);
|
|
512
533
|
return;
|
|
513
534
|
}
|
|
514
|
-
mkdirSync(dirname(
|
|
515
|
-
|
|
535
|
+
mkdirSync(dirname(ps1Path), { recursive: true });
|
|
536
|
+
// UTF-8 with BOM: Windows PowerShell 5.1 misreads BOM-less UTF-8 as ANSI.
|
|
537
|
+
writeFileSync(ps1Path, "\uFEFF" + ps1, "utf8");
|
|
538
|
+
// Remove the old-style .cmd wrapper from previous installs.
|
|
539
|
+
if (existsSync(winCmdPath(name))) rmSync(winCmdPath(name));
|
|
516
540
|
// schtasks /Create /XML requires a UTF-16 file (with BOM).
|
|
517
541
|
writeFileSync(xmlPath, "\uFEFF" + xml, "utf16le");
|
|
518
542
|
if (winTaskExists(name)) {
|
|
@@ -523,7 +547,7 @@ function installWindows(opts) {
|
|
|
523
547
|
}
|
|
524
548
|
run("schtasks", ["/Create", "/TN", name, "/XML", xmlPath, "/F"]);
|
|
525
549
|
run("schtasks", ["/Run", "/TN", name], { ignoreError: true });
|
|
526
|
-
console.log(`✅ 已安装并启动计划任务 ${name}
|
|
550
|
+
console.log(`✅ 已安装并启动计划任务 ${name}(隐藏窗口运行,无黑窗)`);
|
|
527
551
|
console.log(` 端口 : ${port}`);
|
|
528
552
|
console.log(` 目录 : ${cwd}`);
|
|
529
553
|
console.log(` 访问 : http://localhost:${port}`);
|
|
@@ -539,7 +563,7 @@ function uninstallWindows(opts) {
|
|
|
539
563
|
if (winTaskExists(name)) {
|
|
540
564
|
run("schtasks", ["/Delete", "/TN", name, "/F"], { ignoreError: true });
|
|
541
565
|
}
|
|
542
|
-
for (const f of [winCmdPath(name), winTaskXmlPath(name)]) {
|
|
566
|
+
for (const f of [winCmdPath(name), winPs1Path(name), winTaskXmlPath(name)]) {
|
|
543
567
|
if (existsSync(f)) rmSync(f);
|
|
544
568
|
}
|
|
545
569
|
console.log(`🗑 已卸载 ${name}(计划任务已删除,不再自启)`);
|
|
@@ -12,9 +12,11 @@
|
|
|
12
12
|
schtasks /Run /TN "pi-web-ui"
|
|
13
13
|
|
|
14
14
|
Notes:
|
|
15
|
-
- The task
|
|
16
|
-
%APPDATA%\pi-web-ui\pi-web-ui.
|
|
17
|
-
|
|
15
|
+
- The task runs the PowerShell launcher the CLI generates at
|
|
16
|
+
%APPDATA%\pi-web-ui\pi-web-ui.ps1 with -WindowStyle Hidden, so the
|
|
17
|
+
server runs with no black console window (nothing to accidentally
|
|
18
|
+
close/kill). The ps1 sets PORT/PI_WEB_CWD, cd's to the workspace,
|
|
19
|
+
launches node, and appends output to %USERPROFILE%\pi-web-ui.log.
|
|
18
20
|
Preview both generated files with: pi-web-ui server install --print
|
|
19
21
|
- Save this file as UTF-16 LE (schtasks requires it; the CLI does this
|
|
20
22
|
automatically when it writes the task XML).
|
|
@@ -61,8 +63,8 @@
|
|
|
61
63
|
</Settings>
|
|
62
64
|
<Actions Context="Author">
|
|
63
65
|
<Exec>
|
|
64
|
-
<Command>C:\Windows\System32\
|
|
65
|
-
<Arguments
|
|
66
|
+
<Command>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</Command>
|
|
67
|
+
<Arguments>-NoProfile -NonInteractive -ExecutionPolicy Bypass -WindowStyle Hidden -File "%APPDATA%\pi-web-ui\pi-web-ui.ps1"</Arguments>
|
|
66
68
|
<WorkingDirectory>%USERPROFILE%</WorkingDirectory>
|
|
67
69
|
</Exec>
|
|
68
70
|
</Actions>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-web-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.15",
|
|
4
4
|
"description": "Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, Docker/systemd/launchd deployable",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|