diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a34d019 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,209 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Tag to publish (e.g. v2.1.0). Leave empty to use the most recent tag.' + required: false + default: '' + +permissions: + contents: write + +jobs: + portable-windows: + name: Portable Windows zip + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - name: Read OpenClaw version + id: openclaw_version + shell: bash + run: | + version=$(tr -d '[:space:]' < OPENCLAW_VERSION) + echo "version=$version" >> "$GITHUB_OUTPUT" + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Run portable setup (Windows) + shell: cmd + run: | + cd portable + call setup.bat + + - name: Stage portable folder + shell: bash + run: | + mkdir -p dist + tag_name="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" + stage_dir="dist/u-claw-portable-windows-${tag_name}" + mkdir -p "$stage_dir" + cp -R portable/. "$stage_dir/" + # Drop dev-only large files we don't ship + rm -rf "$stage_dir/data/logs" 2>/dev/null || true + + - name: Zip portable + shell: pwsh + run: | + $tag = if ($env:GITHUB_REF_NAME) { $env:GITHUB_REF_NAME } else { '${{ github.event.inputs.tag }}' } + $stage = "dist/u-claw-portable-windows-$tag" + $out = "dist/u-claw-portable-windows-$tag.zip" + Compress-Archive -Path "$stage/*" -DestinationPath $out -CompressionLevel Optimal + + - uses: actions/upload-artifact@v4 + with: + name: portable-windows + path: dist/u-claw-portable-windows-*.zip + + portable-mac: + name: Portable macOS zip + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Run portable setup (mac) + run: | + cd portable + bash setup.sh + + - name: Stage portable folder + run: | + mkdir -p dist + tag_name="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" + stage_dir="dist/u-claw-portable-mac-${tag_name}" + mkdir -p "$stage_dir" + cp -R portable/. "$stage_dir/" + rm -rf "$stage_dir/data/logs" 2>/dev/null || true + + - name: Zip portable + run: | + tag_name="${GITHUB_REF_NAME:-${{ github.event.inputs.tag }}}" + cd dist + zip -qry "u-claw-portable-mac-${tag_name}.zip" "u-claw-portable-mac-${tag_name}" + + - uses: actions/upload-artifact@v4 + with: + name: portable-mac + path: dist/u-claw-portable-mac-*.zip + + desktop-windows: + name: Electron Windows installer + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + shell: cmd + run: | + cd u-claw-app + npm install --registry=https://registry.npmmirror.com + + - name: Build Windows installer + shell: cmd + run: | + cd u-claw-app + npm run build:win + env: + # Skip code signing — we ship unsigned. README documents the SmartScreen workaround. + CSC_IDENTITY_AUTO_DISCOVERY: 'false' + + - uses: actions/upload-artifact@v4 + with: + name: desktop-windows + path: | + u-claw-app/release/*.exe + u-claw-app/release/*.exe.blockmap + + desktop-mac: + name: Electron macOS DMG + runs-on: macos-14 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install dependencies + run: | + cd u-claw-app + npm install --registry=https://registry.npmmirror.com + + - name: Build macOS DMG + run: | + cd u-claw-app + npm run build:mac-arm64 + env: + CSC_IDENTITY_AUTO_DISCOVERY: 'false' + + - uses: actions/upload-artifact@v4 + with: + name: desktop-mac + path: | + u-claw-app/release/*.dmg + u-claw-app/release/*.dmg.blockmap + + publish: + name: Publish GitHub Release + needs: [portable-windows, portable-mac, desktop-windows, desktop-mac] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + path: artifacts + + - name: Resolve tag + id: tag + run: | + if [ -n "${{ github.event.inputs.tag }}" ]; then + tag="${{ github.event.inputs.tag }}" + else + tag="${GITHUB_REF_NAME}" + fi + echo "tag=$tag" >> "$GITHUB_OUTPUT" + + - name: Read OpenClaw version + id: openclaw_version + run: | + version=$(tr -d '[:space:]' < OPENCLAW_VERSION) + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Create or update release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ steps.tag.outputs.tag }} + name: U-Claw ${{ steps.tag.outputs.tag }} + body: | + ## U-Claw ${{ steps.tag.outputs.tag }} + + - 内置虾盘云:首次启动自动绑定本机/U盘指纹,生成 `sk-...` apiKey + - OpenClaw runtime: `${{ steps.openclaw_version.outputs.version }}` + - 充值入口:https://u-claw.org/cloud.html + + > Windows 安装包未做代码签名,首次运行需在 SmartScreen 选择"仍要运行"。 + > macOS DMG 未做公证,首次启动需 `xattr -rd com.apple.quarantine /Applications/U-Claw.app` 或右键打开。 + files: | + artifacts/portable-windows/* + artifacts/portable-mac/* + artifacts/desktop-windows/* + artifacts/desktop-mac/* + fail_on_unmatched_files: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/OPENCLAW_VERSION b/OPENCLAW_VERSION new file mode 100644 index 0000000..8f8eb0c --- /dev/null +++ b/OPENCLAW_VERSION @@ -0,0 +1 @@ +2026.4.29 diff --git a/README.md b/README.md index c947e30..636ffdd 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,18 @@ U-Claw(虾盘)是一个**制作教程 + 全套源代码**,教你把 [OpenC > 📖 **[完整教程](https://u-claw.org/tutorial.html)** — 从零开始的手工安装指南、模型配置、聊天平台接入,小白也能看懂。 +### 🔗 内置虾盘云:开箱即用 + +每个 U-Claw 实例首次启动会**自动**根据当前 U 盘 / 硬盘的指纹生成一个 `sk-...` 形式的虾盘云 apiKey,并写入 `data/.openclaw/openclaw.json`。打开 Config.html 就能看到这张「已绑定虾盘云」横幅(指纹来源、Key、余额)。 + +- **不送 token**:余额初始为 0,需自行充值([u-claw.org/cloud.html](https://u-claw.org/cloud.html)) +- **指纹规则**: + - 从 U 盘根目录启动 → 绑定该 U 盘的硬件指纹(USB Serial + PNPDeviceID) + - 从硬盘启动(电脑安装版 / Electron App)→ 绑定主板 + 系统盘指纹 + - Mac/Linux 走 Hardware UUID / `/etc/machine-id` + 启动盘 UUID +- **换机 / 换盘**:换 U 盘或换电脑后,新的指纹会生成新的 Key;旧 Key 的余额仍归属原指纹(在 Config.html 点「解绑」可触发重新绑定) +- **隐私**:指纹只用于本地生成 Key,不上传,无登录 + ### 一键安装(推荐) 不需要 U 盘,一行命令直接装到电脑: @@ -108,6 +120,19 @@ npm run build:mac-arm64 # 打包 → release/*.dmg npm run build:win # 打包 → release/*.exe ``` +### 直接下载发行版 + +[GitHub Releases](https://github.com/dongsheng123132/u-claw/releases) 提供四种打包好的产物: + +- `u-claw-portable-windows-vX.Y.Z.zip` — Windows 便携版(解压即用) +- `u-claw-portable-mac-vX.Y.Z.zip` — Mac 便携版 +- `U-Claw Setup vX.Y.Z.exe` — Windows 桌面安装包 +- `U-Claw-vX.Y.Z-arm64.dmg` — Mac 桌面安装包 + +> ⚠️ 安装包未签名: +> - **Windows**:双击 `.exe` 时 SmartScreen 会拦,点「更多信息」→「仍要运行」 +> - **Mac**:首次启动如被 Gatekeeper 拦,执行 `xattr -rd com.apple.quarantine /Applications/U-Claw.app` 或在 Finder 里右键→打开 + ### 支持的 AI 模型 **国产模型(无需翻墙):** diff --git a/install/install.sh b/install/install.sh index 85930d4..fcaa82e 100755 --- a/install/install.sh +++ b/install/install.sh @@ -176,13 +176,14 @@ if [ -d "$CORE_DIR/node_modules/openclaw" ]; then echo -e " ${GREEN}✓${NC} OpenClaw 已安装,跳过" else if [ ! -f "$CORE_DIR/package.json" ]; then - cat > "$CORE_DIR/package.json" << 'PKGJSON' + OPENCLAW_VERSION="2026.4.29" + cat > "$CORE_DIR/package.json" << PKGJSON { "name": "u-claw-core", "version": "1.0.0", "private": true, "dependencies": { - "openclaw": "latest" + "openclaw": "$OPENCLAW_VERSION" } } PKGJSON diff --git a/portable/Config.html b/portable/Config.html index f937819..f40d93e 100644 --- a/portable/Config.html +++ b/portable/Config.html @@ -151,6 +151,26 @@ input:focus { border-color: #ff6b35; }

