Some checks failed
Tests / test (push) Has been cancelled
不是翻译 —— 多数文档描述的行为已经不存在了。 先修一个更基本的问题:我们不拥有 u-claw.org 域名,那是上游的。所以之前写在 README、诊断包提示、联系方式里的 help@u-claw.org 全都会把用户的问题发给 上游 —— 一个没有理由回复的人。改为指向我们自己的 issue tracker,并加断言 禁止再出现指向该域名的支持入口。 重写(内容过时,不是语言问题): - install/README.md —— 还写着 10 个中国技能、DeepSeek 优先、国内镜像。 现在按实际流程写:技能读 manifest、模型菜单 Gemini 优先、bundle 有 SHA256 校验。并如实写明 curl|bash 在受管企业电脑上会被 EDR 拦。 - CLAUDE.md 的模型配置整节 —— 还在描述虾盘云首选卡片和 12 个 provider, 那个界面已经换成单框 Key 输入了。 - SECURITY.md —— 安全报告原本指向上游维护者个人邮箱。fork 之后那条路由 是错的:漏洞会发给写不了这份代码、也修不了的人。 - CONTRIBUTING.md —— 补上 fork 关系、pre-push 钩子怎么装、以及 `node --test tests/` 为什么不能用。 翻译并保留: - bootable/README.md、TROUBLESHOOTING.md —— 面向用户,顺带把 「国内镜像」「小米/华为 BIOS 按键」等换成目标市场的实际情况 HANDOFF.md 重写为一份事故复盘:原文一半是过时的一次性交接笔记(引用的 website/guide.html 已不在本仓库),另一半是 persistence.dat 未格式化导致 启动失败的排查记录 —— 后者有长期价值,尤其是「读 offset 1080 的两字节 验证 ext4」这个判断方法,已同时写进 bootable/README.md。 bootable/IMPROVEMENTS_SUMMARY.md 保留中文,加了说明:它是上游 fork 前的 历史改进记录,没人引用,描述的是已完成的工作而非当前行为。翻译它反而会 让人误以为是现行文档。 新增 skills/en/uclaw-help —— 把「怎么用、东西在哪、出问题怎么办」做成 内置知识,每个角色都装。方案 C10.8:能问的产品才是不需要学的产品。
289 lines
20 KiB
Markdown
289 lines
20 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Project Overview — CRITICAL MENTAL MODEL
|
||
|
||
**This repo IS the USB drive content**, minus large dependencies. The relationship:
|
||
|
||
```
|
||
repository (git) = the drive's skeleton — scripts, HTML, small files
|
||
↓ bash setup.sh
|
||
working folder = the drive's contents — skeleton + Node.js + OpenClaw
|
||
↓ copy onto a USB drive
|
||
USB drive = plug in and go
|
||
```
|
||
|
||
The repo is NOT a "build tool" or "generator" — it IS the USB structure. `setup.sh` only fills in large deps that can't go in git. After `setup.sh`, the `portable/` folder is directly copyable to a USB drive.
|
||
|
||
Distribution forms:
|
||
1. **Portable USB** (`portable/`): Run from USB on existing Mac/Windows, zero install. **This is the only form CI publishes** (Windows full zip; Mac runs `setup.sh` on first launch).
|
||
2. **Bootable Linux USB** (`bootable/`): Ventoy + Ubuntu 24.04 — boots any x86_64 PC from USB, no OS needed. Independent module, user-run scripts (not in CI).
|
||
3. **One-line install** (`install/`): `curl | bash` or `irm | iex` — download and install from network, no USB needed. User-run scripts (not in CI).
|
||
|
||
> **Deprecated (2026-06-19): Electron desktop app** (`u-claw-app/`, DMG/EXE) is **no longer built or published** — it was a weaker duplicate of the commercial ClawX desktop and had cold-start gateway-timeout bugs. Code is kept for archive only; see `u-claw-app/DEPRECATED.md`. The `desktop-windows`/`desktop-mac` CI jobs were removed from `release.yml`.
|
||
>
|
||
> **Removed: `usb-release/`** — an abandoned older predecessor of `portable/` (last touched 2026-04, `core/`+`skills/` layout, referenced nowhere). Deleted 2026-06-19.
|
||
|
||
## Development Commands
|
||
|
||
```bash
|
||
# Portable version — build dev copy
|
||
cd portable/advanced && bash setup.sh # Downloads Node.js v22 + OpenClaw + plugins into ../app/
|
||
cd .. && bash "START HERE - Mac.command" # Launch (Mac). Windows: double-click "START HERE - Windows.bat"
|
||
|
||
# Copy to USB drive
|
||
cp -R portable/ /Volumes/YOUR_USB/U-Claw/
|
||
|
||
# Electron desktop app
|
||
cd u-claw-app && bash setup.sh # One-click: Node.js + Electron + deps
|
||
npm run dev # Dev mode
|
||
npm run build:mac-arm64 # Build Mac ARM64 DMG
|
||
npm run build:win # Build Windows NSIS + portable
|
||
|
||
# Bootable Linux USB (run on Windows PowerShell as Admin)
|
||
cd bootable
|
||
.\1-prepare-usb.ps1 # Write Ventoy to USB (formats drive!)
|
||
.\2-download-iso.ps1 # Download Ubuntu ISO (~5.8GB)
|
||
.\3-create-persistence.ps1 # Create 20GB ext4 persistence image
|
||
.\4-copy-to-usb.ps1 # Copy ISO + persistence + scripts to USB
|
||
```
|
||
|
||
### Tests
|
||
|
||
```bash
|
||
node --test # Run every test (node:test, no framework dependency)
|
||
node --test tests/windows-launchers.test.mjs # Run one file
|
||
|
||
# NOT `node --test tests/` — Node reads that path as a module to load and dies
|
||
# with "Cannot find module". That form was documented here for years, which is
|
||
# a good part of why the suite went unrun.
|
||
```
|
||
|
||
Tests assert on the **text/behavior of the launchers and shared `.mjs` helpers** — e.g. that the
|
||
Start launchers stay thin shells over `lib/start.mjs`, that `.bat` files are pure ASCII with CRLF,
|
||
that no China-routed download source comes back, that the two installers resolve skills the same
|
||
way, and that every message key exists in every catalogue. They read repo files as strings; they
|
||
do **not** spawn OpenClaw. There is no root
|
||
`package.json`.
|
||
|
||
**Enable the pre-push hook after cloning** — it is per-clone and nothing installs it for you:
|
||
|
||
```bash
|
||
git config core.hooksPath .githooks
|
||
```
|
||
|
||
It runs the suite and the generated-file check before anything leaves your machine.
|
||
`git push --no-verify` skips it. This matters because CI cannot be relied on here:
|
||
the suite went unrun for the whole life of the upstream project, and on our own
|
||
Gitea the workflow produced zero runs — most likely no runner is registered. The
|
||
hook is the one layer that works with no server support at all.
|
||
|
||
**As of 2026-08-17 tests also run in CI where a runner exists** — `.github/workflows/tests.yml` runs
|
||
`node --test` on every push and PR. Before that they were local-only, so the guards they
|
||
encode could regress unnoticed.
|
||
|
||
**CI workflows** (`.github/workflows/`): `release.yml` builds Win/Mac portable + desktop and
|
||
publishes a GitHub Release on tag push. `track-upstream.yml` runs daily (cron) — checks
|
||
`npm view openclaw version` against the pinned `OPENCLAW_VERSION`; if upstream is newer it bumps
|
||
both `OPENCLAW_VERSION` files + the desktop shell version (`u-claw-app/package.json` patch),
|
||
commits, and pushes a new `v<shell-version>` tag, which in turn triggers `release.yml`. Supports
|
||
`workflow_dispatch` with `force_version` / `dry_run` inputs. `OPENCLAW_VERSION` is the upstream
|
||
pin; `u-claw-app/package.json` is the shell version (the two are separate).
|
||
|
||
Testing of the actual runtime should be done in a separate folder or directly on USB. This repo
|
||
stays clean (no node_modules, no app/ runtime).
|
||
|
||
## Architecture
|
||
|
||
```
|
||
portable/ THE USB content (= repo + setup.sh downloads)
|
||
setup.sh / setup.bat / setup.ps1 — fill in app/ (Node + OpenClaw + plugins)
|
||
{Mac,Windows}-Start — launch gateway + config-server, open dashboard/Config
|
||
{Mac,Windows}-Menu — interactive CLI launcher (pick start/config/CLI/diagnose)
|
||
{Mac,Windows}-Install — copy USB → computer (~/.uclaw/ or %USERPROFILE%)
|
||
{Mac,Windows}-Diagnose — health check / collect logs for bug reports
|
||
{Mac-OpenClaw-CLI,OpenClaw-CLI.bat} — drop into raw `openclaw` CLI
|
||
*.html (Welcome, U-Claw, SkillHub) — local UI pages
|
||
Config.html — redirect shim only; the settings UI itself is
|
||
config-server/public/index.html (single implementation since 2026-08-17).
|
||
The old standalone copy called the API on a root-relative path, which
|
||
cannot work from file:// — Save failed silently for anyone who opened it.
|
||
config-server/server.js — local HTTP server (port 18788-18798) backing
|
||
Config.html: writes openclaw.json, WeChat QR login, update-status API
|
||
lib/ — Node helpers (see "lib/ helpers" below)
|
||
default-config.json — seed config copied to data/.openclaw/ on first run
|
||
app/core/ (OpenClaw) + app/runtime/ (Node.js) — downloaded by setup.sh
|
||
data/.openclaw/openclaw.json — user config (on USB, portable)
|
||
skills/ Single source of truth for skill content + distribution (2026-08-17).
|
||
manifest.json — the only thing installers read
|
||
en/<id>/SKILL.md — content
|
||
Replaces the old three-way split (portable/skills-cn/ on disk,
|
||
heredocs in install.sh, here-strings in install.ps1). See skills/README.md.
|
||
Installed by lib/install-skills.mjs; release.yml copies skills/ + the
|
||
installer onto the drive so it can re-install offline.
|
||
|
||
u-claw-app/ [DEPRECATED 2026-06-19, archived — not built/published] Electron desktop app
|
||
(main.js ~400 lines). Kept for archive only; see u-claw-app/DEPRECATED.md.
|
||
Bundles Node.js in resources/runtime/node-{platform}-{arch}
|
||
|
||
bootable/ Linux bootable USB. Fully self-contained — references nothing
|
||
from the other modules, on purpose.
|
||
Four PowerShell scripts, run on Windows, in order.
|
||
Ventoy 1.0.99 + Ubuntu 24.04 LTS + casper-rw persistence
|
||
linux-setup/setup-openclaw.sh installs into /opt/u-claw/
|
||
Mirror: gitea.fanghe.it.com/zhenghy/u-claw-linux
|
||
|
||
install/ One-line network install (curl | bash / irm | iex).
|
||
install.sh (Mac/Linux) + install.ps1 (Windows)
|
||
Detect → Node.js → OpenClaw → QQ plugin → skills (from
|
||
skills/manifest.json) → model → start script → verify.
|
||
Installs to ~/.uclaw/; same result as advanced/Mac-Install.command.
|
||
These run with no checkout, so they cannot read origin.json
|
||
and carry URLs as literals — tests/origin.test.mjs keeps the
|
||
two in step.
|
||
|
||
```
|
||
|
||
> **This is a fork.** Upstream is `github.com/dongsheng123132/u-claw`; we host at
|
||
> `gitea.fanghe.it.com/zhenghy/u-claw` and do **not** send changes back — the overseas
|
||
> build removes the China-market defaults that are the point of the upstream project.
|
||
> See `origin.json` for every URL this build fetches at runtime, and the migration
|
||
> notes in the workspace root.
|
||
>
|
||
> **The website is upstream's and we do not have it.** They split it out on 2026-04-14
|
||
> (commit `65f830e`) into a private repo of their own. `guide.html` lives there, so the
|
||
> website work in the overseas plan is blocked until we either get access or build our own.
|
||
|
||
Both portable and desktop versions auto-find a free port in range 18789–18799 and start the OpenClaw gateway. On first run, they detect whether a model is configured — if not, they open Config.html; otherwise, they open the dashboard.
|
||
|
||
## Key Technical Details
|
||
|
||
- **Node.js discovery**: Portable looks at `app/runtime/node-mac-arm64/bin/node`; Electron looks at `resources/runtime/node-{platform}-{arch}` then falls back to system `node`
|
||
- **Download sources (overseas build, 2026-08-17)**: Node.js binaries from `nodejs.org/dist`, npm packages from `registry.npmjs.org`, GitHub assets direct. No China-routed mirrors or GitHub proxies remain in scripts, launchers or CI — `tests/no-china-sources.test.mjs` fails the build if any come back.
|
||
- **`OPENCLAW_VERSION` file**: single source of truth for the bundled OpenClaw runtime version (e.g. `2026.6.8`). CI reads it to pin the npm install; it's copied into `portable/` so USB users / `check-update.mjs` can compare installed vs latest. Bump this file to upgrade.
|
||
- **Environment variables**: `OPENCLAW_HOME`, `OPENCLAW_STATE_DIR`, `OPENCLAW_CONFIG_PATH` control where OpenClaw reads config
|
||
- **macOS quarantine**: Mac scripts run `xattr -rd com.apple.quarantine` to remove Gatekeeper blocks
|
||
- **Config format**: `{"gateway":{"mode":"local","auth":{"token":"uclaw"}},"models":{"mode":"merge","providers":{"xxx":{...}}},"agents":{"defaults":{"model":{"primary":"provider/model"}}}}`
|
||
- **Config hot-reload**: OpenClaw watches `openclaw.json` and applies changes without restart
|
||
- **Two local servers on startup**: launchers start the OpenClaw **gateway** (18789–18799) AND
|
||
the **config-server** (`config-server/server.js`, 18788–18798). The config-server backs
|
||
`Config.html` — it writes `openclaw.json`, drives WeChat QR login, and exposes update-status.
|
||
|
||
## lib/ Helpers (portable)
|
||
|
||
Pure-Node, zero-dependency `.mjs` modules (use `fetch` + `node:zlib` only). All are designed to
|
||
**fail silently** and **run detached** so they never block or break OpenClaw startup.
|
||
|
||
| File | Purpose |
|
||
|------|---------|
|
||
| `check-update.mjs` / `publish-latest.mjs` | Portable self-update: check installed vs latest `OPENCLAW_VERSION`; publish helper. |
|
||
| `portable-cache.mjs` | **The startup-speed core.** Moves the heavy, rebuildable caches off the USB drive onto local disk: works out a cache root (win `%LOCALAPPDATA%\U-Claw\<slot>`, mac `~/Library/Caches/U-Claw`, linux `$XDG_CACHE_HOME`), keyed by a UUID so the same cache is reused when the drive gets a different letter. Emits `NODE_COMPILE_CACHE`, and redirects `data/.openclaw/browser` to local disk via a junction (Windows) or symlink (macOS) — the browser profile's endless small random writes are what makes a USB drive feel broken. Prints `KEY=VALUE` for the launcher to read. Fails silently: if it cannot, the cache stays on the drive and startup continues. |
|
||
| `prewarm.mjs` | Wakes the gateway once it is listening: background `GET /ready` → `/status` → `/models` with the auth token, so the config and model subsystems are warm before the user's first message. Zero dependencies, short timeout, detached. |
|
||
| `loading.html` | The splash. Opens the instant the launcher starts, so a slow first run looks like progress rather than a frozen black window. Polls `/ready` once a second and moves on when the gateway answers — which sidesteps the old "dashboard opened before the gateway existed, connection refused" failure (issues #46, #48). Port arrives as `?port=`. |
|
||
| `start.mjs` | **All startup logic (since 2026-08-17).** Runtime detection, data folders, cache acceleration, default config, dependency install, NO_PROXY, WeChat plugin, config-server launch and port discovery, gateway port scan, opening the splash and Settings, prewarm, the fallback watcher, and cleanup on exit. The `.bat` and `.command` files are ~30-line shells over it. Two reasons: the platforms cannot drift apart again, and every user-facing string becomes translatable — neither is possible while the logic lives in a `.bat` that must stay pure ASCII. |
|
||
| `i18n.mjs` + `messages/{en,zh-CN}.json` | Strings for the launcher and the local pages. Resolution order: explicit override > `uclaw.locale` on the drive > system locale > `en`. **The language follows the drive, not the machine** — someone who set it up in Chinese and plugs it into a colleague's English Windows still gets Chinese. Keys are semantic, and a missing one falls back to readable English rather than leaking the key. |
|
||
| `self-heal.mjs` | Checks and repairs run when startup fails, before the user is told anything. Missing folders, a damaged settings file (moved aside, never deleted), a leftover port record, an interrupted copy, a dangling cache link. What it cannot fix produces a redacted diagnostics report. Every repair must be safe on a healthy drive — they all run whenever startup fails, including for reasons none of them explain. |
|
||
| `provider-detect.mjs` | Maps an API key prefix to its provider, so nobody has to know what a Base URL is. `sk-ant-` must be checked before the plain `sk-` catch-all. |
|
||
| ~~`wait-gateway.bat`~~ | Removed 2026-08-17. The fallback watcher moved into `start.mjs` as `watchGatewayReady()`, so macOS has it too — it was Windows-only before. |
|
||
|
||
### Why startup is fast off a slow drive (2026-06-17)
|
||
|
||
Running from a USB drive is slow for three separate reasons, and each needed its
|
||
own fix: **small random writes on the drive**, **no feedback on the first
|
||
screen**, and **a genuinely cold first run**.
|
||
|
||
1. **Move the caches to local disk** (`portable-cache.mjs`). The browser profile
|
||
is the worst offender — OpenClaw hardcodes it at `CONFIG_DIR/browser/` with no
|
||
environment variable to move it, so we redirect it with a junction (Windows)
|
||
or symlink (macOS). The V8 compile cache goes the same way via
|
||
`NODE_COMPILE_CACHE`. **Business data stays on the drive** — `openclaw.json`,
|
||
`memory`, accounts — so portability is unaffected. A UUID key means the same
|
||
cache is reused when the drive comes up as `E:` instead of `D:`.
|
||
2. **Pin the compile cache.** `openclaw.mjs` already calls
|
||
`module.enableCompileCache()`, but it defaults to system temp, which gets
|
||
cleaned. Pointing `NODE_COMPILE_CACHE` at a stable local directory makes the
|
||
second launch reliably fast rather than occasionally fast.
|
||
3. **Show something immediately** (`loading.html`). It opens on double-click and
|
||
polls for readiness itself.
|
||
4. **Warm the gateway** (`prewarm.mjs`) in the background once the port answers.
|
||
5. **Poll instead of guessing.** Windows used to `timeout /t 2` waiting for the
|
||
config server; it now polls the port and proceeds the moment it is up.
|
||
|
||
> OpenClaw's own temp, lock and chrome-mcp files already go to `os.tmpdir()` —
|
||
> system temp, **not the drive** — so they need no handling. The only thing that
|
||
> genuinely lands on the drive is what lives under `OPENCLAW_HOME=data/`.
|
||
|
||
> **No tracking.** This build contains none of the commercial-version logic —
|
||
> no device fingerprinting (`fingerprint.mjs`), no automatic account creation
|
||
> (`bootstrap-xiapan.mjs` / `xiapan-client.mjs`), no crash reporting
|
||
> (`report-bug.mjs`). Upstream removed them on 2026-06-17. Nothing is bound to a
|
||
> device and nothing is uploaded to `api.u-claw.org`.
|
||
|
||
### Choosing a model (rewritten 2026-08-17)
|
||
|
||
Settings is `config-server/public/index.html`. `Config.html` in `advanced/` is a
|
||
redirect shim to it — the old standalone copy called the API on a root-relative
|
||
path while only ever being opened from `file://`, so its Save button had been
|
||
failing silently.
|
||
|
||
**The first screen asks for one thing: an API key.** It used to lay out twelve
|
||
provider cards and then demand a Base URL and a model name — three technical
|
||
fields on the first screen a non-technical user ever saw.
|
||
|
||
The key itself says which provider it belongs to (`lib/provider-detect.mjs`
|
||
maps the prefix), so:
|
||
|
||
1. Paste the key
|
||
2. After an 800ms pause, `POST /api/test-key` sends a 1-token request and reports
|
||
what actually happened — "connected in 340ms", or a sentence saying what to do
|
||
3. A model dropdown appears once it works, so the choice is not locked to
|
||
whatever the first key implied
|
||
|
||
The check runs server-side deliberately: the browser cannot reach most model
|
||
endpoints cross-origin, and doing it in the config server means the key never
|
||
leaves the machine by any path the page controls.
|
||
|
||
Endpoint and model name still exist, under a collapsed *Advanced* section that
|
||
only opens by itself when the key is not one we recognise.
|
||
|
||
Everything is written to `data/.openclaw/openclaw.json` on the drive.
|
||
|
||
## What NOT to Commit
|
||
|
||
Never commit runtime dependencies or build artifacts. These are all in .gitignore:
|
||
- `portable/app/` and `portable/data/` (runtime + user data)
|
||
- `u-claw-app/node_modules/`, `u-claw-app/release/`, `u-claw-app/resources/runtime/`
|
||
- `*.dmg`, `*.exe`, `*.blockmap`
|
||
|
||
Release artifacts go to the release page, not the repo.
|
||
|
||
## Branding Rules
|
||
|
||
- Use only official `openclaw` (not `openclaw-cn` or any community fork)
|
||
- All npm installs reference `openclaw@latest` (official package)
|
||
- External links go to `origin.json`'s `urls`, or to `github.com/openclaw/openclaw` for the runtime.
|
||
We do **not** own `u-claw.org` — that is the upstream project's domain, so never
|
||
offer an address on it as a support route.
|
||
- No references to competitor products (Qclaw, AutoClaw) in any tracked files
|
||
- Skill marketplace links point to `skillhub.tencent.com` or `github.com/openclaw/clawhub`
|
||
|
||
## Platform Support Status
|
||
|
||
- Mac Apple Silicon (ARM64): ✅ Working
|
||
- Mac Intel (x64): ✅ Working — run `setup.sh` first to fetch `node-mac-x64`
|
||
- Windows x64: 🚧 **Carries unverified changes.** A large amount of PowerShell and
|
||
the `.bat` path resolution were written on a Mac with no PowerShell available and
|
||
have never been through a parser. See `U盘实测清单.md` in the workspace root.
|
||
- Linux x64 (bootable USB): ✅ see `bootable/`, mirrored at [u-claw-linux](https://gitea.fanghe.it.com/zhenghy/u-claw-linux)
|
||
|
||
## Bootable Linux Key Details
|
||
|
||
- **Built on**: Windows 10/11, PowerShell as Administrator, four scripts in order
|
||
- **Drive**: 32 GB or larger, USB 3.0
|
||
- **Stack**: Ventoy 1.0.99 → Ubuntu 24.04 ISO → casper-rw persistence → OpenClaw in /opt/u-claw/
|
||
- **Sources**: ISO from releases.ubuntu.com, Node.js from nodejs.org, packages from registry.npmjs.org
|
||
- **Environment**: `OPENCLAW_HOME=/opt/u-claw/data/.openclaw`
|
||
- **Self-contained**: references nothing from `portable/` or `u-claw-app/`, so a change here cannot break them or vice versa
|
||
- **Mirrored**: kept identical to the u-claw-linux repo — a change in one needs the same change in the other
|