LRAgent Desktop Client
The LRAgent Desktop Client is built on Electron v28, extending the web version with rich local system capabilities.
Differences from the Web Version
| Feature | Web Version | Desktop Client |
|---|---|---|
| System Tray Persistent | - | ✅ |
| Global Hotkey Activation | - | ✅ Ctrl+Shift+L |
| Drag-and-Drop File Import | - | ✅ |
| Offline Data Cache | - | ✅ |
| Local File System Read/Write | - | ✅ |
| Native File Dialog | - | ✅ |
| Export to PDF | - | ✅ |
| Windows Native Notifications | - | ✅ |
| Automatic Update Check | - | ✅ |
| System Information View | - | ✅ |
| Clipboard Image Read/Write | - | ✅ |
| Minimize Window to Tray | - | ✅ |
| NSIS Installer Distribution | - | ✅ |
Quick Start
Development Mode
cd C:\bossagents
npm run electron:dev
此命令会自动:
- Detect if the Vite dev server is running on port 5173
- If not running, automatically start Vite
- Clear the ELECTRON_RUN_AS_NODE environment variable (critical step)
- Launch the Electron desktop window
Production Mode (Installer)
npm run electron:build
生成的安装包位于 release/LRAgent-Setup-{version}-win-x64.exe。
Preview Only (No Packaging)
npm run electron:preview
快捷键
| 快捷键 | 功能 |
|--------|------|
| Ctrl+Shift+L | Show/Hide Main Window |
| Ctrl+Shift+N | Quick Create Part |
| Ctrl+Shift+I | Data Quality Check |
| Ctrl+O | Import File |
| Ctrl+S | Export File |
| Ctrl+F | Find Part |
| F11 | Toggle Full Screen |
System Tray
After minimizing the window, LRAgent shrinks to the system tray area:
- Click the tray icon: Show the context menu
- Double-click the tray icon: Restore the main window
- The tray menu includes: Show Window, Quick Create Part, Data Quality Check, Toggle Offline Mode, About, Exit
Offline Mode
The desktop client supports offline data caching:
- The frontend saves data via window.lragent.offlineCacheSave(key, data)
- Loads cached data via window.lragent.offlineCacheLoad(key)
- Lists all cache entries via window.lragent.offlineCacheList()
- Cache is stored in the %APPDATA%/lragent/offline-cache/ directory
- The 'Tools → Clear Cache' menu option allows one-click clearing of all cache.
Frontend API
The desktop client exposes the following APIs via the window.lragent object (available only on desktop):
File System
// 判断是否在桌面端
if (window.lragent?.isDesktop) {
// 读取文本文件
const result = await window.lragent.readFile('/path/to/file.json')
// 写入文件
await window.lragent.writeFile('/path/to/output.json', JSON.stringify(data))
// 读取二进制文件(返回 base64)
const binary = await window.lragent.readBinaryFile('/path/to/image.png')
// 检查文件是否存在
const exists = await window.lragent.fileExists('/path/to/file')
// 获取文件信息
const stat = await window.lragent.fileStat('/path/to/file')
// 列出目录内容
const dir = await window.lragent.listDir('/path/to/dir')
// 创建目录
await window.lragent.mkdir('/path/to/new/dir')
// 删除文件
await window.lragent.deleteFile('/path/to/file')
// 原生文件选择对话框
const { filePaths } = await window.lragent.selectOpenFile({
filters: [{ name: 'Excel', extensions: ['xlsx', 'xls'] }]
})
// 保存文件对话框
const { filePath } = await window.lragent.selectSaveFile({
filters: [{ name: 'JSON', extensions: ['json'] }]
})
// 选择目录
const { filePath: dirPath } = await window.lragent.selectDirectory()
}
剪贴板
const text = await window.lragent.readClipboardText()
await window.lragent.writeClipboardText('复制内容')
const imageDataURL = await window.lragent.readClipboardImage() // 返回 data:image/png;base64,... 或 null
系统信息
const info = await window.lragent.getSystemInfo()
// 返回: { platform, arch, cpuModel, cpuCores, totalMemGB, freeMemGB, uptime, hostname, electronVer, chromeVer, nodeVer }
通知
await window.lragent.sendNotification('LRAgent', 'Part 创建成功')
窗口控制
await window.lragent.windowMinimize()
await window.lragent.windowMaximize() // 切换最大化
await window.lragent.windowClose()
await window.lragent.windowSetTitle('LRAgent - Part 详情')
离线缓存
await window.lragent.offlineCacheSave('parts-list', partsData)
const cached = await window.lragent.offlineCacheLoad('parts-list')
const allKeys = await window.lragent.offlineCacheList()
事件监听
// 文件拖拽到窗口
window.lragent.onFilesDropped((filePaths) => {
console.log('拖入文件:', filePaths)
})
// 菜单导入文件
window.lragent.onFilesImported((filePaths) => {
console.log('导入文件:', filePaths)
})
// 菜单导入目录
window.lragent.onDirectoryImported((dirPath) => {
console.log('导入目录:', dirPath)
})
// 快捷操作(托盘菜单/全局快捷键触发)
window.lragent.onQuickAction((action) => {
// action: 'create-part' | 'inspect-quality' | 'change-impact' | 'search' | 'local-db'
if (action === 'create-part') openCreatePartDialog()
if (action === 'inspect-quality') runQualityInspection()
})
// 离线模式切换
window.lragent.onOfflineMode((enabled) => {
console.log('离线模式:', enabled ? '开启' : '关闭')
})
// 缓存已清除
window.lragent.onCacheCleared(() => {
console.log('缓存已清除')
})
// 导出完成
window.lragent.onExportComplete((info) => {
console.log('导出完成:', info.type, info.path)
})
其他
const version = await window.lragent.getAppVersion() // '0.1.0'
const dataPath = await window.lragent.getAppPath('userData') // 用户数据目录
const locale = await window.lragent.getAppLocale() // 'zh-CN'
await window.lragent.openExternal('https://eastaiai.com') // 打开外部链接
await window.lragent.openPath('C:\\Users\\...') // 用系统程序打开
await window.lragent.showItemInFolder('C:\\file.txt') // 在资源管理器中显示
await window.lragent.checkForUpdates() // 检查GitHub更新
目录结构
C:\bossagents\
├── electron/ # Electron 启动脚本
│ ├── run.js # 启动器(自动管理Vite + ELECTRON_RUN_AS_NODE)
│ ├── main.js # 主进程(备用,与electron-app/main.js同步)
│ └── preload.js # 预加载脚本(备用)
├── electron-app/ # 独立Electron应用目录
│ ├── package.json # 独立package.json(避免node_modules干扰)
│ ├── main.js # 主进程(窗口、托盘、快捷键、IPC)
│ ├── preload.js # 安全桥接层(contextBridge API)
│ └── installer.nsh # NSIS自定义安装脚本
├── electron-builder.yml # 打包配置
├── dist/ # Vite构建产物(打包时包含)
└── release/ # 安装包输出目录
└── LRAgent-Setup-0.1.0-win-x64.exe
打包配置
electron-builder.yml 支持:
- Windows: NSIS installer (supports custom installation path, Chinese interface, desktop shortcut)
- macOS: DMG image (x64 + arm64)
- Linux: AppImage + deb
- Auto-update: Automatically detects new releases on GitHub Release
Troubleshooting
1. ELECTRON_RUN_AS_NODE causes startup failure
Symptom: TypeError: Cannot read properties of undefined (reading 'handle')
Cause: npm/pnpm sets ELECTRON_RUN_AS_NODE=1 when executing scripts, causing Electron to run in plain Node.js mode.
Solution: electron/run.js already handles this automatically. If launching manually, ensure:
$env:ELECTRON_RUN_AS_NODE=''
& "node_modules\electron\dist\electron.exe" "electron-app" --dev
2. Vite 未启动导致白屏
症状: 窗口打开但显示 ERR_CONNECTION_REFUSED
Solution: Start Vite first, then Electron, or use npm run electron:dev (automatically managed)
3. Electron v43 incompatibility
Cause: Electron v43 requires ESM imports (import from 'electron/main'), which is incompatible with CJS projects.
Solution: Currently using Electron v28 LTS (CJS compatible), version is locked in package.json.
4. Installer lacks icon
Current status: Using Electron's default icon. For a custom icon, place icon.ico in the electron-app/ directory and configure win.icon in electron-builder.yml.
5. better-sqlite3 native module rebuild failure
Cause: electron-builder rebuilds native modules by default, requiring Python + Visual Studio Build Tools.
Solution: Add --config.npmRebuild=false during packaging to skip rebuild:
npx electron-builder --win --x64 --config.npmRebuild=false
Version history
- v0.1.0 (2026-08-16)
- Initial desktop client
- System tray + global hotkeys
- Drag-and-drop file import
- Offline data caching
- Local filesystem API
- NSIS installer
- Automatic update detection
BossAgents