🦞 U-Claw Pro

便携版 — 选择模型,填入 API Key,一键启动

+ + +
1选模型
@@ -388,6 +408,50 @@ input:focus { border-color: #ff6b35; }
- - diff --git a/u-claw-app/package.json b/u-claw-app/package.json index b695870..bcf45b7 100644 --- a/u-claw-app/package.json +++ b/u-claw-app/package.json @@ -7,13 +7,14 @@ "license": "MIT", "homepage": "https://u-claw.org", "scripts": { - "start": "electron .", - "dev": "electron . --dev", - "build:mac": "electron-builder --mac", - "build:mac-arm64": "electron-builder --mac --arm64", - "build:mac-x64": "electron-builder --mac --x64", - "build:win": "electron-builder --win", - "build:all": "electron-builder --mac --win", + "sync-lib": "node scripts/sync-lib.js", + "start": "npm run sync-lib && electron .", + "dev": "npm run sync-lib && electron . --dev", + "build:mac": "npm run sync-lib && electron-builder --mac", + "build:mac-arm64": "npm run sync-lib && electron-builder --mac --arm64", + "build:mac-x64": "npm run sync-lib && electron-builder --mac --x64", + "build:win": "npm run sync-lib && electron-builder --win", + "build:all": "npm run sync-lib && electron-builder --mac --win", "postinstall": "electron-builder install-app-deps" }, "build": { diff --git a/u-claw-app/resources/Config.html b/u-claw-app/resources/Config.html index b570e91..f40d93e 100644 --- a/u-claw-app/resources/Config.html +++ b/u-claw-app/resources/Config.html @@ -48,16 +48,51 @@ h1 .lobster { color: #ff6b35; } .buy-link:hover { text-decoration: underline; } /* Forms */ -.form-group { margin-bottom: 16px; } -label { display: block; color: #ccc; margin-bottom: 6px; font-size: 0.9em; } -input[type="text"], input[type="password"] { - width: 100%; padding: 11px 14px; background: #222; border: 1px solid #444; border-radius: 8px; - color: #fff; font-size: 0.95em; outline: none; transition: border-color 0.2s; +.form-group { display: block; margin-bottom: 16px; clear: both; } +.form-group label { + display: block; + width: auto; + float: none; + color: #ccc; + margin-bottom: 8px; + font-size: 0.9em; +} +.form-group input, +input[type="text"], +input[type="password"] { + display: block; + width: 100%; + min-width: 0; + min-height: 46px; + padding: 11px 14px; + background: #222; + border: 1px solid #444; + border-radius: 8px; + color: #fff; + font-size: 0.95em; + line-height: 1.3; + outline: none; + transition: border-color 0.2s; } input:focus { border-color: #ff6b35; } -.input-wrap { position: relative; } -.input-wrap input { padding-right: 44px; } -.toggle-pw { position: absolute; right: 12px; top: 50%; transform: translateY(-50%); background: none; border: none; color: #888; cursor: pointer; font-size: 0.85em; } +.input-wrap { position: relative; display: block; width: 100%; min-width: 0; } +.input-wrap input { padding-right: 64px; } +.toggle-pw { + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + min-width: 38px; + height: 30px; + background: #2d2d2d; + border: 1px solid #444; + border-radius: 6px; + color: #ccc; + cursor: pointer; + font-size: 0.82em; + line-height: 28px; + text-align: center; +} .toggle-pw:hover { color: #ccc; } .hint { color: #888; font-size: 0.8em; margin-top: 6px; line-height: 1.5; } .hint a { color: #ff6b35; text-decoration: none; } @@ -116,6 +151,26 @@ input:focus { border-color: #ff6b35; }

🦞 U-Claw Pro

便携版 — 选择模型,填入 API Key,一键启动

+ + +
1选模型
@@ -353,16 +408,60 @@ input:focus { border-color: #ff6b35; }