@bolloon/bolloon-agent 0.3.16 → 0.3.18

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.
@@ -16,12 +16,19 @@ import * as path from 'path';
16
16
  import { fileURLToPath } from 'url';
17
17
  const RESET = '\x1b[0m';
18
18
  const BOLD = '\x1b[1m';
19
- const CYAN = '\x1b[36m';
20
- const YELLOW = '\x1b[33m';
21
- const GREEN = '\x1b[32m';
22
- const RED = '\x1b[31m';
23
- const GRAY = '\x1b[90m';
24
- const WHITE = '\x1b[37m';
19
+ const DIM = '\x1b[2m';
20
+ // Bolloon Web UI 配色 truecolor ANSI
21
+ function fg(r, g, b) { return `\x1b[38;2;${r};${g};${b}m`; }
22
+ function bg(r, g, b) { return `\x1b[48;2;${r};${g};${b}m`; }
23
+ const C_ACCENT = fg(0xc4, 0xd6, 0x40); // #c4d640
24
+ const C_ACCENT_BG = bg(0xc4, 0xd6, 0x40);
25
+ const C_TEXT = fg(0xd8, 0xd8, 0xc8); // #d8d8c8
26
+ const C_DIM = fg(0x90, 0x90, 0x88); // #909088
27
+ const C_MUTED = fg(0x60, 0x60, 0x58); // #606058
28
+ const C_OK = fg(0x22, 0xc5, 0x5e); // #22c55e
29
+ const C_ERROR = fg(0xef, 0x44, 0x44); // #ef4444
30
+ const C_WARN = fg(0xf5, 0x9e, 0x0b); // #f59e0b
31
+ const C_BORDER = fg(0x3a, 0x3a, 0x36); // #3a3a36
25
32
  const HIDE = '\x1b[?25l';
26
33
  const SHOW = '\x1b[?25h';
27
34
  // 版本信息 — 从 package.json 读取, 不再硬编码
