lazyBoy/docs/development.md

9.3 KiB
Raw Permalink Blame History

開發指南

← 回到 README

本機開發

make dev              # 準備 .env、PostgreSQL、電腦映像
make dev-supervisor   # 終端 1Supervisor :7091
make dev-api          # 終端 2API :3101

前端熱更新:

cd apps/web
npm install
npm run dev           # http://127.0.0.1:5173

檢查與測試

# 有資料庫的 Rust 測試需要 127.0.0.1:5434先用 dev overlay 啟動 Postgres
make postgres

make lint               # clippy-D warnings政策見下方
make test               # Rust 測試(需要 127.0.0.1:5434
make audit              # 依賴漏洞、授權、來源掃描(需要 cargo-deny

cd apps/web
npm run typecheck
npm run build

cd ../..
node --test tests/frontend.test.mjs
python3 tests/log-rotation.test.py

# Cua Driver 能否控制現有 XFCE + Xvfb 桌面(會建 computer image
make cua-smoke
# 生產路徑只使用 Cua更新後請重建 supervisor 與桌面映像。

# Python 整合測試用 docker compose exec 連進 Postgres自己建一次性資料庫後清掉
python3 tests/retention.test.py
python3 tests/run-resume.test.py
python3 tests/run-activity.test.py

make postgres 才會發布 127.0.0.1:5434docker-compose.dev.yml);整套堆疊已經用 基礎設定跑著時,請改用 export COMPOSE_FILE=docker-compose.yml:docker-compose.dev.ymldocker compose up -d,否則後續的 docker compose 指令會拿基礎設定重建 Postgres、 把發布埠拿掉。

Rust 品質檢查

工具鏈以穩定版為準workspace 宣告 rust-version = "1.98"MSRV代表 let-chains 等語法下限),容器用 rust:1-* 映像會自動跟最新小版。本機更新只需:

rustup update stable && rustc --version

Lint 政策集中在三處,新增 crate 時只要補 [lints] workspace = true 就會繼承:

  • Cargo.toml[workspace.lints]:不安全程式碼預設警告、未使用的 Result/Future 直接拒絕,並用 unused_crate_dependencies 抓多餘依賴 (不需要另外裝 cargo-machete)。
  • clippy.toml:閾值類設定。too-many-arguments-threshold = 10 是因為 handler 與 run/vault/voice 協助函式本來就要帶 state + actor + 多個 id超過 10 個參數才會警告。 cargo-clippy 只看得到啟動目錄下的 clippy.toml,請一律在 repo 根目錄跑 make lint
  • 各 crate 的 [lints] workspace = true

要放寬一條 lint 時,請在呼叫點#[allow(...)] 並附一句理由(例: crates/api/src/vault.rs 測試裡的 #[allow(unsafe_code)]),不要在工作區層級關掉規則。

make fmt 會重排整個 workspace目前倉庫仍有歷史格式偏差make fmt-check 會列出來, 等到一次性重整後再併入 CI。CI 目前只需 make lint + make test

供應鏈檢查用 cargo-denymake audit,設定見 deny.tomlRustSec 漏洞、授權白名單、 依賴來源。它不是內建工具,第一次要先 cargo install --locked cargo-deny。 已知無法升級的項目會寫進 deny.tomlignore 並附原因與重檢時機。

映像與 CPU 架構

三個映像(image/computerimage/apiimage/supervisor)一律用 scripts/build-image.sh 建置。支援的架構是 linux/amd64 與 linux/arm64,這個上限由上游二進位發行決定,不是實作取捨:

  • Cua Driver cua-driver-rs-v0.23.2 的 Linux 發行檔只有 linux-x86_64linux-arm64
  • ONNX Runtime v1.24.1 的 Linux 發行檔只有 linux-x64linux-aarch64

image/computer/DockerfileTARGETARCH 選檔並驗證 SHA256scripts/fetch-onnxruntime.sh 同樣只認這兩種架構,其他架構直接建置失敗;build-image.sh 在註冊 QEMU 與開始跨修編 之前就先擋掉不支援的 --platforms,不會燒掉數 GB 才報錯。

make computer            # 本機架構,結果直接進本地 image 庫
make computer-multi      # amd64 + arm64 -> dist/lazyboy-computer-multi.oci.tar
make images-multi        # 三個映像都跨修 amd64 + arm64
make images-multi PUSH=1 # 直接發布 manifest list 到 registry

多架構需要 docker-container builder 與 QEMU binfmtbuild-image.sh 會自行建立 lazyboy builder 並註冊 binfmt主機本身的架構會跳過註冊否則在特權容器內會誤報失敗。 不推送 registry 時輸出 OCI archivenerdctl load -i <檔> 可載入),因為 Docker 的 docker driver 無法匯出 manifest list。

