pi-launcher: macOS/Windows desktop launcher for @agegr/pi-web

按需启动 pi-web 本地 Web UI(端口 30141,URL http://localhost:30141/),
基于 Wails v2 (Go + Vue 3) 构建,逻辑与 dsh-launcher 同构但适配 pi:
- 命令 pi-web、端口 30141、~/.pi/ 凭据
- 接管旧进程(关 app 不留 node 残留)
- 三栏环境检查(Node / pi-web CLI / 端口)

构建:
  macOS:   ./scripts/build-mac.sh
  Windows: scripts\build-windows.bat

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-09-14 16:55:15 +08:00
co-authored by Claude
commit b749b4e0e5
34 changed files with 5060 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
import {main} from '../models';
export function CheckEnv():Promise<main.CheckResult>;
export function CheckUpdate():Promise<main.UpdateInfo>;
export function GetStatus():Promise<main.StatusResult>;
export function HideWindow():Promise<void>;
export function InstallPi():Promise<main.InstallResult>;
export function ShowWindow():Promise<void>;
export function Start():Promise<main.StartResult>;
export function Stop():Promise<main.StartResult>;
export function UpdatePi():Promise<main.InstallResult>;
+39
View File
@@ -0,0 +1,39 @@
// @ts-check
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT
export function CheckEnv() {
return window['go']['main']['App']['CheckEnv']();
}
export function CheckUpdate() {
return window['go']['main']['App']['CheckUpdate']();
}
export function GetStatus() {
return window['go']['main']['App']['GetStatus']();
}
export function HideWindow() {
return window['go']['main']['App']['HideWindow']();
}
export function InstallPi() {
return window['go']['main']['App']['InstallPi']();
}
export function ShowWindow() {
return window['go']['main']['App']['ShowWindow']();
}
export function Start() {
return window['go']['main']['App']['Start']();
}
export function Stop() {
return window['go']['main']['App']['Stop']();
}
export function UpdatePi() {
return window['go']['main']['App']['UpdatePi']();
}
+109
View File
@@ -0,0 +1,109 @@
export namespace main {
export class CheckResult {
nodePath: string;
nodeVersion: string;
nodeOK: boolean;
piPath: string;
piVersion: string;
credFile: string;
credExists: boolean;
homePiDir: string;
portBusy: boolean;
portBusyBy: string;
issues: string[];
static createFrom(source: any = {}) {
return new CheckResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.nodePath = source["nodePath"];
this.nodeVersion = source["nodeVersion"];
this.nodeOK = source["nodeOK"];
this.piPath = source["piPath"];
this.piVersion = source["piVersion"];
this.credFile = source["credFile"];
this.credExists = source["credExists"];
this.homePiDir = source["homePiDir"];
this.portBusy = source["portBusy"];
this.portBusyBy = source["portBusyBy"];
this.issues = source["issues"];
}
}
export class InstallResult {
ok: boolean;
error: string;
output: string;
static createFrom(source: any = {}) {
return new InstallResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ok = source["ok"];
this.error = source["error"];
this.output = source["output"];
}
}
export class StartResult {
ok: boolean;
url: string;
error: string;
output: string;
hidden: boolean;
static createFrom(source: any = {}) {
return new StartResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.ok = source["ok"];
this.url = source["url"];
this.error = source["error"];
this.output = source["output"];
this.hidden = source["hidden"];
}
}
export class StatusResult {
running: boolean;
url: string;
startedAt: string;
pid: number;
static createFrom(source: any = {}) {
return new StatusResult(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.running = source["running"];
this.url = source["url"];
this.startedAt = source["startedAt"];
this.pid = source["pid"];
}
}
export class UpdateInfo {
installed: string;
latest: string;
hasUpdate: boolean;
raw: string;
static createFrom(source: any = {}) {
return new UpdateInfo(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.installed = source["installed"];
this.latest = source["latest"];
this.hasUpdate = source["hasUpdate"];
this.raw = source["raw"];
}
}
}