@@ -38,22 +45,22 @@ function getPackageVersion() {
38
45
  const BOLLOON_VERSION = getPackageVersion();
39
46
  // ── 品牌图标: 顶部带圆标注的 0 (气球) ──────────────
40
47
  export const BOLLOON_ICON = [
41
- `${CYAN} ✦${RESET}`,
42
- `${CYAN} ╱ ╲${RESET}`,
43
- `${CYAN} ════◆════${RESET}`,
44
- `${CYAN} ╲ ╱${RESET}`,
45
- `${CYAN} ╲${RESET}`,
46
- `${CYAN} ✦ ╲${RESET}`,
48
+ `${C_ACCENT} ✦${RESET}`,
49
+ `${C_ACCENT} ╱ ╲${RESET}`,
50
+ `${C_ACCENT} ════◆════${RESET}`,
51
+ `${C_ACCENT} ╲ ╱${RESET}`,
52
+ `${C_ACCENT} ╲${RESET}`,
53
+ `${C_ACCENT} ✦ ╲${RESET}`,
47
54
  ].join('\n');
48
55
  // ── 艺术字: BOLLOON (box 字体) + Bolloon Agent 副标题 ──
49
56
  export const BOLLOON_BANNER = [
50
- `${WHITE}${BOLD}██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ███╗ ██╗${RESET}`,
51
- `${WHITE}${BOLD}██╔══██╗██╔═══██╗██║ ██║ ██╔═══██╗██╔═══██╗████╗ ██║${RESET}`,
52
- `${WHITE}${BOLD}██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║██╔██╗ ██║${RESET}`,
53
- `${WHITE}${BOLD}██╔══██╗██║ ██║██║ ██║ ██║ ██║██║ ██║██║╚██╗██║${RESET}`,
54
- `${WHITE}${BOLD}██████╔╝╚██████╔╝███████╗███████╗╚██████╔╝╚██████╔╝██║ ╚████║${RESET}`,
55
- `${WHITE}${BOLD}╚═════╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝${RESET}`,
56
- `${GRAY}Bolloon Agent v${BOLLOON_VERSION}${RESET}`,
57
+ `${C_TEXT}${BOLD}██████╗ ██████╗ ██╗ ██╗ ██████╗ ██████╗ ███╗ ██╗${RESET}`,
58
+ `${C_TEXT}${BOLD}██╔══██╗██╔═══██╗██║ ██║ ██╔═══██╗██╔═══██╗████╗ ██║${RESET}`,
59
+ `${C_TEXT}${BOLD}██████╔╝██║ ██║██║ ██║ ██║ ██║██║ ██║██╔██╗ ██║${RESET}`,
60
+ `${C_TEXT}${BOLD}██╔══██╗██║ ██║██║ ██║ ██║ ██║██║ ██║██║╚██╗██║${RESET}`,
61
+ `${C_TEXT}${BOLD}██████╔╝╚██████╔╝███████╗███████╗╚██████╔╝╚██████╔╝██║ ╚████║${RESET}`,
62
+ `${C_TEXT}${BOLD}╚═════╝ ╚═════╝ ╚══════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝${RESET}`,
63
+ `${C_DIM}Bolloon Agent v${BOLLOON_VERSION}${RESET}`,
57
64
  ].join('\n');
58
65
  /** 艺术字全部行 (图标在左, BOLLOON 艺术字在右), 供框内渲染 */
59
66
  function brandArtLines() {
@@ -75,18 +82,18 @@ export function printBanner(version) {
75
82
  console.log(BOLLOON_ICON);
76
83
  console.log(BOLLOON_BANNER);
77
84
  if (version)
78
- console.log(`${GRAY} Bolloon Agent v${version}${RESET}`);
79
- console.log(`${GRAY} P2P AI Agent · 文档智能体${RESET}`);
85
+ console.log(`${C_DIM} Bolloon Agent v${version}${RESET}`);
86
+ console.log(`${C_DIM} P2P AI Agent · 文档智能体${RESET}`);
80
87
  console.log('');
81
88
  }
82
89
  // ── 状态图标 ───────────────────────────────────────
83
90
  export const STATUS_SYMBOL = {
84
- pending: `${GRAY}○${RESET}`,
85
- active: `${YELLOW}⠹${RESET}`,
86
- ok: `${GREEN}✓${RESET}`,
87
- warn: `${YELLOW}⚠${RESET}`,
88
- error: `${RED}✗${RESET}`,
89
- info: `${CYAN}●${RESET}`,
91
+ pending: `${C_MUTED}○${RESET}`,
92
+ active: `${C_WARN}⠹${RESET}`,
93
+ ok: `${C_OK}✓${RESET}`,
94
+ warn: `${C_WARN}⚠${RESET}`,
95
+ error: `${C_ERROR}✗${RESET}`,
96
+ info: `${C_ACCENT}●${RESET}`,
90
97
  };
91
98
  // 方角 (启动仪表盘 / 对话框 / 引用框)
92
99
  const SQ = { tl: '┌', tr: '┐', bl: '└', br: '┘', v: '│', h: '─' };
@@ -191,7 +198,7 @@ export function renderDashboard(opts) {
191
198
  }
192
199
  for (const r of opts.rows) {
193
200
  const sym = STATUS_SYMBOL[r.status ?? 'info'];
194
- const detail = r.detail ? ` ${GRAY}${r.detail}${RESET}` : '';
201
+ const detail = r.detail ? ` ${C_DIM}${r.detail}${RESET}` : '';
195
202
  lines.push(boxRow(`${sym} ${r.label}${detail}`, width));
196
203
  }
197
204
  lines.push(boxBottom(width));
@@ -265,7 +272,7 @@ function wrapText(text, width) {
265
272
  /** 对话框默认显示上限 (按高度截断) */
266
273
  const DEFAULT_MAX_LINES = 14;
267
274
  export function renderMessageBox(opts) {
268
- const color = opts.color ?? CYAN;
275
+ const color = opts.color ?? C_ACCENT;
269
276
  const title = opts.title ?? 'Bolloon Agent';
270
277
  const maxLines = opts.maxLines && opts.maxLines > 0 ? opts.maxLines : 0;
271
278
  const bodyLines = wrapText(opts.body, 1000);
@@ -298,20 +305,20 @@ function renderReference(opts) {
298
305
  const inner = Math.max(20, dispWidth(opts.title) + 8, dispWidth(`已压缩 ${opts.hidden} 行 · 完整内容已发送给智能体`), dispWidth(preview) + 2);
299
306
  const width = Math.min(termWidth() - 2, opts.width ?? inner + 4);
300
307
  const lines = [];
301
- lines.push(boxTop(`${GRAY}引用${RESET} ${opts.color}${opts.title}${RESET}`, width, RD));
302
- lines.push(boxRow(`${GRAY}已压缩 ${opts.hidden} 行 · 完整内容已发送给智能体${RESET}`, width, 'left', RD));
308
+ lines.push(boxTop(`${C_DIM}引用${RESET} ${opts.color}${opts.title}${RESET}`, width, RD));
309
+ lines.push(boxRow(`${C_DIM}已压缩 ${opts.hidden} 行 · 完整内容已发送给智能体${RESET}`, width, 'left', RD));
303
310
  if (preview)
304
- lines.push(boxRow(`${GRAY}▏ ${preview}${RESET}`, width, 'left', RD));
311
+ lines.push(boxRow(`${C_DIM}▏ ${preview}${RESET}`, width, 'left', RD));
305
312
  lines.push(boxBottom(width, RD));
306
313
  return lines.join('\n');
307
314
  }
308
315
  /** 已发送消息框 (用户输入) */
309
316
  export function renderUserMessage(body) {
310
- return renderMessageBox({ title: '✓ 已发送', body, color: GREEN, maxLines: DEFAULT_MAX_LINES });
317
+ return renderMessageBox({ title: '✓ 已发送', body, color: C_OK, maxLines: DEFAULT_MAX_LINES });
311
318
  }
312
319
  /** 智能体回复框 */
313
320
  export function renderAgentMessage(body) {
314
- return renderMessageBox({ title: '◉ Bolloon Agent', body, color: CYAN, maxLines: DEFAULT_MAX_LINES });
321
+ return renderMessageBox({ title: '◉ Bolloon Agent', body, color: C_ACCENT, maxLines: DEFAULT_MAX_LINES });
315
322
  }
316
323
  /** 循环工作流连接线: 用 ╼ ╾ 串联相邻工具框 */
317
324
  export function flowConnector(width) {
@@ -323,7 +330,7 @@ export function flowConnector(width) {
323
330
  }
324
331
  /** 渲染单个工具调用为圆角框 (参数 / 状态 / 输出预览) */
325
332
  export function renderToolCall(v) {
326
- const color = v.status === 'ok' ? GREEN : RED;
333
+ const color = v.status === 'ok' ? C_OK : C_ERROR;
327
334
  const sym = v.status === 'ok' ? '✅' : '❌';
328
335
  const w = Math.min(termWidth() - 2, v.width ?? 72);
329
336
  const rows = [];
@@ -382,7 +389,7 @@ export class LoadingTUI {
382
389
  out.push(boxRow(`${STATUS_SYMBOL[step.status]} ${step.label}`, w));
383
390
  }
384
391
  if (showSpinner) {
385
- const sp = YELLOW + FRAMES[this.frameIdx % FRAMES.length] + RESET;
392
+ const sp = C_WARN + FRAMES[this.frameIdx % FRAMES.length] + RESET;
386
393
  out.push(boxRow(`${sp} ${this.currentLabel}`, w));
387
394
  }
388
395
  else {
package/dist/cli-entry.js CHANGED
@@ -20,14 +20,17 @@ import { fileURLToPath } from 'url';
20
20
  import { printBanner } from './cli/loading-tui.js';
21
21
  import { discoverEngines, delegateToEngine } from './external-engines/index.js';
22
22
  import { x402CheckBalance, x402Fetch } from './agents/x402/x402Pay.js';
23
+ import { createRequire } from 'module';
24
+ const _require = createRequire(import.meta.url);
23
25
  const isWindows = process.platform === 'win32';
24
- // ANSI 颜色
26
+ // ANSI 颜色 — Bolloon Web UI 配色 truecolor
27
+ function _fg(r, g, b) { return `\x1b[38;2;${r};${g};${b}m`; }
25
28
  const RESET = '\x1b[0m';
26
29
  const BOLD = '\x1b[1m';
27
- const CYAN = '\x1b[36m';
28
- const YELLOW = '\x1b[33m';
29
- const GREEN = '\x1b[32m';
30
- const MAGENTA = '\x1b[35m';
30
+ const CYAN = _fg(0xc4, 0xd6, 0x40); // #c4d640
31
+ const YELLOW = _fg(0xf5, 0x9e, 0x0b); // #f59e0b
32
+ const GREEN = _fg(0x22, 0xc5, 0x5e); // #22c55e
33
+ const MAGENTA = _fg(0xef, 0x44, 0x44); // #ef4444
31
34
  // 版本信息 — 2026-07-20 Bug 3: 从 package.json 读取, 不再硬编码
32
35
  const VERSION = (() => {
33
36
  try {
@@ -100,9 +103,13 @@ function getMainScript() {
100
103
  throw new Error('找不到入口脚本,请确保已执行 npm run build');
101
104
  }
102
105
  function getElectronPath() {
103
- // 获取 electron 可执行文件路径
104
- const electronPath = require('electron');
105
- return electronPath;
106
+ // ESM 兼容: use _require (createRequire) instead of raw require
107
+ try {
108
+ return _require('electron');
109
+ }
110
+ catch {
111
+ return 'electron';
112
+ }
106
113
  }
107
114
  // 解析命令行参数
108
115
  function parseArgs() {
@@ -1,21 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isDev = exports.MAIN_WINDOW_MIN = exports.MAIN_WINDOW_DEFAULT = exports.WEB_SERVER_STARTUP_TIMEOUT_MS = exports.DEFAULT_HOST = exports.DEFAULT_PORT = void 0;
4
- exports.preferredPort = preferredPort;
5
1
  /**
6
2
  * 常量配置 (env 解析在这里集中, 不散在 main 流程)
7
3
  */
8
- const electron_1 = require("electron");
9
- exports.DEFAULT_PORT = 54188;
4
+ import { app } from 'electron';
5
+ export const DEFAULT_PORT = 54188;
10
6
  /** Hard-pin to loopback; LAN exposure must be explicit. */
11
- exports.DEFAULT_HOST = '127.0.0.1';
12
- exports.WEB_SERVER_STARTUP_TIMEOUT_MS = 15_000;
13
- exports.MAIN_WINDOW_DEFAULT = { width: 1200, height: 800 };
14
- exports.MAIN_WINDOW_MIN = { width: 800, height: 600 };
15
- function preferredPort() {
7
+ export const DEFAULT_HOST = '127.0.0.1';
8
+ export const WEB_SERVER_STARTUP_TIMEOUT_MS = 15_000;
9
+ export const MAIN_WINDOW_DEFAULT = { width: 1200, height: 800 };
10
+ export const MAIN_WINDOW_MIN = { width: 800, height: 600 };
11
+ export function preferredPort() {
16
12
  const raw = process.env.ELECTRON_PORT || process.env.PORT;
17
13
  const n = parseInt(raw || '', 10);
18
- return Number.isFinite(n) && n > 0 && n < 65536 ? n : exports.DEFAULT_PORT;
14
+ return Number.isFinite(n) && n > 0 && n < 65536 ? n : DEFAULT_PORT;
19
15
  }
20
- exports.isDev = process.env.NODE_ENV === 'development' || !electron_1.app.isPackaged;
21
- //# sourceMappingURL=config.js.map
16
+ export const isDev = process.env.NODE_ENV === 'development' || !app.isPackaged;
@@ -1,61 +1,25 @@
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.registerDialogIpc = registerDialogIpc;
37
1
  /**
38
2
  * 文件 dialog 桥 (open / save / dir) + 安全的 fs 桥 (read / write / exists)
39
3
  *
40
4
  * 5MB read 上限保护 — 渲染进程直接 fs.readFile 没法做限制, 走主进程就有界
41
5
  * 所有 handler 解析 event.sender 拿到 window, 让 dialog 模态在该窗口上
42
6
  */
43
- const electron_1 = require("electron");
44
- const fs = __importStar(require("fs"));
45
- const path = __importStar(require("path"));
46
- const logger_1 = require("./logger");
7
+ import { BrowserWindow, dialog, ipcMain } from 'electron';
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import { log } from './logger';
47
11
  const MAX_READ_BYTES = 5 * 1024 * 1024; // 5MB
48
12
  function windowFor(event) {
49
- return electron_1.BrowserWindow.fromWebContents(event.sender);
13
+ return BrowserWindow.fromWebContents(event.sender);
50
14
  }
51
15
  function resolveSafe(target) {
52
16
  // 不去硬限制路径 — user 给 renderer 暴露 fs 已经信任了, 这里只 normalize
53
17
  return path.resolve(target);
54
18
  }
55
- function registerDialogIpc() {
56
- electron_1.ipcMain.handle('dialog:open-file', async (event, opts = {}) => {
19
+ export function registerDialogIpc() {
20
+ ipcMain.handle('dialog:open-file', async (event, opts = {}) => {
57
21
  const win = windowFor(event);
58
- const result = await electron_1.dialog.showOpenDialog(win, {
22
+ const result = await dialog.showOpenDialog(win, {
59
23
  title: opts.title,
60
24
  defaultPath: opts.defaultPath,
61
25
  filters: opts.filters,
@@ -63,25 +27,25 @@ function registerDialogIpc() {
63
27
  });
64
28
  return { canceled: result.canceled, filePaths: result.filePaths };
65
29
  });
66
- electron_1.ipcMain.handle('dialog:save-file', async (event, opts = {}) => {
30
+ ipcMain.handle('dialog:save-file', async (event, opts = {}) => {
67
31
  const win = windowFor(event);
68
- const result = await electron_1.dialog.showSaveDialog(win, {
32
+ const result = await dialog.showSaveDialog(win, {
69
33
  title: opts.title,
70
34
  defaultPath: opts.defaultPath,
71
35
  filters: opts.filters,
72
36
  });
73
37
  return { canceled: result.canceled, filePath: result.filePath };
74
38
  });
75
- electron_1.ipcMain.handle('dialog:open-directory', async (event, opts = {}) => {
39
+ ipcMain.handle('dialog:open-directory', async (event, opts = {}) => {
76
40
  const win = windowFor(event);
77
- const result = await electron_1.dialog.showOpenDialog(win, {
41
+ const result = await dialog.showOpenDialog(win, {
78
42
  title: opts.title,
79
43
  defaultPath: opts.defaultPath,
80
44
  properties: ['openDirectory', 'createDirectory'],
81
45
  });
82
46
  return { canceled: result.canceled, filePaths: result.filePaths };
83
47
  });
84
- electron_1.ipcMain.handle('fs:read-text-file', async (_event, opts) => {
48
+ ipcMain.handle('fs:read-text-file', async (_event, opts) => {
85
49
  const target = resolveSafe(opts.path);
86
50
  const stat = fs.statSync(target);
87
51
  if (stat.size > MAX_READ_BYTES) {
@@ -89,12 +53,12 @@ function registerDialogIpc() {
89
53
  }
90
54
  return fs.readFileSync(target, { encoding: opts.encoding ?? 'utf8' });
91
55
  });
92
- electron_1.ipcMain.handle('fs:write-text-file', async (_event, opts) => {
56
+ ipcMain.handle('fs:write-text-file', async (_event, opts) => {
93
57
  const target = resolveSafe(opts.path);
94
58
  fs.mkdirSync(path.dirname(target), { recursive: true });
95
59
  fs.writeFileSync(target, opts.content, { encoding: opts.encoding ?? 'utf8' });
96
60
  });
97
- electron_1.ipcMain.handle('fs:path-exists', async (_event, opts) => {
61
+ ipcMain.handle('fs:path-exists', async (_event, opts) => {
98
62
  try {
99
63
  fs.accessSync(resolveSafe(opts.path));
100
64
  return true;
@@ -103,6 +67,5 @@ function registerDialogIpc() {
103
67
  return false;
104
68
  }
105
69
  });
106
- (0, logger_1.log)('dialog + fs IPC handlers registered');
70
+ log('dialog + fs IPC handlers registered');
107
71
  }
108
- //# sourceMappingURL=dialogs.js.map
@@ -1,54 +1,14 @@
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.hasSeenFirstRun = hasSeenFirstRun;
37
- exports.markFirstRunSeen = markFirstRunSeen;
38
- exports.showFirstRunOverlay = showFirstRunOverlay;
39
- exports.registerFirstRunIpc = registerFirstRunIpc;
40
- exports.maybeShowFirstRun = maybeShowFirstRun;
41
1
  /**
42
2
  * 首启检测 + 引导浮层
43
3
  *
44
4
  * 标记文件写在 userData (不是 ~/.bolloon/), 卸载 app 自然清掉
45
5
  * 引导窗是父主窗的 modal, frame=false, 透明背景; 关闭时标记写入
46
6
  */
47
- const electron_1 = require("electron");
48
- const fs = __importStar(require("fs"));
49
- const path = __importStar(require("path"));
50
- const paths_1 = require("./paths");
51
- const logger_1 = require("./logger");
7
+ import { BrowserWindow, app, ipcMain } from 'electron';
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import { firstRunFlagPath, dataDir, logsDir } from './paths';
11
+ import { log } from './logger';
52
12
  const OVERLAY_HTML = `
53
13
  <!DOCTYPE html>
54
14
  <html>
@@ -104,26 +64,26 @@ const OVERLAY_HTML = `
104
64
  </body>
105
65
  </html>
106
66
  `;
107
- function hasSeenFirstRun() {
67
+ export function hasSeenFirstRun() {
108
68
  try {
109
- return fs.existsSync((0, paths_1.firstRunFlagPath)());
69
+ return fs.existsSync(firstRunFlagPath());
110
70
  }
111
71
  catch {
112
72
  return false;
113
73
  }
114
74
  }
115
- function markFirstRunSeen() {
75
+ export function markFirstRunSeen() {
116
76
  try {
117
- fs.mkdirSync(path.dirname((0, paths_1.firstRunFlagPath)()), { recursive: true });
118
- fs.writeFileSync((0, paths_1.firstRunFlagPath)(), new Date().toISOString());
77
+ fs.mkdirSync(path.dirname(firstRunFlagPath()), { recursive: true });
78
+ fs.writeFileSync(firstRunFlagPath(), new Date().toISOString());
119
79
  }
120
80
  catch (err) {
121
- (0, logger_1.log)(`写入首启标记失败: ${err.message}`, 'warn');
81
+ log(`写入首启标记失败: ${err.message}`, 'warn');
122
82
  }
123
83
  }
124
- function showFirstRunOverlay(parent) {
84
+ export function showFirstRunOverlay(parent) {
125
85
  return new Promise((resolve) => {
126
- const overlay = new electron_1.BrowserWindow({
86
+ const overlay = new BrowserWindow({
127
87
  parent,
128
88
  modal: true,
129
89
  frame: false,
@@ -143,28 +103,27 @@ function showFirstRunOverlay(parent) {
143
103
  markFirstRunSeen();
144
104
  overlay.close();
145
105
  };
146
- electron_1.ipcMain.once('first-run:ack', handler);
106
+ ipcMain.once('first-run:ack', handler);
147
107
  overlay.on('closed', () => {
148
- electron_1.ipcMain.removeListener('first-run:ack', handler);
108
+ ipcMain.removeListener('first-run:ack', handler);
149
109
  resolve();
150
110
  });
151
111
  });
152
112
  }
153
113
  /** 注册 IPC handlers (给 preload 桥用) */
154
- function registerFirstRunIpc() {
155
- electron_1.ipcMain.handle('first-run:seen', () => hasSeenFirstRun());
156
- electron_1.ipcMain.handle('first-run:mark-seen', () => { markFirstRunSeen(); });
114
+ export function registerFirstRunIpc() {
115
+ ipcMain.handle('first-run:seen', () => hasSeenFirstRun());
116
+ ipcMain.handle('first-run:mark-seen', () => { markFirstRunSeen(); });
157
117
  // 同步值 (不用 ipcRenderer.invoke 的 await) — 用 exposeInMainWorld 的 sync getter 更顺
158
- electron_1.ipcMain.handle('first-run:data-dir', () => (0, paths_1.dataDir)());
159
- electron_1.ipcMain.handle('first-run:logs-dir', () => (0, paths_1.logsDir)());
160
- (0, logger_1.log)('first-run IPC handlers registered');
118
+ ipcMain.handle('first-run:data-dir', () => dataDir());
119
+ ipcMain.handle('first-run:logs-dir', () => logsDir());
120
+ log('first-run IPC handlers registered');
161
121
  }
162
122
  /** 包装 — 决定要不要弹 overlay */
163
- async function maybeShowFirstRun(parent) {
123
+ export async function maybeShowFirstRun(parent) {
164
124
  if (hasSeenFirstRun())
165
125
  return;
166
- (0, logger_1.log)('首启 — 弹出引导');
126
+ log('首启 — 弹出引导');
167
127
  await showFirstRunOverlay(parent);
168
- electron_1.app.addRecentDocument((0, paths_1.firstRunFlagPath)()); // 跟踪最近文档, 让 user 知道有这文件
128
+ app.addRecentDocument(firstRunFlagPath()); // 跟踪最近文档, 让 user 知道有这文件
169
129
  }
170
- //# sourceMappingURL=first-run.js.map
@@ -1,20 +1,16 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerCoreIpc = registerCoreIpc;
4
1
  /**
5
2
  * IPC handler 集中注册 — version / userData path / open-external (legacy 3 个)
6
3
  * dialog/fs 的注册在 dialogs.ts; updater 的注册在 updater.ts
7
4
  */
8
- const electron_1 = require("electron");
9
- const paths_1 = require("./paths");
10
- const logger_1 = require("./logger");
11
- function registerCoreIpc() {
12
- electron_1.ipcMain.handle('get-version', () => electron_1.app.getVersion());
13
- electron_1.ipcMain.handle('get-user-data-path', () => (0, paths_1.userDataDir)());
14
- electron_1.ipcMain.handle('get-data-path', () => (0, paths_1.dataDir)()); // 跟 userData 分开, 渲染层要用
15
- electron_1.ipcMain.handle('open-external', async (_event, url) => {
16
- await electron_1.shell.openExternal(url);
5
+ import { app, ipcMain, shell } from 'electron';
6
+ import { userDataDir, dataDir } from './paths';
7
+ import { log } from './logger';
8
+ export function registerCoreIpc() {
9
+ ipcMain.handle('get-version', () => app.getVersion());
10
+ ipcMain.handle('get-user-data-path', () => userDataDir());
11
+ ipcMain.handle('get-data-path', () => dataDir()); // 跟 userData 分开, 渲染层要用
12
+ ipcMain.handle('open-external', async (_event, url) => {
13
+ await shell.openExternal(url);
17
14
  });
18
- (0, logger_1.log)('core IPC handlers registered');
15
+ log('core IPC handlers registered');
19
16
  }
20
- //# sourceMappingURL=ipc.js.map
@@ -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
- const fs = __importStar(require("fs"));
45
- const paths_1 = require("./paths");
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((0, paths_1.logsDir)(), { recursive: true });
19
+ fs.mkdirSync(logsDir(), { recursive: true });
56
20
  try {
57
- currentSize = fs.statSync((0, paths_1.mainLogPath)()).size;
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 = (0, paths_1.mainLogPath)();
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((0, paths_1.mainLogPath)(), line);
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