mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-13 03:13:41 +08:00
433 lines
13 KiB
Markdown
433 lines
13 KiB
Markdown
# MateClaw Desktop
|
||
|
||
MateClaw 的桌面客户端,基于 Electron 构建,自动集成 JRE 21 和后端服务,实现双击即用。
|
||
|
||
## 架构
|
||
|
||
```
|
||
Electron Shell
|
||
├── Splash Screen (Vue 3) ← 启动加载界面
|
||
├── Bundled JRE 21 ← 自带 Java 运行时
|
||
├── mateclaw-server.jar ← Spring Boot 后端 + Vue 前端
|
||
└── BrowserWindow → localhost:18088
|
||
```
|
||
|
||
**启动流程**: Electron 启动 → 显示 Splash → 用内置 JRE 启动 JAR → 等待后端就绪 → 加载主界面
|
||
|
||
## 快速开始
|
||
|
||
### 前置要求
|
||
|
||
- Node.js 18+
|
||
- pnpm (前端构建)
|
||
- Maven 3.9+ (后端构建)
|
||
- Java 21+ (仅构建时需要,运行时使用内置 JRE)
|
||
|
||
### 开发模式
|
||
|
||
```bash
|
||
# 1. 安装依赖
|
||
npm install
|
||
|
||
# 2. 构建后端 JAR(包含前端资源)
|
||
npm run setup:jar
|
||
|
||
# 3. 下载 JRE(当前平台)
|
||
npm run setup:jre
|
||
|
||
# 4. 启动开发模式
|
||
npm run dev
|
||
```
|
||
|
||
### 打包发布
|
||
|
||
```bash
|
||
# macOS (.dmg)
|
||
npm run package:mac
|
||
|
||
# Windows (.exe)
|
||
npm run package:win
|
||
|
||
# 全平台
|
||
npm run package:all
|
||
```
|
||
|
||
输出在 `release/` 目录。
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
mateclaw-desktop/
|
||
├── electron/main/ # Electron 主进程(Java 生命周期管理)
|
||
├── electron/preload/ # 预加载脚本(安全 IPC 桥接)
|
||
├── src/ # Splash Screen(Vue 3 加载页面)
|
||
├── build/ # 应用图标和 macOS entitlements
|
||
├── scripts/ # 构建脚本
|
||
│ ├── download-jre.sh # 下载 Adoptium JRE 21
|
||
│ └── build.sh # 构建前端 + 后端 JAR
|
||
└── resources/ # 运行时资源(JRE + JAR,不提交到 Git)
|
||
```
|
||
|
||
## 环境变量
|
||
|
||
桌面应用**不需要任何环境变量**就能启动——LLM 供应商 Key 在 UI 里加。
|
||
|
||
以下是可选的环境变量(桌面应用会继承系统环境):
|
||
|
||
| 变量 | 必须 | 说明 |
|
||
|------|------|------|
|
||
| `SERPER_API_KEY` | ❌ | Google Serper 搜索 API(搜索工具暂未迁到 UI) |
|
||
| `TAVILY_API_KEY` | ❌ | Tavily 搜索 API |
|
||
|
||
> 💡 DashScope / OpenAI / Anthropic / DeepSeek / Kimi / Ollama 等 LLM 供应商 Key 启动后在「设置 → 模型 → 添加供应商」里粘进去,加密存到本地 H2 数据库。
|
||
|
||
## 自动升级
|
||
|
||
应用内置 `electron-updater` 自动升级,更新产物托管在 [GitHub Releases](https://github.com/matevip/mateclaw/releases)。
|
||
|
||
**升级流程**:启动时检查 → Splash Screen 底部通知 → 用户点击下载 → 下载完成点击重启 → 自动停止 Java 后端 → 安装新版本
|
||
|
||
| 平台 | 更新包格式 | 元数据文件 | 签名要求 |
|
||
|------|-----------|-----------|---------|
|
||
| Windows | NSIS `.exe` | `latest.yml` | 可选(不签名会触发 SmartScreen) |
|
||
| macOS | `.zip` | `latest-mac.yml` | **必须签名+公证**(否则只能手动 DMG 安装) |
|
||
|
||
## 发布操作手册
|
||
|
||
### 第一步:配置 GitHub Token
|
||
|
||
`electron-builder` 使用 `github` provider,需要 GitHub Personal Access Token 来创建 Release 并上传产物。
|
||
|
||
1. 前往 https://github.com/settings/tokens → **Generate new token (classic)**
|
||
2. 勾选 `repo` 权限(需要完整 repo 访问才能创建 Release)
|
||
3. 生成后保存 token
|
||
|
||
```bash
|
||
# 设置环境变量(建议写入 ~/.zshrc 或 CI Secret)
|
||
export GH_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||
```
|
||
|
||
### 第二步:版本号管理
|
||
|
||
每次发布前必须更新 `package.json` 中的 `version` 字段。`electron-updater` 客户端通过对比本地版本号和 `latest.yml` 中的版本号来判断是否有更新。
|
||
|
||
```bash
|
||
# 编辑版本号
|
||
cd mateclaw-desktop
|
||
vim package.json # 修改 "version": "1.0.0" → "1.1.0"
|
||
```
|
||
|
||
版本号遵循 [SemVer](https://semver.org/):
|
||
- 修复 bug → `1.0.0` → `1.0.1`
|
||
- 新功能 → `1.0.0` → `1.1.0`
|
||
- 破坏性变更 → `1.0.0` → `2.0.0`
|
||
|
||
### 第三步:构建并发布
|
||
|
||
```bash
|
||
cd mateclaw-desktop
|
||
|
||
# 一键构建全平台 + 自动上传到 GitHub Releases
|
||
export GH_TOKEN=ghp_xxxxxxxxxxxx
|
||
bash scripts/build-all-platforms.sh --all --publish=always
|
||
```
|
||
|
||
这会自动:
|
||
1. 构建后端 JAR
|
||
2. 下载各平台 JRE
|
||
3. 编译前端
|
||
4. 打包 macOS(DMG + ZIP)和 Windows(NSIS)
|
||
5. 生成 `latest.yml` 和 `latest-mac.yml`
|
||
6. 创建 GitHub Draft Release 并上传所有产物
|
||
|
||
完成后前往 https://github.com/matevip/mateclaw/releases ,找到 Draft Release:
|
||
- 填写 Release Notes(更新说明)
|
||
- 点击 **Publish release** 正式发布
|
||
|
||
也可以仅构建特定平台:
|
||
|
||
```bash
|
||
bash scripts/build-all-platforms.sh --mac-only --publish=always # 仅 macOS
|
||
bash scripts/build-all-platforms.sh --win-only --publish=always # 仅 Windows
|
||
```
|
||
|
||
### 第四步(可选):手动发布
|
||
|
||
如果不想用 `--publish=always` 自动上传:
|
||
|
||
```bash
|
||
# 1. 仅构建,不上传
|
||
bash scripts/build-all-platforms.sh --all
|
||
|
||
# 2. 查看生成的产物
|
||
ls -la release/
|
||
# 产物包括:
|
||
# MateClaw_1.1.0_arm64.dmg macOS ARM64 安装包
|
||
# MateClaw_1.1.0_x64.dmg macOS x64 安装包
|
||
# MateClaw_1.1.0_arm64.zip macOS ARM64 更新包(升级用)
|
||
# MateClaw_1.1.0_x64.zip macOS x64 更新包(升级用)
|
||
# MateClaw_1.1.0_x64_Setup.exe Windows x64 安装包
|
||
# MateClaw_1.1.0_arm64_Setup.exe Windows ARM64 安装包
|
||
# MateClaw_1.1.0_*.blockmap 差分下载支持文件
|
||
# latest.yml Windows 更新元数据
|
||
# latest-mac.yml macOS 更新元数据
|
||
|
||
# 3. 在 GitHub 手动创建 Release
|
||
# Tag: v1.1.0
|
||
# 上传 release/ 目录中的所有 .exe .zip .dmg .blockmap .yml 文件
|
||
```
|
||
|
||
> **注意**:`latest.yml` 和 `latest-mac.yml` 必须上传,客户端靠它们检测新版本。
|
||
|
||
---
|
||
|
||
## macOS 代码签名与公证
|
||
|
||
macOS 自动升级**必须**签名+公证,否则 Gatekeeper 会阻止更新后的应用启动。未签名时 macOS 用户只能手动下载 DMG 安装。
|
||
|
||
> **证书创建完整指南**:首次配置或证书过期时,参见 [CODESIGNING.md](./CODESIGNING.md)(含 CSR 生成、证书创建、.p12 导出、公证配置等完整步骤)。
|
||
|
||
### 本地签名构建(推荐)
|
||
|
||
证书安装到本地钥匙串后,**不需要设置 `CSC_LINK`**,electron-builder 会自动发现证书:
|
||
|
||
```bash
|
||
# 只需设置公证相关变量
|
||
export APPLE_ID=your@apple.id
|
||
export APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx # 在 appleid.apple.com 生成
|
||
export APPLE_TEAM_ID=XXXXXXXXXX # 10 位团队 ID
|
||
|
||
bash scripts/build-all-platforms.sh --mac-only --publish=always
|
||
```
|
||
|
||
`electron-builder` 会自动完成签名 → 公证 → 装订(staple)→ 上传。
|
||
|
||
> **注意**:不要设置 `CSC_LINK` 环境变量,否则 electron-builder 会创建临时钥匙串,可能导致签名卡死。详见 [CODESIGNING.md](./CODESIGNING.md) 故障排查章节。
|
||
|
||
### CI/CD 签名构建
|
||
|
||
CI 环境无本地钥匙串,需通过 `CSC_LINK` 指定 `.p12` 文件(Base64 编码存入 GitHub Secret):
|
||
|
||
```bash
|
||
export CSC_LINK=base64_encoded_p12_content
|
||
export CSC_KEY_PASSWORD=your_certificate_password
|
||
export APPLE_ID=your@apple.id
|
||
export APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx
|
||
export APPLE_TEAM_ID=XXXXXXXXXX
|
||
|
||
bash scripts/build-all-platforms.sh --mac-only --publish=always
|
||
```
|
||
|
||
### 公证超时处理
|
||
|
||
如果公证上传超时(`deadlineExceeded`),可先跳过公证构建,再用 `xcrun notarytool` 手动公证:
|
||
|
||
```bash
|
||
# 1. 去掉公证变量,仅签名出包
|
||
unset APPLE_ID APPLE_APP_SPECIFIC_PASSWORD APPLE_TEAM_ID
|
||
bash scripts/build-all-platforms.sh --mac-only
|
||
|
||
# 2. 手动公证(支持断点续传)
|
||
xcrun notarytool submit release/MateClaw_*.zip \
|
||
--apple-id your@apple.id \
|
||
--password "app专用密码" \
|
||
--team-id XXXXXXXXXX \
|
||
--wait
|
||
|
||
# 3. 装订公证票据
|
||
xcrun stapler staple release/MateClaw_*.dmg
|
||
```
|
||
|
||
### 跳过签名(开发/测试用)
|
||
|
||
```bash
|
||
export CSC_IDENTITY_AUTO_DISCOVERY=false
|
||
bash scripts/build-all-platforms.sh --mac-only
|
||
```
|
||
|
||
---
|
||
|
||
## Windows 代码签名(可选)
|
||
|
||
未签名的 Windows 安装包会触发 SmartScreen 警告("Windows 已保护你的电脑"),用户可以点击"仍要运行"。签名可消除此警告。
|
||
|
||
### EV 代码签名证书
|
||
|
||
推荐使用 EV(Extended Validation)证书,可立即获得 SmartScreen 信誉,无需积累安装量。
|
||
|
||
证书提供商(参考):
|
||
- [DigiCert](https://www.digicert.com/signing/code-signing-certificates) — 需硬件 token
|
||
- [SSL.com](https://www.ssl.com/certificates/ev-code-signing/) — 支持云签名
|
||
- [Certum](https://shop.certum.eu/code-signing-certificates/) — 较便宜的选项
|
||
|
||
### 配置
|
||
|
||
```bash
|
||
# PFX 文件签名
|
||
export WIN_CSC_LINK=/path/to/windows-cert.pfx
|
||
export WIN_CSC_KEY_PASSWORD=password
|
||
|
||
# 或使用 signtool(需要硬件 token 的 EV 证书)
|
||
# 在 electron-builder.json 的 win 节中配置:
|
||
# "signingHashAlgorithms": ["sha256"],
|
||
# "sign": "./scripts/sign.js"
|
||
```
|
||
|
||
---
|
||
|
||
## CI/CD 自动发布(GitHub Actions)
|
||
|
||
以下为 GitHub Actions 完整示例,实现 Git tag 推送时自动构建全平台并发布:
|
||
|
||
```yaml
|
||
# .github/workflows/release.yml
|
||
name: Release Desktop
|
||
|
||
on:
|
||
push:
|
||
tags:
|
||
- 'v*' # 推送 v1.0.0 等 tag 时触发
|
||
|
||
jobs:
|
||
release-mac:
|
||
runs-on: macos-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 20
|
||
|
||
- uses: actions/setup-java@v4
|
||
with:
|
||
distribution: temurin
|
||
java-version: 21
|
||
|
||
- name: Build and publish macOS
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
CSC_LINK: ${{ secrets.MAC_CSC_LINK }}
|
||
CSC_KEY_PASSWORD: ${{ secrets.MAC_CSC_KEY_PASSWORD }}
|
||
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
||
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||
run: |
|
||
cd mateclaw-desktop
|
||
npm install
|
||
bash scripts/build-all-platforms.sh --mac-only --publish=always
|
||
|
||
release-win:
|
||
runs-on: windows-latest
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- uses: actions/setup-node@v4
|
||
with:
|
||
node-version: 20
|
||
|
||
- uses: actions/setup-java@v4
|
||
with:
|
||
distribution: temurin
|
||
java-version: 21
|
||
|
||
- name: Build and publish Windows
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
cd mateclaw-desktop
|
||
npm install
|
||
bash scripts/build-all-platforms.sh --win-only --publish=always
|
||
```
|
||
|
||
### 配置 CI Secrets
|
||
|
||
在 GitHub 仓库 → Settings → Secrets and variables → Actions → New repository secret:
|
||
|
||
| Secret 名称 | 说明 |
|
||
|-------------|------|
|
||
| `MAC_CSC_LINK` | macOS 签名证书 .p12 的 Base64 编码:`base64 -i cert.p12 \| tr -d '\n'` |
|
||
| `MAC_CSC_KEY_PASSWORD` | .p12 证书密码 |
|
||
| `APPLE_ID` | Apple ID 邮箱 |
|
||
| `APPLE_APP_SPECIFIC_PASSWORD` | App 专用密码 |
|
||
| `APPLE_TEAM_ID` | 10 位开发者团队 ID |
|
||
| `GITHUB_TOKEN` | 自动提供,无需手动配置 |
|
||
|
||
### 发布流程(CI 方式)
|
||
|
||
```bash
|
||
# 1. 更新版本号
|
||
cd mateclaw-desktop
|
||
vim package.json # "version": "1.1.0"
|
||
|
||
# 2. 提交并打 tag
|
||
git add -A && git commit -m "release: v1.1.0"
|
||
git tag v1.1.0
|
||
git push origin main --tags
|
||
|
||
# 3. GitHub Actions 自动构建并创建 Draft Release
|
||
# 4. 前往 GitHub Releases 确认并发布
|
||
```
|
||
|
||
---
|
||
|
||
## 本地测试自动升级
|
||
|
||
### 方式一:开发模式 + dev-app-update.yml
|
||
|
||
在开发模式下测试 updater 流程(不需要打包):
|
||
|
||
```bash
|
||
# 1. 在 mateclaw-desktop/ 根目录创建 dev-app-update.yml
|
||
cat > dev-app-update.yml << 'EOF'
|
||
provider: generic
|
||
url: http://localhost:8080/
|
||
EOF
|
||
|
||
# 2. 构建一个"新版本"的产物
|
||
# 先把 package.json 的 version 改为更高版本(如 9.9.9)
|
||
# 然后构建:
|
||
npm run build
|
||
npx electron-builder --mac --publish=never # 或 --win
|
||
# 构建完成后把 version 改回原值
|
||
|
||
# 3. 启动本地文件服务器
|
||
cd release && python3 -m http.server 8080
|
||
|
||
# 4. 另一个终端启动开发模式
|
||
cd mateclaw-desktop && npm run dev
|
||
# updater 会从 localhost:8080 检查更新并发现"新版本"
|
||
```
|
||
|
||
> 开发模式下 `quitAndInstall()` 不会真正安装,但可验证检查→发现→下载的完整流程。
|
||
|
||
### 方式二:打包后端到端测试(推荐)
|
||
|
||
```bash
|
||
# 1. 打包 v1.0.0 并安装到系统
|
||
# 2. 修改 package.json version 为 v1.1.0
|
||
# 3. 重新构建,产物上传到 GitHub Release(或本地服务器)
|
||
# 4. 启动已安装的 v1.0.0,观察完整升级流程:
|
||
# 检查更新 → 发现 v1.1.0 → 下载 → 重启安装
|
||
```
|
||
|
||
---
|
||
|
||
## 发布检查单
|
||
|
||
- [ ] `package.json` 版本号已更新
|
||
- [ ] 后端 JAR 已构建(`npm run setup:jar`)
|
||
- [ ] 各平台 JRE 已下载
|
||
- [ ] `npm run build` 编译通过
|
||
- [ ] `GH_TOKEN` 环境变量已设置
|
||
- [ ] macOS 签名证书环境变量已设置(若需要签名)
|
||
- [ ] `bash scripts/build-all-platforms.sh --all --publish=always` 执行成功
|
||
- [ ] GitHub Draft Release 已确认发布
|
||
- [ ] 在旧版本应用上验证升级通知正常
|
||
|
||
## 技术栈
|
||
|
||
- **Electron** - 桌面应用框架
|
||
- **Vite + Vue 3** - Splash Screen 构建
|
||
- **electron-builder** + **electron-updater** - 跨平台打包与自动升级
|
||
- **Adoptium JRE 21** - 内置 Java 运行时
|