Dev Loop
This page describes the local development loop used inside the FrankenTUI
workspace. It applies whether you’re an AI agent working on the codebase
per AGENTS.md, a contributor maintaining a fork, or anyone running the
workspace’s own tests.
This is not a tutorial for consumers of FrankenTUI — for that, see project setup. This is the inside-the-workspace loop: check, clippy, fmt, test, snapshot, bench.
Read this alongside project philosophy (no outside PR merges) and snapshot blessing (how snapshot baselines get updated).
Toolchain
FrankenTUI requires nightly Rust, pinned via rust-toolchain.toml
at the workspace root:
[toolchain]
channel = "nightly"
components = ["rust-src", "rustfmt", "clippy"]The toolchain file selects nightly automatically when you run Cargo from
the workspace directory. If you see the option '-Z' is only accepted on the nightly compiler, something is bypassing the toolchain file —
usually IDE integration that pins a different channel.
Mental model
The check / clippy / fmt gate
Every substantive change runs through three gates. If any fail, stop and fix — don’t layer more changes on top.
cargo check --workspace --all-targetsCatches compile errors and warnings (warnings-as-errors are enforced by the workspace lints).
cargo clippy --workspace --all-targets -- -D warningsClippy runs pedantic + nursery lints. -D warnings promotes any
remaining warning to an error. Fix the lint; don’t #[allow] it unless
you have a crate-level reason.
cargo fmt --checkChecks formatting. Run cargo fmt (no --check) to apply.
Tests
Every component crate has inline #[cfg(test)] unit tests. Cross-crate
integration tests live in the workspace tests/ directory.
cargo test --workspace
# Or per-crate:
cargo test -p ftui-core
cargo test -p ftui-render
cargo test -p ftui-style
cargo test -p ftui-text
cargo test -p ftui-layout
cargo test -p ftui-runtime
cargo test -p ftui-widgets
cargo test -p ftui-extras
cargo test -p ftui-harnessFor snapshot tests:
cargo test -p ftui-demo-showcase
BLESS=1 cargo test -p ftui-demo-showcase # update baselines
cargo insta review # review interactivelySee snapshot blessing for the contributor-side protocol.
E2E scripts
Scripted end-to-end tests live under scripts/:
./scripts/e2e_test.sh
./scripts/widget_api_e2e.sh
./scripts/demo_showcase_e2e.sh
./scripts/pane_e2e.sh --mode smoke
./scripts/pane_e2e.sh --mode fullFor deterministic runs:
E2E_DETERMINISTIC=1 E2E_SEED=0 E2E_TIME_STEP_MS=100 ./scripts/e2e_test.sh
E2E_DETERMINISTIC=1 E2E_SEED=42 ./scripts/demo_showcase_e2e.shdoctor_frankentui verification stack
A canonical local verification stack for the doctor_frankentui crate.
Requires cargo, python3, jq, rg (ripgrep), cargo-llvm-cov, and
Python TOML parser support (tomllib in Python 3.11+ or tomli for
older Python).
# Unit + integration
cargo test -p doctor_frankentui --all-targets -- --nocapture
# Workflow-level E2E
./scripts/doctor_frankentui_happy_e2e.sh /tmp/doctor_frankentui_ci/happy
./scripts/doctor_frankentui_failure_e2e.sh /tmp/doctor_frankentui_ci/failure
# Determinism soak (fails on non-volatile divergence)
./scripts/doctor_frankentui_determinism_soak.sh /tmp/doctor_frankentui_ci/determinism 3
# Coverage gate
./scripts/doctor_frankentui_coverage.sh /tmp/doctor_frankentui_ci/coverageCI runs the same contract in the doctor-frankentui-verification job
and uploads artifacts under /tmp/doctor_frankentui_ci/. See AGENTS.md
for the artifact manifest.
Editing discipline (from AGENTS.md)
Three rules apply to anyone editing the workspace. They’re enforced by
convention and (for agents) by the AGENTS.md policy.
No file deletion without explicit permission
You are never allowed to delete a file without explicit, written permission from the project owner. Even a test file you yourself created. Agents have a horrible track record of deleting important work; this rule eliminates the failure mode entirely.
If a file should not exist, say so in an issue and wait for a decision.
No script-based changes
Do not run scripts that process or edit code files in the repo. Brittle regex-based transformations create far more problems than they solve. Changes that touch many files should use:
- Parallel subagents making manual, per-file edits, or
- Methodical hand edits for anything subtle.
Never a regex sweep.
Revise in place
New files are reserved for genuinely new functionality that cannot
sensibly live in an existing file. Do not create variant files like
mainV2.rs, main_improved.rs, main_enhanced.rs. If you need to
change something, edit the original.
The bar for creating a new file is incredibly high. Check whether your addition belongs in any of the 20 existing crates first.
Backwards compatibility
The project is pre-v1 with no outside users. We do not care about backwards compatibility:
- Never create compatibility shims.
- Never create wrapper functions for deprecated APIs.
- Just fix the code directly.
The goal is zero tech debt, not migration paths.
Unsafe policy
Render, runtime, and layout crates declare #![forbid(unsafe_code)].
If a change needs unsafe, file an issue first and get a decision.
Benchmark-driven “unsafe saves N microseconds” arguments are rarely
sufficient — see design decisions.
Pitfalls
Don’t let warnings accumulate. cargo check runs with
workspace-level lint settings; a warning today becomes a CI failure
tomorrow when another lint trips and the -D warnings gate fires on
something you thought was unrelated.
Don’t commit without running the three gates. Check, clippy, fmt-check. A broken gate on main blocks every other contributor until it’s fixed.
Don’t skip the snapshot review. If you changed a widget, a style,
or a layout, snapshot-test results will differ. Run cargo insta review, accept intentional changes, reject unexpected ones, and
commit the baseline updates alongside your code change.
Don’t edit AGENTS.md without coordinating. That file is the
source of truth for agent behavior across the workspace. Changes
propagate via agent policies and cannot be rolled back easily.