Skip to content

Latest commit

 

History

History
135 lines (96 loc) · 5.89 KB

DEVELOPMENT_SETUP.md

File metadata and controls

135 lines (96 loc) · 5.89 KB

Development setup

What a fresh clone needs before pnpm install, pnpm test, and cargo test all work.

The quick start in ../README.md is enough to run the web stack. Read this page when an install or a test run fails on a machine that looks correctly configured. The two that show up most are an unbuilt common package and missing GTK headers, and neither error message names its own fix.

Prerequisites

Tool Version Notes
Node >= 22 .nvmrc pins the exact version
pnpm >= 11 Use it exclusively. Never npm, yarn, or bun.
Docker Engine or Desktop Needed for the stack, integration tests, and e2e
Rust stable Desktop app only. Skip unless you build packages/desktop.

Design files from CI Common

pnpm install does not need a GitHub Packages token. The stylesheet, canon file, and company logo files the Hub carries are copied into this repo and listed in packages/frontend/ci-common.vendor.json. Text copies carry a vendored-from: line. Search that string when a CI Common package changes, then refresh the copies from a checkout:

node scripts/vendor-ci-common.mjs --from ../ci-common --ref <tag>
node scripts/vendor-ci-common.mjs --check

Pass a commit or a tag that exists in your checkout (git -C ../ci-common fetch --tags), not HEAD: the script reads files with git show <ref>:<path>, and a stale local main has none of the newest files. CI Common tags each package on its own, so one --ref carries all three only when they were released together; check that the version it writes for tokens, config and assets is the one you meant.

CI Common keeps its lint gate as packages/config/bin/lint-canon.ts, which tsup builds. The file has no type syntax, so the manifest vendors it byte for byte into packages/frontend/scripts/lint-canon.mjs and lint:canon runs it with plain node. If a later release adds real TypeScript to it, lint:canon fails to parse the copy; vendor the built dist/lint-canon.js instead.

The Hub's own mark is not vendored. It lives in packages/frontend/hub-brand, which is the origin for the favicons, app icons, and header logo; pnpm --filter frontend brand:sync mirrors it into place.

Build common before backend tests

Build packages/common before running backend tests — the backend's vitest config aliases @ci-hub/common/schemas and /types to source, but /validation resolves through the package's exports to dist/, so an unbuilt common fails 26 backend test files with Cannot find package '@ci-hub/common/validation':

pnpm --filter common build

cargo test fails on a missing system library

The system library `dbus-1` required by crate `libdbus-sys` was not found.

Tauri needs GTK and WebKit development headers that most distributions do not install by default. dbus-1 is only the first one the build reaches; installing it alone moves the failure along.

Install the full set — the same list desktop-tests.yml installs on its runner:

sudo apt-get update && sudo apt-get install -y build-essential pkg-config libssl-dev libdbus-1-dev libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libxdo-dev

Verify before rebuilding:

pkg-config --exists gtk+-3.0 webkit2gtk-4.1 dbus-1 && echo ok

Testing the Rust without the headers

Most of the desktop crate never touches Tauri — hub_manager (the Docker/host engine), docker_engine, port_manager, hub_env, hub_names, error_reporting, and sentry_scrubber contain no tauri:: reference between them. This script copies those into a scratch crate with only their real dependencies and runs their tests there, so you can verify a change without the GUI stack:

packages/desktop/src-tauri/scripts/test-without-gui.sh

Pass a git ref to test that instead of the working tree, which is how you compare a refactor against the commit it started from:

packages/desktop/src-tauri/scripts/test-without-gui.sh origin/dev

It covers 155 of the crate's tests. main.rs, tray.rs, and commands/ are genuinely Tauri-coupled and still need the full toolchain, so treat this as a fast local gate rather than a replacement for desktop-tests.yml.

Building the desktop app for release needs a few more (patchelf, libfuse2, rpm, xdg-utils); see desktop-build.yml.

Running the checks

pnpm run check:pr is the closest local equivalent to a full PR run:

pnpm run check:pr

That is lint:ci, knip:ci, check:workflows, tsc, check:openapi, test, and cargo test. Because automatic CI triggers are gated (see CI.md), running this locally is not optional — nothing runs it for you on push.

Individual lanes, when you want a faster loop:

pnpm --filter backend exec vitest run     # backend only
pnpm exec vitest run --config scripts/vitest.config.ts   # cihub CLI only
pnpm exec biome check .                   # lint and format

Known-good baselines

Compare against these before assuming your change broke something. Captured 2026-09-06 on dev.

Lane Files Tests
backend 223 (+1 skipped) 3,102
frontend 162 1,421
scripts (cihub) 27 675
common 13 201
openclaw-plugin 3 44

A lane that fails identically before and after your change is a pre-existing problem, not yours. Capture the baseline first when you touch anything broad.

Related

  • CI.md — why workflows are gated and how to dispatch one. That file is generated by ci-local docs; do not hand-edit it.
  • ../CONTRIBUTING.md — conventions for issues, PRs, and module structure.
  • agent/AGENT_WORKFLOW.md — the workflow coding agents follow.