Development Setup
Applies to: ChengOS v0.1.0+ | Last verified: 2026-08-12 | Source:
chengflow/CLAUDE.md,chengflow-ui/CLAUDE.md,chengflow/.env.example,chengflow/Cargo.toml, rootCLAUDE.md
This page is for people who want to build ChengOS itself. If you only want to run it, use
Installing ChengOS instead — whole-system installs go through
deploy/chengos.sh, not the commands here.
Repository layout
chengos is a meta-workspace, not a single repository. There is a trap in it worth knowing
before your first git status.
| Directory | Stack | Role |
|---|---|---|
chengflow/ | Rust (Cargo workspace) | Core backend: engine, REST + WebSocket API, node system |
chengflow-ui/ | React 18 + TS + Vite | Primary frontend: visual editor, runtime page renderer |
chengflow-sdk/ | React 18 + TS + Vite | Channel-gateway frontend |
chengapp/ | Rust + React + Tauri | Chat product |
deploy/ | Shell + Docker Compose | Deployment tooling |
Product names and directory names diverge. The channel gateway is called chengflow-app
in docs and deployment configs but lives in chengflow-sdk/.
Git topology
chengflow/, chengflow-ui/, chengapp/, and chengflow-sdk/ are independent repositories,
each with its own .git. The root .gitignore ignores the first three so their source is not
uploaded to the public mirror. chengflow-sdk/ is recorded as a bare gitlink with no
.gitmodules, so root git status shows m chengflow-sdk whenever its worktree moves — that
is expected, not a dirty worktree.
Root-level git status and git diff will not show file-level changes inside any
subproject. Run git from inside it:
cd chengflow && git status --short && git diff
The root repo is not empty: it owns deploy/, scripts/, .github/, and the release metadata
(VERSION, CHANGELOG.md, README.md, release.sh).
A cross-cutting change — a node's schema, say — means editing Rust in chengflow/ and the
corresponding handling in a frontend, and committing in each affected repository separately.
Three related projects are not in this tree at all. chenghub, skill-registry, and
skill-package-spec live under /home/cheng/works/chengrouter/community/. They are standalone
Rust projects, not members of the chengflow Cargo workspace, and must not depend on cheng-*
crates.
Prerequisites
- Rust — the workspace is on edition 2024, so a recent stable toolchain.
- Node.js ≥ 18 and pnpm ≥ 9 for the frontends.
- PostgreSQL — the only source of business truth.
- Redis — optional for the core, required for agent memory nodes and the scheduler.
- Qdrant — optional, needed for RAG.
Backend setup
cd chengflow
cp .env.example .env
cargo run -p cheng-api # listens on :19225
Key settings in .env:
| Variable | Purpose |
|---|---|
DATABASE_URL | PostgreSQL connection |
TEST_DATABASE_URL | Separate database for tests |
DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD | Connection details for agent memory nodes |
RUN_MIGRATIONS | true runs migrations on startup |
CREDENTIAL_MASTER_KEY_1 | 64-character hex (32 bytes) for AES-256-GCM credential encryption |
REDIS_URL or REDIS_HOST/REDIS_PORT | Redis |
PUBLIC_BASE_URL | Public HTTPS base used to compute webhook callbacks |
CORS_PERMISSIVE / CORS_ALLOWED_ORIGINS | CORS |
RUST_LOG | Log level (info by default) |
CHENG_DEMO_MODE | Fail-closed public demo API — denies saves, executions, and WebSockets |
Use TEST_DATABASE_URL for a separate test database. Tests are destructive against whatever
they point at.
A bare cargo build or cargo run targets the default-members — cheng-api and chengctl —
not the whole workspace. Build everything with cargo build --workspace.
Frontend setup
cd chengflow-ui
pnpm install
pnpm dev # :5173, proxies /api and /ws to :3000
The Vite dev server proxies /api, /ws, and related paths to the backend on
http://localhost:19225 (see vite.config.ts). The old Express server on :4000 is deprecated.
Environment variables for the frontend must be prefixed VITE_.
pnpm build needs the backend running. It runs gen:pages, which calls the backend to
render static pages; without a backend that step fails or skips. Run pnpm gen:pages standalone
to regenerate pages.
Database
cd crates/cheng-storage
diesel migration run # apply
diesel migration revert # undo the last one
diesel print-schema > src/schema.rs
Or set RUN_MIGRATIONS=true and let the server apply them on startup.
Common commands
Rust (chengflow/, chengapp/):
cargo build # default-members only
cargo build -p cheng-core # one crate
cargo test # whole workspace
cargo test -p cheng-engine # one crate
cargo test test_workflow_creation
cargo test -- --nocapture
cargo check # no codegen — the fast loop
cargo fmt
cargo clippy
Frontends (chengflow-ui/, chengflow-sdk/, chengapp/):
pnpm dev / build / preview
pnpm test # Vitest, watch mode
pnpm test -- src/path/file.test.ts
pnpm test -- -t "test name"
pnpm test:integration # Vitest integration config
pnpm test:e2e # Playwright
pnpm test:coverage
pnpm lint / lint:fix / format / type-check
chengapp is a mixed workspace whose Rust side excludes the Tauri client (src-tauri),
because it links webkit2gtk, which is not present on every dev host. Build it separately:
cargo build --manifest-path src-tauri/Cargo.toml
i18n tooling
Node UI strings are translated offline by chengctl — no database or server required:
cargo run -p chengctl -- missing-i18n [--fail-if-missing]
cargo run -p chengctl -- dump-i18n-keys [--package builtin] [--output keys.json]
cargo run -p chengctl -- translate-missing [--engine baidu|llm] [--dry-run]
cargo run -p chengctl -- merge-i18n --base PATH --patch PATH
Base en-US keys are extracted from the registered builtin nodes; zh-CN lives in an overrides
file, with untranslated entries marked [TODO-zh]. Bundles live under config/i18n.
API docs and packaging
make openapi # generate openapi.yaml from code
make docs # OpenAPI, Swagger, Redoc, Postman, SDKs, Markdown
make dev # API server plus docs server
make test-api # API contract tests
./build.sh # release binary + Docker / hybrid bundles (--help for options)
Working conventions
- Do not create documentation or
*.mdfiles unless explicitly asked. This is a hard rule in the backend's own guidance and applies across the workspace. - Confine a change to one subproject when you can.
- Read the subproject's own
CLAUDE.mdorREADME.md— the root file covers only what spans projects.
Next steps
- Architecture Deep Dive — how the layers fit together.
- Crate Structure — what lives where.
- Writing a Custom Node — the most common first contribution.