diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..761e19e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,26 @@ +# 统一使用 LF 行尾(适配 macOS / Linux / Windows 跨平台协作) +* text=auto eol=lf + +# Windows 批处理脚本保持 CRLF +*.bat text eol=crlf +*.cmd text eol=crlf + +# 二进制文件不处理行尾 +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.icns binary +*.woff binary +*.woff2 binary +*.ttf binary +*.otf binary +*.zip binary +*.exe binary +*.dll binary +*.dylib binary +*.so binary + +# Rust 锁文件 +Cargo.lock text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0f28db5..c3b38cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,11 +70,21 @@ jobs: libgtk-3-dev \ libayatana-appindicator3-dev + # Rust 格式检查 + - name: Rust 格式检查 + working-directory: src-tauri + run: cargo fmt --all -- --check + # Rust 编译检查 - name: Rust 编译检查 working-directory: src-tauri run: cargo check + # Rust Lint(警告视为错误) + - name: Rust Clippy + working-directory: src-tauri + run: cargo clippy --all-targets -- -D warnings + # 前端构建验证 - name: 前端构建验证 run: npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a52677e..3496c10 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,8 @@ on: default: 'v1.0.0' jobs: - release: + # ── 跨平台构建 job ───────────────────────────────────────────────────────── + build: name: 构建 (${{ matrix.platform.name }}) runs-on: ${{ matrix.platform.os }} permissions: @@ -24,58 +25,59 @@ jobs: fail-fast: false matrix: platform: - # macOS Apple Silicon (ARM64) - - name: macOS (ARM64) + - name: macOS (Apple Silicon) os: macos-latest args: --target aarch64-apple-darwin rust_target: aarch64-apple-darwin - # macOS Intel (x64) - name: macOS (Intel) os: macos-latest args: --target x86_64-apple-darwin rust_target: x86_64-apple-darwin - # Linux x86_64 - name: Linux (x64) os: ubuntu-latest args: "" rust_target: "" - # Windows x86_64 - name: Windows (x64) os: windows-latest args: "" rust_target: "" steps: - # 签出代码 - name: 签出代码 uses: actions/checkout@v4 with: fetch-depth: 0 - # 安装 Node.js 22 + - name: 设置版本标签 + id: vars + shell: bash + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> "$GITHUB_ENV" + else + echo "TAG_NAME=${{ github.ref_name }}" >> "$GITHUB_ENV" + fi + - name: 安装 Node.js uses: actions/setup-node@v4 with: node-version: 22 cache: npm - # 安装前端依赖 - name: 安装前端依赖 run: npm ci - # 安装 Rust 工具链 (stable) - name: 安装 Rust 工具链 uses: dtolnay/rust-toolchain@stable with: targets: ${{ matrix.platform.rust_target }} - # Rust 编译缓存 - name: Rust 编译缓存 uses: swatinem/rust-cache@v2 with: workspaces: src-tauri -> target + key: ${{ matrix.platform.name }} - # Linux 专用: 安装 Tauri v2 系统依赖 - name: 安装 Linux 系统依赖 if: runner.os == 'Linux' run: | @@ -88,61 +90,108 @@ jobs: libgtk-3-dev \ libayatana-appindicator3-dev - - name: 设置 Release 标签 - id: vars + - name: 构建 Tauri 应用 + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # macOS 代码签名(可选) + # APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + # APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + # APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} + # APPLE_ID: ${{ secrets.APPLE_ID }} + # APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + # APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + # Windows 代码签名(可选) + # TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} + # TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} + with: + tagName: ${{ env.TAG_NAME }} + releaseName: "ClawPanel ${{ env.TAG_NAME }}" + releaseBody: "正在构建所有平台安装包,请稍候..." + releaseDraft: false + prerelease: false + args: ${{ matrix.platform.args }} + + # ── 所有平台构建完成后,统一更新 Release Notes ───────────────────────────── + # 独立 job 确保只执行一次,彻底避免多个 matrix job 的竞争条件 + update-release-notes: + name: 更新 Release Notes + needs: build + runs-on: ubuntu-latest + if: always() && needs.build.result != 'cancelled' + permissions: + contents: write + + steps: + - name: 签出代码 + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: 设置版本标签 shell: bash run: | if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then - echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> $GITHUB_ENV + echo "TAG_NAME=${{ github.event.inputs.tag_name }}" >> "$GITHUB_ENV" else - echo "TAG_NAME=${{ github.ref_name }}" >> $GITHUB_ENV + echo "TAG_NAME=${{ github.ref_name }}" >> "$GITHUB_ENV" fi - # 生成 Release Body(下载引导 + 动态 changelog) - - name: 生成 Release Body - id: release_body + - name: 生成并更新 Release Notes shell: bash + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BUILD_RESULT: ${{ needs.build.result }} run: | VERSION="${TAG_NAME#v}" - # 获取上一个 tag,用于生成 changelog PREV_TAG=$(git tag --sort=-v:refname | grep -E '^v' | sed -n '2p' || echo "") - - # 动态生成 changelog if [ -n "$PREV_TAG" ]; then - CHANGELOG=$(git log "${PREV_TAG}..HEAD" --pretty=format:"- %s" --no-merges | head -30) - CHANGELOG_HEADER="自 ${PREV_TAG} 以来的更新" + CHANGELOG=$(git log "${PREV_TAG}..HEAD" --pretty=format:"- %s" --no-merges | head -30 || echo "") + CHANGELOG_HEADER="自 ${PREV_TAG} 以来的变更" else - CHANGELOG=$(git log --pretty=format:"- %s" --no-merges -20) - CHANGELOG_HEADER="主要更新" + CHANGELOG=$(git log --pretty=format:"- %s" --no-merges -20 || echo "") + CHANGELOG_HEADER="主要变更" fi - # 写入 Release Body + # 构建状态标记 + if [ "$BUILD_RESULT" = "success" ]; then + STATUS_BADGE="✅ 全部平台构建成功" + else + STATUS_BADGE="⚠️ 部分平台构建失败,请查看 [Actions 日志](https://github.com/${{ github.repository }}/actions)" + fi + + cat > release_body.md << 'ENDOFBODY' + PLACEHOLDER + ENDOFBODY + cat > release_body.md << ENDOFBODY + ${STATUS_BADGE} + ## 下载安装 根据你的操作系统选择对应安装包: ### macOS - | 芯片 | 安装包 | 说明 | - |------|--------|------| - | Apple Silicon (M1/M2/M3/M4) | \`ClawPanel_${VERSION}_aarch64.dmg\` | 2020 年末及之后的 Mac | - | Intel | \`ClawPanel_${VERSION}_x64.dmg\` | 2020 年及之前的 Mac | + | 芯片 | 安装包 | + |------|--------| + | Apple Silicon (M1/M2/M3/M4) | \`ClawPanel_${VERSION}_aarch64.dmg\` | + | Intel | \`ClawPanel_${VERSION}_x64.dmg\` | - > 不确定芯片类型?点击左上角 → 关于本机,查看「芯片」一栏。 + > 首次打开提示"无法验证开发者":前往**系统设置 → 隐私与安全性**,点击「仍要打开」。 ### Windows - | 格式 | 安装包 | 说明 | - |------|--------|------| - | EXE 安装器 | \`ClawPanel_${VERSION}_x64-setup.exe\` | 推荐,双击安装 | - | MSI 安装器 | \`ClawPanel_${VERSION}_x64_en-US.msi\` | 企业部署 / 静默安装 | + | 格式 | 安装包 | + |------|--------| + | EXE 安装器(推荐) | \`ClawPanel_${VERSION}_x64-setup.exe\` | + | MSI 安装器 | \`ClawPanel_${VERSION}_x64_en-US.msi\` | ### Linux - | 格式 | 安装包 | 说明 | - |------|--------|------| - | AppImage | \`ClawPanel_${VERSION}_amd64.AppImage\` | 免安装,\`chmod +x\` 后直接运行 | - | DEB | \`ClawPanel_${VERSION}_amd64.deb\` | Debian / Ubuntu:\`sudo dpkg -i *.deb\` | - | RPM | \`ClawPanel-${VERSION}-1.x86_64.rpm\` | Fedora / RHEL:\`sudo rpm -i *.rpm\` | + | 格式 | 安装包 | + |------|--------| + | AppImage(免安装) | \`ClawPanel_${VERSION}_amd64.AppImage\` | + | DEB(Debian/Ubuntu) | \`ClawPanel_${VERSION}_amd64.deb\` | + | RPM(Fedora/RHEL) | \`ClawPanel-${VERSION}-1.x86_64.rpm\` | --- @@ -152,34 +201,7 @@ jobs: --- - 完整更新日志请查看 [CHANGELOG.md](https://github.com/qingchencloud/clawpanel/blob/main/CHANGELOG.md) + 完整日志见 [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) ENDOFBODY - # 去除 heredoc 缩进 - sed -i.bak 's/^ //' release_body.md && rm -f release_body.md.bak - - # 使用 tauri-action 构建并发布 - - name: 构建 Tauri 应用 - uses: tauri-apps/tauri-action@v0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tagName: ${{ env.TAG_NAME }} - releaseName: "ClawPanel ${{ env.TAG_NAME }}" - releaseBody: "构建中,稍后更新..." - releaseDraft: false - prerelease: false - args: ${{ matrix.platform.args }} - - # 更新 Release Body(仅第一个完成的 job 执行) - - name: 更新 Release 描述 - if: always() - shell: bash - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - # 检查当前 Release body 是否为空或默认值,避免重复更新 - CURRENT_BODY=$(gh release view "$TAG_NAME" --json body -q '.body' 2>/dev/null || echo "") - if [ ${#CURRENT_BODY} -lt 100 ]; then - gh release edit "$TAG_NAME" --notes-file release_body.md - fi + gh release edit "$TAG_NAME" --notes-file release_body.md diff --git a/.gitignore b/.gitignore index 564d1c1..a0ffd02 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,44 @@ +# 依赖 node_modules/ + +# 构建产物 dist/ src-tauri/target/ + +# 日志 *.log +tauri-dev.log +api_doc_mcp.log + +# macOS .DS_Store +.AppleDouble +.LSOverride + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ +*.lnk + +# 构建临时文件 +nul +release_body.md +release_body.md.bak + +# 内部开发文档(不入公开仓) +BLOCKING_ISSUES_REPORT.md + +# IDE / 编辑器 +.idea/ +*.iml +.vscode/settings.json +.vscode/launch.json +*.suo +*.user +*.userosscache +*.sln.docstates + +# Rust 开发工具 +src-tauri/.cargo/ diff --git a/.windsurf/workflows/release.md b/.windsurf/workflows/release.md new file mode 100644 index 0000000..116ad88 --- /dev/null +++ b/.windsurf/workflows/release.md @@ -0,0 +1,64 @@ +--- +description: 发布新版本(打 tag + 推送,触发跨平台构建) +--- + +## 发布前检查 + +1. 确认所有改动已提交,工作区干净: +```bash +git status +``` + +2. 确认 CI 全部通过(main 分支绿灯) + +3. 更新 `CHANGELOG.md`,在顶部加入本次版本的变更记录 + +4. 更新 `src-tauri/tauri.conf.json` 中的 `version` 字段,与即将发布的版本号保持一致: +```json +{ "version": "1.2.3" } +``` + +5. 提交版本更新: +```bash +git add CHANGELOG.md src-tauri/tauri.conf.json +git commit -m "chore: release v1.2.3" +git push origin main +``` + +## 打 tag 并触发发布 + +```bash +git tag v1.2.3 +git push origin v1.2.3 +``` + +推送 tag 后,GitHub Actions 会自动: +- 并行构建 macOS ARM64 / macOS Intel / Linux / Windows 四个平台 +- 创建 GitHub Release 并上传安装包 +- 所有平台构建完成后统一写入 Release Notes + +## 查看构建进度 + +前往仓库 **Actions** 页面,找到 `Release` 工作流查看实时日志。 + +## 手动触发(不打 tag) + +在 GitHub Actions 页面手动触发 `Release` 工作流,输入版本号(如 `v1.2.3`)。 + +## 发布后验证 + +- [ ] Release 页面出现四个平台的安装包 +- [ ] Release Notes 内容正确(有下载表格 + changelog) +- [ ] 下载 Windows EXE 安装验证可用 +- [ ] `latest` 标签指向新 Release + +## 回滚 + +如果发布有问题,在 GitHub Releases 页面将该 Release 设为 Draft 或删除,然后修复后重新打 tag: +```bash +git tag -d v1.2.3 +git push origin :refs/tags/v1.2.3 +# 修复问题后 +git tag v1.2.3 +git push origin v1.2.3 +``` diff --git a/README.md b/README.md index 77df41a..062b49c 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ --- -ClawPanel 是 [OpenClaw](https://github.com/openclaw-labs/openclaw) AI Agent 框架的可视化管理面板,提供服务管控、模型配置、日志查看、记忆管理等核心功能,一站式管理你的 OpenClaw 实例。 +ClawPanel 是 [OpenClaw](https://github.com/openclaw/openclaw) AI Agent 框架的可视化管理面板,提供服务管控、模型配置、日志查看、记忆管理等核心功能,一站式管理你的 OpenClaw 实例。 ## 下载安装 @@ -176,7 +176,7 @@ npm run tauri build -- --bundles nsis | 项目 | 说明 | |------|------| -| [OpenClaw](https://github.com/openclaw-labs/openclaw) | AI Agent 框架 | +| [OpenClaw](https://github.com/openclaw/openclaw) | AI Agent 框架 | | [ClawApp](https://github.com/qingchencloud/clawapp) | 跨平台移动聊天客户端 | | [cftunnel](https://github.com/qingchencloud/cftunnel) | Cloudflare Tunnel 内网穿透工具 | diff --git a/build.ps1 b/build.ps1 new file mode 100644 index 0000000..2992a0d --- /dev/null +++ b/build.ps1 @@ -0,0 +1,123 @@ +#!/usr/bin/env pwsh +# ClawPanel 本地构建脚本(Windows) +# 用法: +# .\build.ps1 — 构建 Windows 安装包(默认) +# .\build.ps1 -Debug — Debug 构建(快,不打包) +# .\build.ps1 -Clean — 清理 Rust 编译缓存后构建 + +param( + [switch]$Debug, + [switch]$Clean +) + +$ErrorActionPreference = "Stop" + +function Write-Step([string]$msg) { + Write-Host "`n▶ $msg" -ForegroundColor Cyan +} +function Write-Ok([string]$msg) { + Write-Host " ✓ $msg" -ForegroundColor Green +} +function Write-Fail([string]$msg) { + Write-Host " ✗ $msg" -ForegroundColor Red +} + +Write-Host "" +Write-Host " ClawPanel 构建工具" -ForegroundColor Magenta +Write-Host " ─────────────────────────────────────" -ForegroundColor DarkGray +Write-Host " 平台: Windows x64 (本机构建)" -ForegroundColor DarkGray +Write-Host " 跨平台构建 (macOS / Linux) 请推送 tag 触发 GitHub Actions" -ForegroundColor DarkGray +Write-Host "" + +# ── 环境检测 ────────────────────────────────────────────────────────────────── + +Write-Step "检查构建依赖" + +if (-not (Get-Command node -ErrorAction SilentlyContinue)) { + Write-Fail "未找到 Node.js,请从 https://nodejs.org 安装 v18+" + exit 1 +} +$nodeVer = (node --version) +Write-Ok "Node.js $nodeVer" + +if (-not (Get-Command npm -ErrorAction SilentlyContinue)) { + Write-Fail "未找到 npm" + exit 1 +} + +if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) { + Write-Fail "未找到 Rust/Cargo,请从 https://rustup.rs 安装" + exit 1 +} +$rustVer = (rustc --version) +Write-Ok "Rust $rustVer" + +# 检测 WebView2(Windows 必须) +$webview2Key = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" +if (-not (Test-Path $webview2Key)) { + Write-Host " ⚠ 未检测到 WebView2 Runtime,目标用户需要安装" -ForegroundColor Yellow + Write-Host " 下载地址: https://developer.microsoft.com/microsoft-edge/webview2/" -ForegroundColor DarkGray +} + +# ── 依赖安装 ────────────────────────────────────────────────────────────────── + +Write-Step "安装前端依赖" +if (-not (Test-Path "node_modules")) { + npm ci --silent + if ($LASTEXITCODE -ne 0) { Write-Fail "npm ci 失败"; exit 1 } + Write-Ok "依赖安装完成" +} else { + Write-Ok "依赖已存在,跳过" +} + +# ── 清理缓存 ────────────────────────────────────────────────────────────────── + +if ($Clean) { + Write-Step "清理 Rust 编译缓存" + Push-Location src-tauri + cargo clean + Pop-Location + Write-Ok "缓存已清理" +} + +# ── 构建 ────────────────────────────────────────────────────────────────────── + +$startTime = Get-Date + +if ($Debug) { + Write-Step "Debug 构建(不打包安装器)" + npm run tauri build -- --debug +} else { + Write-Step "Release 构建(生成 Windows 安装包)" + npm run tauri build +} + +if ($LASTEXITCODE -ne 0) { + Write-Fail "构建失败" + exit 1 +} + +$elapsed = [math]::Round(((Get-Date) - $startTime).TotalSeconds) + +# ── 输出结果 ────────────────────────────────────────────────────────────────── + +Write-Host "" +Write-Host " ✅ 构建成功!耗时 ${elapsed}s" -ForegroundColor Green +Write-Host " ─────────────────────────────────────" -ForegroundColor DarkGray + +$bundleDir = "src-tauri\target\release\bundle" +if ($Debug) { + $exePath = "src-tauri\target\debug\clawpanel.exe" + Write-Host " 可执行文件: $exePath" -ForegroundColor White +} else { + Write-Host " 安装包目录: $bundleDir" -ForegroundColor White + $msi = Get-ChildItem "$bundleDir\msi\*.msi" -ErrorAction SilentlyContinue | Select-Object -First 1 + $exe = Get-ChildItem "$bundleDir\nsis\*-setup.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($msi) { Write-Host " MSI: $($msi.FullName)" -ForegroundColor DarkGray } + if ($exe) { Write-Host " EXE: $($exe.FullName)" -ForegroundColor DarkGray } +} + +Write-Host "" +Write-Host " 提示: 发布跨平台版本请推送 tag,例如:" -ForegroundColor DarkGray +Write-Host " git tag v1.0.0 && git push origin v1.0.0" -ForegroundColor DarkGray +Write-Host "" diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..f5f9901 --- /dev/null +++ b/build.sh @@ -0,0 +1,146 @@ +#!/usr/bin/env bash +# ClawPanel 本地构建脚本(macOS / Linux) +# 用法: +# ./build.sh — 构建当前平台安装包(默认) +# ./build.sh --debug — Debug 构建(快,不打包) +# ./build.sh --clean — 清理 Rust 编译缓存后构建 +set -euo pipefail + +DEBUG=false +CLEAN=false + +for arg in "$@"; do + case "$arg" in + --debug) DEBUG=true ;; + --clean) CLEAN=true ;; + esac +done + +RED='\033[0;31m'; GREEN='\033[0;32m'; CYAN='\033[0;36m' +MAGENTA='\033[0;35m'; GRAY='\033[0;90m'; RESET='\033[0m' + +step() { echo -e "\n${CYAN}▶ $1${RESET}"; } +ok() { echo -e " ${GREEN}✓ $1${RESET}"; } +fail() { echo -e " ${RED}✗ $1${RESET}"; exit 1; } + +echo "" +echo -e " ${MAGENTA}ClawPanel 构建工具${RESET}" +echo -e " ${GRAY}─────────────────────────────────────${RESET}" +if [[ "$(uname)" == "Darwin" ]]; then + ARCH=$(uname -m) + if [[ "$ARCH" == "arm64" ]]; then + echo -e " ${GRAY}平台: macOS Apple Silicon (aarch64)${RESET}" + else + echo -e " ${GRAY}平台: macOS Intel (x86_64)${RESET}" + fi +else + echo -e " ${GRAY}平台: Linux x86_64${RESET}" +fi +echo -e " ${GRAY}跨平台构建 (其他平台) 请推送 tag 触发 GitHub Actions${RESET}" +echo "" + +# ── 环境检测 ────────────────────────────────────────────────────────────────── + +step "检查构建依赖" + +if ! command -v node &>/dev/null; then + fail "未找到 Node.js,请从 https://nodejs.org 安装 v18+" +fi +ok "Node.js $(node --version)" + +if ! command -v cargo &>/dev/null; then + fail "未找到 Rust/Cargo,请从 https://rustup.rs 安装" +fi +ok "Rust $(rustc --version)" + +# macOS 额外检测 +if [[ "$(uname)" == "Darwin" ]]; then + if ! command -v xcode-select &>/dev/null || ! xcode-select -p &>/dev/null 2>&1; then + echo -e " ${YELLOW}⚠ 未找到 Xcode Command Line Tools${RESET}" + echo -e " 运行: xcode-select --install" + fi +fi + +# Linux 额外检测 +if [[ "$(uname)" == "Linux" ]]; then + MISSING=() + for pkg in libwebkit2gtk-4.1-dev libssl-dev libgtk-3-dev; do + if ! dpkg -s "$pkg" &>/dev/null 2>&1; then + MISSING+=("$pkg") + fi + done + if [ ${#MISSING[@]} -gt 0 ]; then + echo -e " ${RED}✗ 缺少系统依赖: ${MISSING[*]}${RESET}" + echo -e " 运行: sudo apt-get install -y ${MISSING[*]} libayatana-appindicator3-dev librsvg2-dev patchelf" + exit 1 + fi +fi + +# ── 依赖安装 ────────────────────────────────────────────────────────────────── + +step "安装前端依赖" +if [ ! -d "node_modules" ]; then + npm ci --silent + ok "依赖安装完成" +else + ok "依赖已存在,跳过" +fi + +# ── 清理缓存 ────────────────────────────────────────────────────────────────── + +if [ "$CLEAN" = true ]; then + step "清理 Rust 编译缓存" + (cd src-tauri && cargo clean) + ok "缓存已清理" +fi + +# ── 构建 ────────────────────────────────────────────────────────────────────── + +START_TIME=$(date +%s) + +if [ "$DEBUG" = true ]; then + step "Debug 构建(不打包安装器)" + npm run tauri build -- --debug +else + step "Release 构建" + # macOS Apple Silicon: 同时构建 ARM64 + Intel Universal Binary(可选) + if [[ "$(uname)" == "Darwin" ]] && [[ "$(uname -m)" == "arm64" ]]; then + # 确保 Intel target 已安装 + rustup target add x86_64-apple-darwin 2>/dev/null || true + echo -e " ${GRAY}构建 ARM64 版本...${RESET}" + npm run tauri build -- --target aarch64-apple-darwin + else + npm run tauri build + fi +fi + +END_TIME=$(date +%s) +ELAPSED=$((END_TIME - START_TIME)) + +# ── 输出结果 ────────────────────────────────────────────────────────────────── + +echo "" +echo -e " ${GREEN}✅ 构建成功!耗时 ${ELAPSED}s${RESET}" +echo -e " ${GRAY}─────────────────────────────────────${RESET}" + +if [ "$DEBUG" = true ]; then + echo -e " 可执行文件: src-tauri/target/debug/clawpanel" +else + BUNDLE_DIR="src-tauri/target/release/bundle" + if [[ "$(uname)" == "Darwin" ]]; then + DMG=$(find "$BUNDLE_DIR/dmg" -name "*.dmg" 2>/dev/null | head -1) + APP=$(find "$BUNDLE_DIR/macos" -name "*.app" -maxdepth 1 2>/dev/null | head -1) + [ -n "$DMG" ] && echo -e " DMG: ${GRAY}$DMG${RESET}" + [ -n "$APP" ] && echo -e " APP: ${GRAY}$APP${RESET}" + else + APPIMAGE=$(find "$BUNDLE_DIR/appimage" -name "*.AppImage" 2>/dev/null | head -1) + DEB=$(find "$BUNDLE_DIR/deb" -name "*.deb" 2>/dev/null | head -1) + [ -n "$APPIMAGE" ] && echo -e " AppImage: ${GRAY}$APPIMAGE${RESET}" + [ -n "$DEB" ] && echo -e " DEB: ${GRAY}$DEB${RESET}" + fi +fi + +echo "" +echo -e " ${GRAY}提示: 发布跨平台版本请推送 tag,例如:${RESET}" +echo -e " ${GRAY} git tag v1.0.0 && git push origin v1.0.0${RESET}" +echo "" diff --git a/docs/index.html b/docs/index.html index cbffbcb..ed1b176 100644 --- a/docs/index.html +++ b/docs/index.html @@ -310,7 +310,7 @@

相关项目

- +

OpenClaw

AI Agent 框架,支持多模型协作、工具调用、记忆管理

diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index df45fac..a9bbb70 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -342,6 +342,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-shell", + "tokio", "zip", ] @@ -4054,6 +4055,7 @@ dependencies = [ "libc", "mio", "pin-project-lite", + "signal-hook-registry", "socket2", "windows-sys 0.61.2", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index a6b5d46..5b4277e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -23,3 +23,4 @@ ed25519-dalek = { version = "2", features = ["rand_core"] } sha2 = "0.10" rand = "0.8" base64 = "0.22" +tokio = { version = "1", features = ["process", "time"] }