@bolloon/bolloon-agent 0.2.0 → 0.2.2
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/dist/agents/judgment-protocol.js +479 -0
- package/dist/agents/pi-sdk.js +269 -1
- package/dist/electron/config.js +9 -14
- package/dist/electron/dialogs.js +16 -53
- package/dist/electron/first-run.js +24 -65
- package/dist/electron/ipc.js +10 -14
- package/dist/electron/logger.js +7 -44
- package/dist/electron/main.js +38 -41
- package/dist/electron/menu.js +13 -18
- package/dist/electron/paths.js +12 -54
- package/dist/electron/server.js +18 -56
- package/dist/electron/tray.js +15 -53
- package/dist/electron/window.js +22 -61
- package/dist/security/tool-gate.js +4 -0
- package/dist/web/client.js +3767 -2873
- package/dist/web/components/p2p/P2PModal.js +188 -0
- package/dist/web/components/p2p/index.js +264 -226
- package/dist/web/components/p2p/p2p-modal.js +657 -0
- package/dist/web/components/p2p/p2p-tools.js +248 -0
- package/dist/web/ui/message-renderer.js +442 -326
- package/dist/web/ui/step-timeline.js +351 -255
- package/ios/App/App/AppDelegate.swift +49 -0
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png +0 -0
- package/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
- package/ios/App/App/Assets.xcassets/Contents.json +6 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +23 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
- package/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
- package/ios/App/App/Base.lproj/LaunchScreen.storyboard +32 -0
- package/ios/App/App/Base.lproj/Main.storyboard +19 -0
- package/ios/App/App/Info.plist +88 -0
- package/ios/App/App.xcodeproj/project.pbxproj +376 -0
- package/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/ios/App/CapApp-SPM/Package.swift +25 -0
- package/ios/App/CapApp-SPM/README.md +5 -0
- package/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift +1 -0
- package/ios/debug.xcconfig +1 -0
- package/package.json +14 -3
- package/scripts/build-app-bundle.cjs +170 -0
- package/.comm/README.md +0 -21
- package/.comm/default/2026-06-17T08-23-00-017Z-8a735de8.md +0 -7
package/dist/electron/logger.js
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.log = log;
|
|
37
1
|
/**
|
|
38
2
|
* 简单 logger: 写日志到 <userData>/logs/bolloon.log, size-based 轮转
|
|
39
3
|
* (5MB 上限, 保留 .1 .2 .3 共 3 个备份 → ~20MB 上限)
|
|
@@ -41,8 +5,8 @@ exports.log = log;
|
|
|
41
5
|
* 同步写是因为 Electron 主进程日志量小, 同步 append 简单可靠, 不丢日志.
|
|
42
6
|
* 量大的会话级 jsonl 走自己路径 (lifecycle-hooks 等), 跟本 logger 无关.
|
|
43
7
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import { mainLogPath, logsDir } from './paths';
|
|
46
10
|
const MAX_BYTES = 5 * 1024 * 1024;
|
|
47
11
|
const MAX_BACKUPS = 3; // 保留 bolloon.log.1 .2 .3
|
|
48
12
|
let currentSize = 0;
|
|
@@ -52,9 +16,9 @@ function ensureLogFile() {
|
|
|
52
16
|
return;
|
|
53
17
|
initialized = true;
|
|
54
18
|
try {
|
|
55
|
-
fs.mkdirSync(
|
|
19
|
+
fs.mkdirSync(logsDir(), { recursive: true });
|
|
56
20
|
try {
|
|
57
|
-
currentSize = fs.statSync(
|
|
21
|
+
currentSize = fs.statSync(mainLogPath()).size;
|
|
58
22
|
}
|
|
59
23
|
catch {
|
|
60
24
|
currentSize = 0;
|
|
@@ -67,7 +31,7 @@ function ensureLogFile() {
|
|
|
67
31
|
}
|
|
68
32
|
}
|
|
69
33
|
function rotate() {
|
|
70
|
-
const logPath =
|
|
34
|
+
const logPath = mainLogPath();
|
|
71
35
|
for (let i = MAX_BACKUPS; i >= 1; i--) {
|
|
72
36
|
const src = `${logPath}.${i}`;
|
|
73
37
|
const dst = `${logPath}.${i + 1}`;
|
|
@@ -90,14 +54,14 @@ function rotate() {
|
|
|
90
54
|
catch { /* missing ok */ }
|
|
91
55
|
currentSize = 0;
|
|
92
56
|
}
|
|
93
|
-
function log(message, level = 'info') {
|
|
57
|
+
export function log(message, level = 'info') {
|
|
94
58
|
ensureLogFile();
|
|
95
59
|
const ts = new Date().toISOString();
|
|
96
60
|
const line = `[${ts}] [${level}] ${message}\n`;
|
|
97
61
|
if (currentSize + line.length > MAX_BYTES)
|
|
98
62
|
rotate();
|
|
99
63
|
try {
|
|
100
|
-
fs.appendFileSync(
|
|
64
|
+
fs.appendFileSync(mainLogPath(), line);
|
|
101
65
|
currentSize += line.length;
|
|
102
66
|
}
|
|
103
67
|
catch (err) {
|
|
@@ -111,4 +75,3 @@ function log(message, level = 'info') {
|
|
|
111
75
|
else
|
|
112
76
|
console.log(line.trimEnd());
|
|
113
77
|
}
|
|
114
|
-
//# sourceMappingURL=logger.js.map
|
package/dist/electron/main.js
CHANGED
|
@@ -1,63 +1,60 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
/**
|
|
4
2
|
* Electron 主进程 lifecycle 入口
|
|
5
3
|
* 单实例锁 → whenReady → createMainWindow → cleanup on quit
|
|
6
4
|
* 启动时: 装 menu / tray / IPC handlers / 首启引导
|
|
7
5
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
import { app, BrowserWindow } from 'electron';
|
|
7
|
+
import { log } from './logger';
|
|
8
|
+
import { createMainWindow, focusMainWindow, getMainWindow } from './window';
|
|
9
|
+
import { killWebServer } from './server';
|
|
10
|
+
import { installAppMenu } from './menu';
|
|
11
|
+
import { createTray, destroyTray } from './tray';
|
|
12
|
+
import { registerCoreIpc } from './ipc';
|
|
13
|
+
import { registerDialogIpc } from './dialogs';
|
|
14
|
+
import { registerFirstRunIpc, maybeShowFirstRun } from './first-run';
|
|
15
|
+
log('Bolloon Electron 启动');
|
|
18
16
|
// 单实例锁
|
|
19
|
-
const gotTheLock =
|
|
17
|
+
const gotTheLock = app.requestSingleInstanceLock();
|
|
20
18
|
if (!gotTheLock) {
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
log('已有实例在运行,退出');
|
|
20
|
+
app.quit();
|
|
23
21
|
}
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
app.on('second-instance', () => {
|
|
23
|
+
focusMainWindow();
|
|
26
24
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
await
|
|
25
|
+
app.whenReady().then(async () => {
|
|
26
|
+
log('Electron 准备好');
|
|
27
|
+
registerCoreIpc();
|
|
28
|
+
registerDialogIpc();
|
|
29
|
+
registerFirstRunIpc();
|
|
30
|
+
installAppMenu(getMainWindow);
|
|
31
|
+
createTray(getMainWindow);
|
|
32
|
+
await createMainWindow();
|
|
35
33
|
// 首启引导 (在主窗口就绪后弹, 不阻塞 UI)
|
|
36
|
-
const win =
|
|
34
|
+
const win = getMainWindow();
|
|
37
35
|
if (win) {
|
|
38
36
|
win.webContents.once('did-finish-load', () => {
|
|
39
|
-
void
|
|
37
|
+
void maybeShowFirstRun(win);
|
|
40
38
|
});
|
|
41
39
|
}
|
|
42
|
-
|
|
40
|
+
app.on('activate', async () => {
|
|
43
41
|
// macOS: dock 图标被点击且没有窗口时, 重开
|
|
44
|
-
if (
|
|
45
|
-
await
|
|
42
|
+
if (BrowserWindow.getAllWindows().length === 0) {
|
|
43
|
+
await createMainWindow();
|
|
46
44
|
}
|
|
47
45
|
});
|
|
48
46
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
app.on('window-all-closed', () => {
|
|
48
|
+
log('所有窗口已关闭');
|
|
49
|
+
destroyTray();
|
|
50
|
+
killWebServer();
|
|
53
51
|
if (process.platform !== 'darwin') {
|
|
54
|
-
|
|
52
|
+
app.quit();
|
|
55
53
|
}
|
|
56
54
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
app.on('before-quit', () => {
|
|
56
|
+
log('应用即将退出');
|
|
57
|
+
destroyTray();
|
|
58
|
+
killWebServer();
|
|
61
59
|
});
|
|
62
|
-
|
|
63
|
-
//# sourceMappingURL=main.js.map
|
|
60
|
+
log('主进程初始化完成');
|
package/dist/electron/menu.js
CHANGED
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildAppMenu = buildAppMenu;
|
|
4
|
-
exports.installAppMenu = installAppMenu;
|
|
5
1
|
/**
|
|
6
2
|
* 应用菜单 — macOS 标准 + File/Edit/View/Window/Help 自定义项
|
|
7
3
|
* "Open Data Folder" 等会跨平台显示 (mac 也会出现, 不会冲突)
|
|
8
4
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
import { app, Menu, shell } from 'electron';
|
|
6
|
+
import { dataDir, logsDir } from './paths';
|
|
7
|
+
import { log } from './logger';
|
|
12
8
|
function openDataFolder() {
|
|
13
|
-
|
|
9
|
+
shell.openPath(dataDir()).catch((e) => log(`open data folder 失败: ${e.message}`, 'error'));
|
|
14
10
|
}
|
|
15
11
|
function openLogsFolder() {
|
|
16
|
-
|
|
12
|
+
shell.openPath(logsDir()).catch((e) => log(`open logs folder 失败: ${e.message}`, 'error'));
|
|
17
13
|
}
|
|
18
14
|
function openExternal(url) {
|
|
19
|
-
|
|
15
|
+
shell.openExternal(url).catch((e) => log(`openExternal 失败: ${e.message}`, 'error'));
|
|
20
16
|
}
|
|
21
|
-
function buildAppMenu(getMainWindow) {
|
|
17
|
+
export function buildAppMenu(getMainWindow) {
|
|
22
18
|
const isMac = process.platform === 'darwin';
|
|
23
19
|
const win = getMainWindow();
|
|
24
20
|
const appMenu = {
|
|
25
|
-
label:
|
|
21
|
+
label: app.getName(),
|
|
26
22
|
submenu: [
|
|
27
23
|
{ role: 'about' },
|
|
28
24
|
{ type: 'separator' },
|
|
@@ -121,8 +117,8 @@ function buildAppMenu(getMainWindow) {
|
|
|
121
117
|
dialog.showMessageBox({
|
|
122
118
|
type: 'info',
|
|
123
119
|
title: 'About Bolloon Agent',
|
|
124
|
-
message: `Bolloon Agent v${
|
|
125
|
-
detail: `P2P AI Document Agent\nData: ${
|
|
120
|
+
message: `Bolloon Agent v${app.getVersion()}`,
|
|
121
|
+
detail: `P2P AI Document Agent\nData: ${dataDir()}\nLogs: ${logsDir()}`,
|
|
126
122
|
buttons: ['OK'],
|
|
127
123
|
}).catch(() => { });
|
|
128
124
|
},
|
|
@@ -137,9 +133,8 @@ function buildAppMenu(getMainWindow) {
|
|
|
137
133
|
windowMenu,
|
|
138
134
|
helpMenu,
|
|
139
135
|
];
|
|
140
|
-
return
|
|
136
|
+
return Menu.buildFromTemplate(template);
|
|
141
137
|
}
|
|
142
|
-
function installAppMenu(getMainWindow) {
|
|
143
|
-
|
|
138
|
+
export function installAppMenu(getMainWindow) {
|
|
139
|
+
Menu.setApplicationMenu(buildAppMenu(getMainWindow));
|
|
144
140
|
}
|
|
145
|
-
//# sourceMappingURL=menu.js.map
|
package/dist/electron/paths.js
CHANGED
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.dataDir = dataDir;
|
|
37
|
-
exports.userDataDir = userDataDir;
|
|
38
|
-
exports.logsDir = logsDir;
|
|
39
|
-
exports.mainLogPath = mainLogPath;
|
|
40
|
-
exports.firstRunFlagPath = firstRunFlagPath;
|
|
41
|
-
exports.buildResourcesDir = buildResourcesDir;
|
|
42
1
|
/**
|
|
43
2
|
* 路径常量 — 单一来源, 避免散落各处
|
|
44
3
|
*
|
|
@@ -47,29 +6,28 @@ exports.buildResourcesDir = buildResourcesDir;
|
|
|
47
6
|
* userDataDir: Electron 的 app.getPath('userData'), 用来放日志 / 临时 / 锁文件
|
|
48
7
|
* logsDir: userData 下的 logs/ 子目录
|
|
49
8
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
function dataDir() {
|
|
9
|
+
import { app } from 'electron';
|
|
10
|
+
import * as os from 'os';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
export function dataDir() {
|
|
54
13
|
return path.join(os.homedir(), '.bolloon');
|
|
55
14
|
}
|
|
56
|
-
function userDataDir() {
|
|
57
|
-
return
|
|
15
|
+
export function userDataDir() {
|
|
16
|
+
return app.getPath('userData');
|
|
58
17
|
}
|
|
59
|
-
function logsDir() {
|
|
18
|
+
export function logsDir() {
|
|
60
19
|
return path.join(userDataDir(), 'logs');
|
|
61
20
|
}
|
|
62
|
-
function mainLogPath() {
|
|
21
|
+
export function mainLogPath() {
|
|
63
22
|
return path.join(logsDir(), 'bolloon.log');
|
|
64
23
|
}
|
|
65
|
-
function firstRunFlagPath() {
|
|
24
|
+
export function firstRunFlagPath() {
|
|
66
25
|
return path.join(userDataDir(), '.bolloon-first-run-seen');
|
|
67
26
|
}
|
|
68
27
|
/** 资源目录: packaged 下是 process.resourcesPath/build, dev 下是 repo/build/ */
|
|
69
|
-
function buildResourcesDir() {
|
|
70
|
-
if (
|
|
28
|
+
export function buildResourcesDir() {
|
|
29
|
+
if (app.isPackaged) {
|
|
71
30
|
return path.join(process.resourcesPath, 'build');
|
|
72
31
|
}
|
|
73
|
-
return path.join(
|
|
32
|
+
return path.join(app.getAppPath(), 'build');
|
|
74
33
|
}
|
|
75
|
-
//# sourceMappingURL=paths.js.map
|
package/dist/electron/server.js
CHANGED
|
@@ -1,76 +1,38 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.getWebServerProcess = getWebServerProcess;
|
|
37
|
-
exports.killWebServer = killWebServer;
|
|
38
|
-
exports.startWebServer = startWebServer;
|
|
39
1
|
/**
|
|
40
2
|
* Spawns dist/web/server.js as a child Node process (via Electron's
|
|
41
3
|
* ELECTRON_RUN_AS_NODE=1) and parses BOLLOON_PORT=NNNN to learn the
|
|
42
4
|
* actually-bound port (which may have drifted from the preferred port
|
|
43
5
|
* due to EADDRINUSE auto-bump).
|
|
44
6
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
7
|
+
import { spawn } from 'child_process';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import { log } from './logger';
|
|
10
|
+
import { WEB_SERVER_STARTUP_TIMEOUT_MS, DEFAULT_HOST } from './config';
|
|
49
11
|
let webServerProcess = null;
|
|
50
|
-
function getWebServerProcess() {
|
|
12
|
+
export function getWebServerProcess() {
|
|
51
13
|
return webServerProcess;
|
|
52
14
|
}
|
|
53
|
-
function killWebServer() {
|
|
15
|
+
export function killWebServer() {
|
|
54
16
|
if (webServerProcess && !webServerProcess.killed) {
|
|
55
|
-
|
|
17
|
+
log('终止 Web 服务器进程');
|
|
56
18
|
webServerProcess.kill();
|
|
57
19
|
}
|
|
58
20
|
webServerProcess = null;
|
|
59
21
|
}
|
|
60
|
-
function startWebServer(preferredPort) {
|
|
22
|
+
export function startWebServer(preferredPort) {
|
|
61
23
|
return new Promise((resolve, reject) => {
|
|
62
24
|
const serverScript = path.join(__dirname, '..', 'web', 'server.js');
|
|
63
|
-
|
|
25
|
+
log(`启动 Web 服务器进程: ${serverScript}`);
|
|
64
26
|
// ELECTRON_RUN_AS_NODE=1 — packaged 时 process.execPath 是 Electron 二进制,
|
|
65
27
|
// 没这行 require() 会失败. Dev 模式 (electron dist/electron.js) 同样情况.
|
|
66
|
-
webServerProcess =
|
|
28
|
+
webServerProcess = spawn(process.execPath, [serverScript], {
|
|
67
29
|
env: {
|
|
68
30
|
...process.env,
|
|
69
31
|
ELECTRON_RUN_AS_NODE: '1',
|
|
70
32
|
NODE_ENV: 'production',
|
|
71
33
|
PORT: String(preferredPort),
|
|
72
34
|
ELECTRON_PORT: String(preferredPort),
|
|
73
|
-
BOLLOON_HOST:
|
|
35
|
+
BOLLOON_HOST: DEFAULT_HOST,
|
|
74
36
|
},
|
|
75
37
|
stdio: ['ignore', 'pipe', 'pipe'],
|
|
76
38
|
});
|
|
@@ -82,31 +44,31 @@ function startWebServer(preferredPort) {
|
|
|
82
44
|
const m = stdoutBuf.match(/^BOLLOON_PORT=(\d+)/m);
|
|
83
45
|
if (m) {
|
|
84
46
|
const actualPort = parseInt(m[1], 10);
|
|
85
|
-
|
|
47
|
+
log(`Web 服务器就绪: 实际端口=${actualPort} (preferred=${preferredPort})`);
|
|
86
48
|
resolve({ port: actualPort });
|
|
87
49
|
}
|
|
88
50
|
});
|
|
89
51
|
webServerProcess.stderr?.on('data', (data) => {
|
|
90
52
|
stderrData += data.toString();
|
|
91
53
|
process.stderr.write(`[WebServer ERR] ${data}`);
|
|
54
|
+
log(`[WebServer stderr] ${data.toString().trim()}`, 'warn');
|
|
92
55
|
});
|
|
93
56
|
webServerProcess.on('error', (err) => {
|
|
94
|
-
|
|
57
|
+
log(`Web 服务器启动失败: ${err.message}`, 'error');
|
|
95
58
|
reject(err);
|
|
96
59
|
});
|
|
97
60
|
webServerProcess.on('exit', (code, signal) => {
|
|
98
|
-
|
|
61
|
+
log(`Web 服务器退出: code=${code} signal=${signal}`);
|
|
99
62
|
if (code !== 0 && code !== null) {
|
|
100
|
-
|
|
63
|
+
log(`Web 服务器 stderr: ${stderrData.slice(0, 500)}`, 'error');
|
|
101
64
|
}
|
|
102
65
|
webServerProcess = null;
|
|
103
66
|
});
|
|
104
67
|
setTimeout(() => {
|
|
105
68
|
if (webServerProcess && !webServerProcess.killed) {
|
|
106
|
-
|
|
69
|
+
log(`Web 服务器启动超时 (${WEB_SERVER_STARTUP_TIMEOUT_MS}ms)`, 'error');
|
|
107
70
|
reject(new Error('Web server startup timeout'));
|
|
108
71
|
}
|
|
109
|
-
},
|
|
72
|
+
}, WEB_SERVER_STARTUP_TIMEOUT_MS);
|
|
110
73
|
});
|
|
111
74
|
}
|
|
112
|
-
//# sourceMappingURL=server.js.map
|
package/dist/electron/tray.js
CHANGED
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.createTray = createTray;
|
|
37
|
-
exports.destroyTray = destroyTray;
|
|
38
1
|
/**
|
|
39
2
|
* 系统托盘 — Show / Hide / Quit
|
|
40
3
|
*
|
|
@@ -44,33 +7,33 @@ exports.destroyTray = destroyTray;
|
|
|
44
7
|
*
|
|
45
8
|
* 若 build 目录没有 tray 图标, 降级为不创建托盘 (主菜单和窗口关闭行为不变)
|
|
46
9
|
*/
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
10
|
+
import { Tray, Menu, nativeImage, app } from 'electron';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import { buildResourcesDir } from './paths';
|
|
14
|
+
import { log } from './logger';
|
|
52
15
|
let trayInstance = null;
|
|
53
16
|
function loadTrayIcon() {
|
|
54
17
|
const isMac = process.platform === 'darwin';
|
|
55
18
|
const file = isMac ? 'trayTemplate.png' : 'tray.png';
|
|
56
|
-
const iconPath = path.join(
|
|
19
|
+
const iconPath = path.join(buildResourcesDir(), file);
|
|
57
20
|
if (!fs.existsSync(iconPath)) {
|
|
58
|
-
|
|
21
|
+
log(`托盘图标缺失: ${iconPath} (跳过托盘创建)`, 'warn');
|
|
59
22
|
return null;
|
|
60
23
|
}
|
|
61
|
-
const img =
|
|
24
|
+
const img = nativeImage.createFromPath(iconPath);
|
|
62
25
|
if (isMac)
|
|
63
26
|
img.setTemplateImage(true);
|
|
64
27
|
return img;
|
|
65
28
|
}
|
|
66
|
-
function createTray(getMainWindow) {
|
|
29
|
+
export function createTray(getMainWindow) {
|
|
67
30
|
if (trayInstance)
|
|
68
31
|
return;
|
|
69
32
|
const icon = loadTrayIcon();
|
|
70
33
|
if (!icon)
|
|
71
34
|
return;
|
|
72
|
-
trayInstance = new
|
|
73
|
-
trayInstance.setToolTip(`Bolloon Agent v${
|
|
35
|
+
trayInstance = new Tray(icon);
|
|
36
|
+
trayInstance.setToolTip(`Bolloon Agent v${app.getVersion()}`);
|
|
74
37
|
const toggle = () => {
|
|
75
38
|
const w = getMainWindow();
|
|
76
39
|
if (!w)
|
|
@@ -85,14 +48,14 @@ function createTray(getMainWindow) {
|
|
|
85
48
|
w.focus();
|
|
86
49
|
}
|
|
87
50
|
};
|
|
88
|
-
const menu =
|
|
51
|
+
const menu = Menu.buildFromTemplate([
|
|
89
52
|
{ label: 'Show / Hide', click: () => toggle() },
|
|
90
53
|
{ type: 'separator' },
|
|
91
54
|
{
|
|
92
55
|
label: 'Quit',
|
|
93
56
|
click: () => {
|
|
94
|
-
|
|
95
|
-
|
|
57
|
+
log('托盘菜单 Quit');
|
|
58
|
+
app.quit();
|
|
96
59
|
},
|
|
97
60
|
},
|
|
98
61
|
]);
|
|
@@ -102,10 +65,9 @@ function createTray(getMainWindow) {
|
|
|
102
65
|
trayInstance.on('click', () => toggle());
|
|
103
66
|
}
|
|
104
67
|
}
|
|
105
|
-
function destroyTray() {
|
|
68
|
+
export function destroyTray() {
|
|
106
69
|
if (trayInstance) {
|
|
107
70
|
trayInstance.destroy();
|
|
108
71
|
trayInstance = null;
|
|
109
72
|
}
|
|
110
73
|
}
|
|
111
|
-
//# sourceMappingURL=tray.js.map
|