Crate Structure

Applies to: ChengOS v0.2.0+ | Last verified: 2026-09-25 | Source: chengflow/Cargo.toml, chengflow/CLAUDE.md, crates/

The backend is a Cargo workspace. This page is the map: what each crate owns, and the naming traps that cost time when you first go looking for something.

Workspace members

members = [
  "crates/cheng-vector",   "crates/cheng-common",   "crates/cheng-core",
  "crates/cheng-storage",  "crates/cheng-engine",   "crates/cheng-file-ops",
  "crates/cheng-code-index","crates/cheng-local-executor",
  "crates/cheng-workspace-tools", "crates/cheng-nodes", "crates/cheng-llm",
  "crates/cheng-adapters", "benches/cheng-engine-benchmarks",
  "crates/cheng-api",      "crates/cheng-cli",      "crates/cheng-mcp",
  "crates/chengctl",
]
default-members = ["crates/cheng-api", "crates/chengctl"]

default-members matters. A bare cargo build or cargo run targets only cheng-api and chengctl. Use --workspace to build everything, or -p <crate> for one.

The workspace is on edition 2024, with dependency versions pinned centrally in [workspace.dependencies] — add a dependency there, not in the member crate, when more than one crate needs it.

The crates

Foundation

CrateOwns
cheng-commonBasic types, error handling, shared utilities, and version.rs — the single release version every component reads
cheng-coreDomain models, ports (traits), domain services, domain events. No infrastructure dependencies.

cheng-core is the crate to protect. If something you are adding needs a database connection, an HTTP client, or a filesystem path, it does not belong there.

Infrastructure

CrateOwns
cheng-storagePostgreSQL persistence with Diesel; migrations; DieselWorkflowRepository, DieselExecutionRepository; domain ↔ row conversion
cheng-vectorVector database abstraction — Qdrant integration, named vectors, BM25 full-text
cheng-llmLLM provider abstraction layer, plus the separate decision layer: typed-choice providers (TypeSafe Jev, Laya, the LLM baseline), decision_config and decision_calibration loading, and the DecisionService behind ai/decision_branch
cheng-adaptersFirst-party channel adapters (WhatsApp, Telegram, Slack, DingTalk, WeCom, ChengApp), registered in create_default_registry()
cheng-mcpMCP integration: a static app-level server at /mcp (MCP_ENABLED=true) plus per-workflow dynamic servers on ephemeral ports

Execution

CrateOwns
cheng-engineDAG-based executor with streaming; scheduling; lifecycle
cheng-nodesBuiltin nodes and the registry
cheng-runtimeScript execution: LightRuntime (QuickJS / Python sandbox) and HeavyRuntime (Docker), used by the tools/code_* nodes
cheng-code-indexTree-sitter code intelligence: indexing, symbols, go-to-definition, find-references, workspace symbols

cheng-runtime is not a top-level workspace member — it is a path dependency of cheng-nodes. Looking for it in the members list will not find it.

cheng-code-index is storage-agnostic at its core, with an optional durable PostgreSQL store and Redis coordination behind cargo features: redis-state, lang-typescript, lang-javascript, lang-python. Rust support is built in, the other languages are feature-gated.

The shared client-local trio

These three exist because the same operations must run server-side and client-side with identical semantics:

CrateOwns
cheng-file-opsPure file-operation core — logic plus JSON-compatible I/O types, no node/engine/API code
cheng-workspace-toolsThe same split for non-file workspace tools: process, shell, git, tests, markdown, preview
cheng-local-executorUI-independent client-local execution shell: request classification, read-only policy, mutation/process serialisation, cancellation

cheng-file-ops is shared by both backends of tools/file_ops_hub — the server-local shims in cheng-nodes and the client-local executor. cheng-local-executor is reused by every local client: the cheng CLI, its TUI and headless shells, and the desktop client. That is the whole point: file semantics cannot drift between "the server did it" and "your machine did it".

Interfaces

CrateOwns
cheng-apiAxum REST API, WebSocket via WsManager, dependency injection in main.rs
cheng-cliTerminal workflow client — builds the cheng binary; contains the TUI (tui/, tui.rs) and headless mode
chengctlOffline CLI: i18n tooling, and gen-node-docs, which renders the node-reference articles from the live registry and fails when a registered node is missing from log/node-docs-map.toml. No database or server needed

cheng-cli's lib.rs exposes the API client, event stream, and session cache so integration tests can drive them; main.rs is a thin composition over that. The binary is named cheng, not cheng-cli.

Macros

cheng-macros is the crate directory, but the Cargo package is cheng-workflow-macros and the Rust import path is cheng_workflow_macros. It provides #[derive(Node)] and #[derive(FieldOrder)].

This is the naming trap that costs the most time. use cheng_macros::Node does not compile.

Archived: the Spatial Design Platform

The spatial crates — cheng-spatial, cheng-plan, cheng-quantity, cheng-scene, cheng-spatial-conformance — together with their storage, API handlers, and contracts were removed in commit 909662be. That was a product decision, not a technical failure. The last green state is preserved at the tag spatial-phase-1-archived, which carries the revival instructions; the design documents are under docs/archive/spatial-*.md.

Do not build on spatial APIs: nothing in the current tree provides them. The commented Phase 2-4 placeholders in the workspace members list are notes, not crates. A revival must re-add its database migration under a current date so it sorts after migrations added since.

Non-Rust directories in chengflow/

DirectoryContents
node_skills/Per-node usage docs / skill definitions consumed by agent and LLM features, one directory per node type
skills/Higher-level workflow-building skills: workflow-helper, workflow-json-builder, skill-importer
config/i18nNode translation bundles
docs/Internal design docs

node_skills/ and skills/ are LLM-facing assets, not Rust code. Adding a node usually means adding a node_skills/<node>/ entry too, or the agent will not know how to use it.

Node implementation directories

Under cheng-nodes/src/nodes/builtin/:

agent  ai  chat  document  io  rag  table  tools  translation  ui  utils  workspace

The category value in the #[node(...)] macro — trigger, control, webui, and so on — is a logical grouping for the UI and may differ from the directory name. Do not assume category = "Utils" means the file is in utils/, or vice versa.

Finding your way

You are looking forStart at
A business rulecheng-core/src/domain/
An interface definitioncheng-core/src/ports/
A database querycheng-storage/src/repos/
Scheduling or DAG logiccheng-engine/src/executor/, .../dag/
A nodecheng-nodes/src/nodes/builtin/<category>/
An HTTP endpointcheng-api/src/rest/handlers/, routes in rest/routes.rs
A WebSocket messagecheng-api/src/ws/protocol.rs
Wiring / DIcheng-api/src/main.rs

Docs and packaging

Node reference docs are generated, not hand-written:

cargo run -p chengctl -- gen-node-docs --locale en --dry-run   # coverage check only
cargo run -p chengctl -- gen-node-docs --locale zh             # write log/docs-content/zh

Adding a node without placing it in log/node-docs-map.toml (or its [skip] table, with a reason) fails both this command and cargo test -p chengctl. The source headers stamp the workspace version; override with --applies-to vX.Y.Z.

The Makefile generates API documentation from code — make openapi, make docs, make dev, make test-api; run make help for the full list. ./build.sh builds the release binary and packages Docker and hybrid bundles, defaulting to single-user mode and the x86_64-unknown-linux-musl target.

Next steps