docs/how-to-make-a-project-flow-project.md
This guide is for both:
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:
flow.toml at repo root.[[tasks]] in flow.toml.f env instead of committed .env files.f commit with explicit quality/testing policy..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 latest
Why:
f doctor catches missing tooling and shell issues early.f auth login enables cloud-backed features (f env, remote flows).f latest avoids inconsistent command behavior across team members.From repository root:
cd /path/to/repo
f setup
f setup will:
.ai/, .gitignore integration)flow.toml if missingflow.toml filessetup task if one existsIf flow.toml does not exist yet, f setup is the fastest way to initialize safely.
flow.toml BaselineUse 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 = 600
Notes:
dev, test, build, deploy) so AI sessions stay consistent.If you already have scripts in package.json, Makefile, shell scripts, or CI configs:
flow.toml.f <task> the public entrypoint.f commands 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.
f envDo 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 value
Run commands with injected env:
f env run -e dev -- f dev
If 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 commit
Recommended:
f commit for normal flow (fast commit + deferred deep review)f commit --slow when you want blocking review before commitPolicy lives in flow.toml:
[commit.testing] for local test gate[commit.skill_gate] for required skills[invariants] for project-specific guardrailsTreat --skip-tests / --skip-quality as emergency-only.
Initialize AI task pack:
f tasks init-ai
f tasks list
f ai:starter
This creates .ai/tasks/*.mbt entries that can be run like normal tasks.
Use this for:
Choose one deploy target in flow.toml:
[host] for Linux SSH deploys[cloudflare] for Workers[railway] for RailwayThen run:
f deploy
Avoid ad hoc deploy commands in docs/CI when equivalent f deploy flow exists.
Make team defaults explicit:
f setup, f dev, f test, f commit.f test, f build) instead of bespoke command chains.Simple CI shape:
f setup
f test
f build
Run this from repo root:
f setup
f tasks list
f test
f env list -e dev
f commit --dry
You are done when:
flow.toml defines all core workflows as tasks.f env, not committed files.f commit runs with your intended testing/quality policy.f setup + f tasks list.npm run ... in docs and f ... in flow): pick Flow as canonical.[commit.testing], [commit.skill_gate], and invariants intentionally.flow.toml as 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