This guide is for both:
- a brand-new repository
- an existing repository that already has scripts/tooling
The goal is to make flow.toml the project control plane so local development, AI workflows, quality gates, and deploy operations all run through f.
A project is Flow-managed when it has:
- A
flow.tomlat repo root. - Core workflows exposed as
[[tasks]]inflow.toml. - Secrets/environment managed by
f envinstead of committed.envfiles. - Commits made through
f commitwith explicit quality/testing policy. - Optional AI task and skills wiring (
.ai/tasks,.ai/skills,[skills]).
If your team can run f tasks, f <task>, f env, and f commit end-to-end from repo root, the project is Flow-native.
On each developer machine:
f doctor
f auth login
f latestWhy:
f doctorcatches missing tooling and shell issues early.f auth loginenables cloud-backed features (f env, remote flows).f latestavoids inconsistent command behavior across team members.
From repository root:
cd /path/to/repo
f setupf setup will:
- bootstrap project metadata (
.ai/,.gitignoreintegration) - generate
flow.tomlif missing - append missing Codex baseline sections in existing
flow.tomlfiles - run
setuptask if one exists
If flow.toml does not exist yet, f setup is the fastest way to initialize safely.
Use this as a practical starter and replace commands with your real project commands.
version = 1
name = "my-project"
[skills]
sync_tasks = true
install = ["quality-feature-delivery"]
[skills.codex]
generate_openai_yaml = true
force_reload_after_sync = true
task_skill_allow_implicit_invocation = false
[[tasks]]
name = "setup"
command = "echo 'project setup checks here'"
description = "Prepare local environment and verify prerequisites"
[[tasks]]
name = "dev"
command = "npm run dev"
description = "Start local development server"
[[tasks]]
name = "test"
command = "npm test"
description = "Run test suite"
[[tasks]]
name = "test-related"
command = "npm run test:related"
description = "Run smallest useful tests for current diff"
[[tasks]]
name = "lint"
command = "npm run lint"
description = "Lint source code"
[[tasks]]
name = "build"
command = "npm run build"
description = "Build production artifacts"
[commit]
review_instructions_file = ".ai/commit-review-instructions.md"
[commit.testing]
mode = "block"
require_related_tests = true
max_local_gate_seconds = 30
[commit.skill_gate]
mode = "block"
required = ["quality-feature-delivery"]
[invariants]
mode = "warn"
architecture_style = "layered architecture with task-based workflows"
non_negotiable = [
"do not bypass Flow tasks for standard workflows",
"keep user-visible changes documented"
]
forbidden = ["git reset --hard", "git add -A .env"]
[invariants.files]
max_lines = 600Notes:
- Keep task names short and stable (
dev,test,build,deploy) so AI sessions stay consistent. - Prefer one canonical task per workflow. Avoid duplicate aliases with different behavior.
If you already have scripts in package.json, Makefile, shell scripts, or CI configs:
- Map each workflow to one Flow task in
flow.toml. - Keep script internals if needed, but make
f <task>the public entrypoint. - Update docs/README to reference
fcommands first.
Example mapping:
npm run dev->[[tasks]] name = "dev"make test->[[tasks]] name = "test"./scripts/release.sh->[[tasks]] name = "release"
This prevents "works on my machine" command drift.
Do not commit secrets in repo files.
Use project-scoped env values:
f env project set -e dev API_KEY=sk-...
f env project set -e production API_KEY=sk-...
f env list -e dev
f env get -e production API_KEY -f valueRun commands with injected env:
f env run -e dev -- f devIf your project deploys to Cloudflare, declare env policy in flow.toml and use f env apply / f deploy cf.
Once baseline tasks and env are ready, enforce commit behavior:
f commitRecommended:
f commitfor normal flow (fast commit + deferred deep review)f commit --slowwhen you want blocking review before commit
Policy lives in flow.toml:
[commit.testing]for local test gate[commit.skill_gate]for required skills[invariants]for project-specific guardrails
Treat --skip-tests / --skip-quality as emergency-only.
Initialize AI task pack:
f tasks init-ai
f tasks list
f ai:starterThis creates .ai/tasks/*.mbt entries that can be run like normal tasks.
Use this for:
- structured automation
- repo-specific AI workflows
- low-latency repeatable helper routines
Choose one deploy target in flow.toml:
[host]for Linux SSH deploys[cloudflare]for Workers[railway]for Railway
Then run:
f deployAvoid ad hoc deploy commands in docs/CI when equivalent f deploy flow exists.
Make team defaults explicit:
- README Quick Start uses
f setup,f dev,f test,f commit. - CI scripts call Flow tasks (
f test,f build) instead of bespoke command chains. - Contributors run from repo root to avoid task resolution surprises.
Simple CI shape:
f setup
f test
f buildRun this from repo root:
f setup
f tasks list
f test
f env list -e dev
f commit --dryYou are done when:
flow.tomldefines all core workflows as tasks.- Secrets are in
f env, not committed files. f commitruns with your intended testing/quality policy.- New contributors can get productive with
f setup+f tasks list. - CI and deploy flows run through Flow entrypoints.
- Keeping parallel command paths (
npm run ...in docs andf ...in flow): pick Flow as canonical. - Defining tasks without descriptions: hurts discoverability for humans and AI.
- Leaving commit policy at defaults: set
[commit.testing],[commit.skill_gate], and invariants intentionally. - Treating
flow.tomlas static: update it whenever workflow changes.
docs/flow-toml-spec.mddocs/commands/setup.mddocs/commands/tasks.mddocs/commands/env.mddocs/commands/commit.mddocs/how-to-use-flow-to-deploy.md