README 首頁圖

首頁圖不再手刻假介面:先用 scripts/capture-hero.mjs正在跑的真實介面,再由 docs/hero.html 套上品牌框輸出 docs/readme-hero.png。兩段都只要有任一 Chromium CHROME= 指定,否則依序找 PATH 上的 chromiumChrome 與 Playwright 下載的 chrome

# 1. 對運行中的 stack 擷取真實畫面(登入 token 讀 .env可用 LB_TOKENLB_URL 覆寫)
# 群組視圖的右欄是機器人自己的瀏覽器,進圖前先用 --hide 遮掉,再補一張中立的上去;
# --anchor 會印出被遮區塊在圖上的位置hero.html 的圖層座標就是從這裡來的。
node scripts/capture-hero.mjs --out docs/hero/agent.png
node scripts/capture-hero.mjs --out docs/hero/room.png --pick 測試聊天 \
  --hide .side-card --anchor .side-card
node scripts/capture-hero.mjs --out docs/hero/desktop.png --pick 阿狗 --selector .side-card

# 2. 套框輸出 README 用的圖SHOT= 決定用哪張(預設 room
scripts/render-readme-hero.sh
SHOT=agent scripts/render-readme-hero.sh

capture-hero.mjs 直接講 CDP沒有 npm 相依。預設擷取 1480x6502 倍圖),正好對應 hero.html 的 1184x520 視窗不會裁到圖。noVNC 是即時串流,--settle(預設 6 秒)是留給 桌面畫出內容的時間。發布前務必逐張檢查:機器人瀏覽器裡留著的帳號、網址與貼文會一起進 圖,--hide 的 selector 沒命中時擷取會直接失敗,不要繞過這個檢查把圖放進 repo。

專案結構

LazyBoy/
├── apps/web/                 React 前端與 noVNC 頁面
├── crates/
│   ├── api/                  對外 API 與 Agent 執行迴圈
│   ├── contracts/            跨元件資料契約
│   ├── control/              瀏覽器與桌面控制
│   ├── controld/             容器內控制服務
│   ├── harness/              模型與語音後端
│   ├── sandbox/              API 到 Supervisor 的抽象
│   └── supervisor/           Docker 生命週期管理
├── image/                    API、Supervisor、電腦映像
├── migrations/               SQLx PostgreSQL migrations
├── tests/                    Rust 以外的契約與回歸測試
├── scripts/                  環境初始化與執行工具
├── docs/hero.html            README 首頁框架(品牌+真實截圖)
├── docs/hero/                README 用的真實截圖原檔
├── docs/workflow.html        可互動產品流程圖
├── docker-compose.yml        正式堆疊
├── clippy.toml               Clippy 閾值(要在 repo 根目錄執行才讀得到)
├── deny.toml                 cargo-deny 供應鏈政策make audit
└── Makefile                  常用開發與部署指令

公開發布準備

對外發布前,可依下列清單補齊授權、貢獻流程與自動化檢查。只有在對應結果已公開時才加入品質徽章。

若要取得可公開查驗的安全與品質徽章,建議依序完成:

  • 在公開 GitHub repository 建立正式 mirrorOpenSSF 的公開查驗以 GitHub 為主要整合目標。
  • Apache 2.0 LICENSE
  • SECURITY.mdCONTRIBUTING.md 與行為準則。
  • 建立 CIRust format / Clippy / tests、前端 typecheck / build / tests。
  • 啟用 Dependabot 或 Renovate、CodeQL、secret scanning 與 branch protection。
  • 執行並發布 OpenSSF Scorecard 結果後,再加入 Scorecard 徽章。
  • OpenSSF Best Practices 登記專案、誠實完成 Passing 問卷後,再加入認證徽章。
  • 若提供容器映像,再加入 SBOM、簽章與可重現版本發布流程。

不建議現在顯示 CI passing、coverage、OpenSSF 或 Best Practices 徽章:目前 repository 沒有對應的公開結果,徽章會失真或直接顯示 unknown。

Cua saved-login integration

COMPUTER_IMAGE=lazyboy/computer:cua-work scripts/cua-login-test.sh starts a disposable desktop, installs a test-only certificate utility, trusts a generated localhost certificate inside that container, and opens the HTTPS fixture through Cua. It runs the same field-filling function as use_saved_login, checks both exact fixture values, and verifies that the form was not submitted. No model key or real login is used; the container is removed on exit. Build the desktop image from the current tree first.

Cua 0.23.2 can return effect: refused for an Email field despite a zero CLI exit status. The adapter treats that as a failure. A classified unsupported browser typing route can use a uniquely labelled native web field from Cua, click its freshly observed bounds, and paste through the Cua-operated clipboard editor. Other errors remain errors.