ai-zero-token 1.0.8 → 1.0.10

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.
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ import { app as electronApp, BrowserWindow, dialog, shell } from "electron";
3
+ import { startServer } from "../server/index.js";
4
+ let gatewayServer = null;
5
+ let mainWindow = null;
6
+ let isQuitting = false;
7
+ function createBrowserUrl(host, port) {
8
+ if (host === "0.0.0.0" || host === "::") {
9
+ return `http://127.0.0.1:${port}`;
10
+ }
11
+ return `http://${host}:${port}`;
12
+ }
13
+ function isGatewayUrl(targetUrl, gatewayUrl) {
14
+ try {
15
+ const target = new URL(targetUrl);
16
+ const gateway = new URL(gatewayUrl);
17
+ return target.origin === gateway.origin;
18
+ } catch {
19
+ return false;
20
+ }
21
+ }
22
+ function resolveAdminUrl(gatewayUrl) {
23
+ const devUrl = process.env.AZT_ADMIN_UI_DEV_URL?.trim();
24
+ return devUrl || gatewayUrl;
25
+ }
26
+ async function ensureGatewayServer() {
27
+ if (gatewayServer) {
28
+ return gatewayServer;
29
+ }
30
+ gatewayServer = await startServer();
31
+ const adminUrl = createBrowserUrl(gatewayServer.host, gatewayServer.port);
32
+ console.log("AI Zero Token desktop gateway started.");
33
+ console.log(`admin: ${adminUrl}`);
34
+ console.log(`apiBase: ${adminUrl}/v1`);
35
+ console.log(`listen: http://${gatewayServer.host}:${gatewayServer.port}`);
36
+ return gatewayServer;
37
+ }
38
+ async function createMainWindow() {
39
+ const server = await ensureGatewayServer();
40
+ const gatewayUrl = createBrowserUrl(server.host, server.port);
41
+ const adminUrl = resolveAdminUrl(gatewayUrl);
42
+ mainWindow = new BrowserWindow({
43
+ width: 1440,
44
+ height: 960,
45
+ minWidth: 1100,
46
+ minHeight: 720,
47
+ title: "AI Zero Token",
48
+ backgroundColor: "#f8fafc",
49
+ webPreferences: {
50
+ contextIsolation: true,
51
+ nodeIntegration: false,
52
+ sandbox: true
53
+ }
54
+ });
55
+ mainWindow.webContents.setWindowOpenHandler(({ url }) => {
56
+ void shell.openExternal(url);
57
+ return { action: "deny" };
58
+ });
59
+ mainWindow.webContents.on("will-navigate", (event, url) => {
60
+ if (isGatewayUrl(url, adminUrl) || isGatewayUrl(url, gatewayUrl)) {
61
+ return;
62
+ }
63
+ event.preventDefault();
64
+ void shell.openExternal(url);
65
+ });
66
+ mainWindow.on("closed", () => {
67
+ mainWindow = null;
68
+ });
69
+ await mainWindow.loadURL(adminUrl);
70
+ }
71
+ function focusMainWindow() {
72
+ if (!mainWindow) {
73
+ void createMainWindow().catch(handleStartupError);
74
+ return;
75
+ }
76
+ if (mainWindow.isMinimized()) {
77
+ mainWindow.restore();
78
+ }
79
+ mainWindow.focus();
80
+ }
81
+ async function closeGatewayServer() {
82
+ if (!gatewayServer) {
83
+ return;
84
+ }
85
+ const server = gatewayServer;
86
+ gatewayServer = null;
87
+ await server.app.close();
88
+ }
89
+ function handleStartupError(error) {
90
+ const message = error instanceof Error ? error.message : String(error);
91
+ console.error("[desktop:error]", error);
92
+ if (electronApp.isReady()) {
93
+ dialog.showErrorBox("AI Zero Token \u542F\u52A8\u5931\u8D25", message);
94
+ }
95
+ electronApp.quit();
96
+ }
97
+ const hasSingleInstanceLock = electronApp.requestSingleInstanceLock();
98
+ if (!hasSingleInstanceLock) {
99
+ electronApp.quit();
100
+ } else {
101
+ electronApp.on("second-instance", () => {
102
+ focusMainWindow();
103
+ });
104
+ electronApp.whenReady().then(createMainWindow).catch(handleStartupError);
105
+ electronApp.on("activate", () => {
106
+ if (BrowserWindow.getAllWindows().length === 0) {
107
+ focusMainWindow();
108
+ }
109
+ });
110
+ electronApp.on("window-all-closed", () => {
111
+ if (process.platform !== "darwin") {
112
+ electronApp.quit();
113
+ }
114
+ });
115
+ electronApp.on("before-quit", (event) => {
116
+ if (!gatewayServer || isQuitting) {
117
+ return;
118
+ }
119
+ event.preventDefault();
120
+ isQuitting = true;
121
+ void closeGatewayServer().catch((error) => {
122
+ console.error("[desktop:gateway:close]", error);
123
+ }).finally(() => {
124
+ electronApp.quit();
125
+ });
126
+ });
127
+ }