Development guidelines
The repository’s contributing guide is the single source of truth for working on Flow. It applies equally to humans and to AI coding assistants. This page summarizes the enforced rules.
Commands
Section titled “Commands”pnpm install # JS workspace dependenciescargo build # Rust workspacepnpm desktop:dev # desktop app, hot reloadpnpm web:dev # web target against flow-serverpnpm site:dev # this website + docs site
pnpm typecheck # tsc across all JS packagespnpm lint # eslintpnpm build # full JS buildcargo test --workspace # Rust testspnpm e2e # Playwright UI end-to-endTesting
Section titled “Testing”- Rust is covered by
cargo testwith per-crate integration tests. - The desktop UI is covered by Playwright end-to-end tests that drive the real React app in a browser. Tauri’s native WebDriver doesn’t support macOS, so the suite runs the web build against the Vite dev server with a Tauri IPC mock. This is the same React app the shell loads, without the native host. Each run starts from fresh UI state. Assert against stable anchors such as titles, roles, and panel headers, never CSS internals.
- E2E is deliberately not part of the pre-commit gate, because it needs a browser and a dev server. Run it when you change UI behavior, and in CI.
Pre-commit verification
Section titled “Pre-commit verification”Use the smallest verification set that covers the change. Never hand off work that fails a required check.
| Change type | Required checks |
|---|---|
| Frontend TypeScript / React | pnpm typecheck, pnpm lint, pnpm build |
| Frontend styling | pnpm lint, pnpm build |
| Rust crates | cargo build, cargo test --workspace |
| Tauri commands / IPC | pnpm typecheck, cargo build, relevant Rust tests |
| DSL grammar/spec changes | spec rebuild script, DSL parser tests, a standalone parse check |
| UI behavior changes | relevant Playwright spec, or pnpm e2e |
| Docs only | no build, unless docs feed generated specs |
Coding standards (enforced)
Section titled “Coding standards (enforced)”Design tokens only
Section titled “Design tokens only”Do not hardcode colors, shadows, margins, padding, or radii in components or
stylesheets. Every visual parameter resolves through the --flow-* design
tokens for borders, surfaces, radius, and shadow scales. Static dimensions,
transitions, and focus rings belong in the modular stylesheet. Do not use
inline styles except for dynamic, state-driven values.
TypeScript safety
Section titled “TypeScript safety”Do not use as any, as unknown, or force-casts on dynamic values. Write type
guards or runtime validation helpers that check literal unions exhaustively
and fall back safely. Status checks match the full union, never loose strings.
Vendor neutrality
Section titled “Vendor neutrality”Product source, shipped catalogs, tests, fixtures, and user-facing templates must not include vendor brand names, product names, or sample customer paths. The one exception is a surface that is explicitly an integration boundary and requires the real provider name. Use neutral placeholders everywhere else. Vendor-specific data that the user imports at runtime flows through as data, never as literals in the codebase.
No emoji or decorative glyphs
Section titled “No emoji or decorative glyphs”Do not hardcode emoji or decorative glyph symbols in source, including log lines, UI and CLI strings, comments, and doc strings. They render inconsistently across terminals and fonts. Use plain descriptive text. If you need a status marker, prefer a word or a shared constant.
Comments
Section titled “Comments”Keep comments minimal. Document only non-obvious intent or constraints that the code cannot convey. Do not write narrative prose, change history, or restatements of the code.
Git commits
Section titled “Git commits”- Short, imperative subject that aims for 50 characters or less, optionally
with a conventional prefix:
fix: preset shell nodes blocked by validation. - No co-author or attribution trailers of any kind.
- Body only when it earns its place. Use it to explain the why, not the what.
- Verify first. Run the pre-commit checks for the change type before you commit.
DSL changes
Section titled “DSL changes”Anything touching the DSL goes through the spec pipeline: the compiled spec is
generated, never hand-edited, and it feeds both the in-app generator prompt
and the model-training corpus downstream. Preserve the round-trip property
(serialize(parse(s)) is a fixed point), and re-run the spec build plus the
parser tests. See the tech stack.
Related
Section titled “Related”- Tech stack
- API documentation
- Installation - toolchain setup.