MoFlo
A standalone, opinionated AI agent orchestration toolkit for Claude Code, optimized for local development.
TL;DR
MoFlo makes Claude Code remember what it learns, check what it knows before exploring files, and get smarter over time — all automatically. Install it, run flo init, restart Claude Code, and everything just works: your docs and code are indexed on session start so Claude can search them instantly, gates prevent Claude from wasting tokens on blind exploration, task outcomes feed back into routing so it picks the right agent type next time, and context depletion warnings tell you when to start a fresh session. No configuration, no API keys, no cloud services — it all runs locally on your machine.
Quickstart
npm install --save-dev moflo
flo init
Restart Claude Code. That's it — memory, indexing, gates, and routing are all active.
Or — just ask Claude to install MoFlo into your project and initialize it!
To verify everything is running, run the /healer skill inside Claude Code (or flo healer from the CLI) after restarting — it runs full diagnostics. If anything fails, run /healer --fix to automatically fix issues.
Next Step: Consult the Eldar
After installing moflo, the single highest-leverage thing you can do for the best experience is run /eldar inside a Claude Code session.
Where /healer (or flo healer from the CLI) verifies that moflo itself is wired up correctly, /eldar audits how Claude is set up to actually use your project — guidance docs, CLAUDE.md, memory namespaces, hook/MCP wiring, model routing, and whether every technology in your stack (TypeScript, Python, Rust, Go, etc.) has matching guidance for Claude to lean on. The stack → guidance cross-reference alone is often the difference between "Claude feels lost in this codebase" and "Claude knows this codebase".
/eldar # Read-only audit; categorized findings, severity-ranked
/eldar --fix # Interactive triage — pick what to fix and the Eldar walk you through it
Run it on day one in any new project, any time Claude feels off, or as a periodic health check. Outside of the core install, this is the most impactful thing moflo offers — full details in the /eldar section further down.
Opinionated Defaults
MoFlo makes deliberate choices so you don't have to:
- Fully self-contained — No external services, no cloud dependencies, no API keys. Everything runs locally on your machine.
- Minimal dependencies — small runtime dep set, all WASM or prebuilt binaries. No native compilation, no
node-gyp, no platform-specific build steps. - Node.js runtime — Targets Node.js specifically. All scripts, hooks, and tooling are JavaScript/TypeScript. No Python, no Rust binaries, no native compilation.
- node:sqlite (built-in) — The memory database uses Node 22's built-in SQLite engine. No
better-sqlite3native bindings to compile, no WASM round-trip, no platform-specific build steps. Works identically on Windows, macOS, and Linux. - Neural embeddings by default — 384-dimensional embeddings using
all-MiniLM-L6-v2. No hash fallback, no peer-optional setup, no install prompts — real semantic search works out of the box. Apostinstallstep trims the embedding runtime to your platform and strips GPU-only libraries the runtime never loads, reclaiming roughly 340 MB on Linux and 150 MB on Windows from a fresh install. SetMOFLO_NO_PRUNE=1to skip the trim, orONNXRUNTIME_NODE_INSTALL_CUDA=trueto keep CUDA GPU support. - Full learning stack wired up OOTB — All configured and functional from
flo init, no manual setup:- SONA (Self-Optimizing Neural Architecture) — learns from task trajectories
- MicroLoRA — fast rank-2 weight adaptations from successful patterns
- EWC++ (Elastic Weight Consolidation) — prevents catastrophic forgetting across sessions
- HNSW Vector Search — fast nearest-neighbor search over your knowledge base
- Semantic Routing — maps tasks to the right agent via learned patterns (ReasoningBank)
- Trajectory Persistence — outcomes survive across sessions
- All local, no GPU, no API keys, no external services.
- Memory-first — Claude must search what it already knows before exploring files. Enforced by hooks, not just instructions.
- Task registration before agents — Sub-agents can't spawn until work is tracked. Prevents runaway agent proliferation.
- Learned routing — Task outcomes feed back into the routing system automatically. No manual configuration needed — it gets smarter with use.
- Incremental indexing — Guidance and code map indexes run on every session start but skip unchanged files. Fast after the first run.
- Claude Code is the only target — MoFlo is built and shipped for Anthropic's Claude Code (CLI, IDE extensions, web). It is not a Claude Desktop integration: nothing reads from or writes to
~/.claude/claude_desktop_config.jsonor%APPDATA%/Claude/, and adding paths there is always a bug. The MCP tools, memory system, and hooks could in principle work with any MCP-capable client, but Claude Code is the only surface we author for, test against, or accept bug reports on. - GitHub-oriented — The
/floskill, PR automation, and issue tracking are built around GitHub. With Claude's help, you can adapt them to your own issue tracker and source control system. - Cross-platform — Works identically on macOS, Linux, and Windows.
Features
Getting Started
1. Install and init
npm install --save-dev moflo
flo init
flo init automatically scans your project to find where your guidance, code, and tests live, then writes the results into moflo.yaml. It looks for:
It also generates:
In interactive mode (flo init without --yes), it shows what it found and lets you confirm or adjust before writing.
Migrating from Claude Flow / Ruflo
If flo init detects an existing .claude/settings.json or .claude-flow/ directory (from a prior Claude Flow or Ruflo installation), it treats the project as already initialized and runs in update mode — merging MoFlo's hooks and configuration into your existing setup without overwriting your data. Specifically:
- Hooks — If your
.claude/settings.jsonalready has MoFlo-style gate hooks (flo gate), the hooks step is skipped. Otherwise, MoFlo's hooks are written into the file (existing non-MoFlo hooks are not removed). - MCP servers — MoFlo registers itself as the
mofloserver in.mcp.json. If you hadclaude-floworrufloMCP servers configured previously, those entries remain untouched — you can remove them manually once you've verified MoFlo is working. The/healerskill (orflo healerfrom the CLI) checks for themofloserver specifically. - Config files —
moflo.yaml,CLAUDE.md, and.claude/skills/flo/follow the same skip-if-exists logic. Use--forceto regenerate them.
To force a clean re-initialization over an existing setup:
flo init --force
First-run heads-up: brief CPU spike during initial indexing
The very first time MoFlo runs in your project — typically right after flo init and the next session start — it builds the initial guidance, code map, and test indexes from scratch and generates 384-dim embeddings for every chunk. On a medium-sized project this takes one to a few minutes and you may see elevated CPU during that window. It runs in the background, so you can start working immediately; you just might hear your fans for a bit.
After that first pass, indexing is incremental and lazy — every subsequent session start only re-processes files that actually changed since the last run, which typically finishes in under a second with no perceptible CPU activity. The big one-time cost is a deliberate trade: pay it once, then every future session opens with your project already searchable by meaning.
Tip: Let that initial indexing finish before running
/healer(orflo healer). Healer's embeddings and semantic-quality checks expect the indexes to exist — if you run it mid-build it may flag warnings that resolve themselves the moment indexing completes.
2. Review your guidance and code settings
Open moflo.yaml to see what init detected. The two key sections:
Guidance — documentation that helps Claude understand your project (conventions, architecture, domain context):
guidance:
directories:
- .claude/guidance # project rules, patterns, conventions
- docs # general documentation
Code map — source files to index for "where does X live?" navigation:
code_map:
directories:
- src # your source code
- packages # shared packages (monorepo)
extensions: [".ts", ".tsx"]
exclude: [node_modules, dist, .next, coverage]
Tests — test files to index for "what tests cover X?" reverse mapping:
tests:
directories:
- tests # your test files
- __tests__ # jest-style test dirs
patterns: ["*.test.*", "*.spec.*", "*.test-*"]
extensions: [".ts", ".tsx", ".js", ".jsx"]
exclude: [node_modules, coverage, dist]
namespace: tests
MoFlo chunks your guidance files into semantic embeddings, indexes your code structure, and maps test files back to their source targets — so Claude searches your knowledge base before touching any files. Adjust these directories to match your project:
# Monorepo with shared docs
guidance:
directories: [.claude/guidance, docs, packages/shared/docs]
code_map:
directories: [packages, apps, libs]
# Backend + frontend
code_map:
directories: [server/src, client/src]
3. Index and verify
flo memory index-guidance # Index your guidance docs
flo memory code-map # Index your code structure
flo healer # Verify everything works (alias: flo doctor)
Both indexes run automatically at session start after this, so you only need to run them manually on first setup or after major structural changes. The first index may take a minute or two on large codebases (1,000+ files) but runs in the background — you can start working immediately. Subsequent indexes are incremental and typically finish in under a second. To reindex everything at once:
flo memory refresh # Reindex all content, rebuild embeddings, cleanup, vacuum
Auto-Indexing
MoFlo automatically indexes three types of content on every session start, so your AI assistant always has up-to-date knowledge without manual intervention.
What gets indexed
How it works
- Session start hook — When Claude Code starts a new session, MoFlo's
SessionStarthook launches the indexers sequentially in a single background process. This runs silently — you can start working immediately. - Incremental — Each indexer tracks file modification times. Only files that changed since the last index run are re-processed. The first run on a large codebase may take a minute or two; subsequent runs typically finish in under a second.
- Embedding generation — Guidance chunks are embedded using MiniLM-L6-v2 (384 dimensions, WASM). These vectors are stored in the SQLite memory database and used for semantic search.
- No blocking — The indexers run in the background and don't block your session from starting. You can begin working immediately.
Configuration
Each indexer can be toggled independently in moflo.yaml:
auto_index:
guidance: true # Index docs on session start
code_map: true # Index code structure on session start
tests: true # Index test files on session start
Set any to false to disable that indexer. The underlying data remains in memory — you just stop refreshing it automatically. You can still run indexers manually:
flo memory index-guidance # Manual guidance reindex
flo memory code-map # Manual code map reindex
flo memory refresh # Reindex everything + rebuild embeddings + vacuum
Why this matters
Without auto-indexing, Claude Code starts every session with a blank slate — it doesn't know what documentation exists, where code lives, or what tests cover which files. It resorts to Glob/Grep exploration, which burns tokens and context window on rediscovery.
With auto-indexing, Claude can search semantically ("how does auth work?") and get relevant documentation chunks ranked by similarity, or ask "where is the user model defined?" and get a direct answer from the code map — all without touching the filesystem.
Learning From Your Sessions
MoFlo turns the work you do into durable knowledge. A lesson worth keeping — a reusable pattern, a gotcha that cost you an hour, a decision and the rationale behind it — lands in the learnings memory namespace, where it's embedded and semantically searchable in every future session. Two paths feed that namespace: one you trigger, one that runs on its own.
/meditate — deliberate retrospective
Run /meditate at the end of a meaningful chunk of work. It reviews the session, distills the handful of lessons that would help a future session on a different task, deduplicates them against what's already stored, and writes the survivors to learnings. It's the curated pass — you choose when to capture, and it keeps only high-signal items (an empty reflection is a valid result, not a failure to pad).
/meditate # Review the whole session and store durable lessons
/meditate --preview # Show the candidate lessons without writing anything
/meditate <focus> # Scope the retrospective to one thread, e.g. "the auth refactor"
Auto-meditate — the automatic counterpart
Auto-meditate does the same job without being asked. While you work, a lightweight hook notices when a durable lesson emerges — a correction, an error you fixed, a decision you made. At the next session start, a brief background pass distills those into learnings using the same durability bar and dedup-then-store protocol as /meditate. It reuses your existing Claude Code session (no extra API key), runs in the background, and ships on by default.
auto_meditate:
enabled: true # Set to false to opt out — /meditate still works manually
The two are complementary: auto-meditate is the always-on safety net, /meditate is the deliberate, curated pass. Both write to the same learnings namespace and both deduplicate, so neither pollutes the other — and anything they store is available to semantic search from then on.
Sharing learnings across installations
The learnings (and knowledge) namespaces are the durable slice of memory — user-authored and worth carrying across checkouts. The rest of the DB (code-map, guidance chunks, run state) is structural or ephemeral and rebuilds cheaply, so it stays local. For ongoing sync MoFlo shares only the durable slice — never live-shares the whole moflo.db between two daemons, which would make each daemon's in-memory search index diverge.
Pick the mechanism by topology:
Verify your setup with flo doctor -c shared-db (it warns if you've accidentally pointed at a full moflo.db for live sharing). Full guide: moflo-cross-install-memory-sharing.md.
The Gate System
MoFlo installs Claude Code hooks that run on every tool call. Together, these gates create a feedback loop that prevents Claude from wasting tokens on blind exploration and ensures it builds on prior knowledge.
Gates explained
Smart classification
The memory-first gate doesn't blindly block every request. It classifies each prompt:
- Simple directives (e.g., "commit", "yes", "continue", "looks good") — skip the gate entirely, no memory search required
- Task-oriented prompts (e.g., "fix the auth bug", "add pagination to the API") — gate enforced, must search memory first
Escape hatch
Prefix any prompt with @@ to bypass the memory-first gate for that turn. Useful for conversational questions, thinking out loud, or discussions that don't need prior context:
@@ what do you think about this approach?
@@ question — is there a better way to handle auth tokens?
The @@ prefix is stripped before Claude sees the prompt, so it won't affect the response.
Disabling gates
All gates are configurable in moflo.yaml:
gates:
memory_first: true # Set to false to disable memory-first enforcement
task_create_first: true # Set to false to disable TaskCreate enforcement (disables task_status_gate too)
task_status_gate: block # Open tasks block `gh pr create`; warn → report only; off → silent
context_tracking: true # Set to false to disable the context-usage notice
# context_limit: 200k # Optional. Your model's window, so the notice can quote a %.
# Unset (default) = report raw tokens; moflo never guesses a window.
verify_before_done: true # On by default (#1294); set false to skip /verify before `gh pr create`
You can also disable individual hooks in .claude/settings.json by removing the corresponding hook entries.
The /flo Skill
Inside Claude Code, the /flo (or /fl) slash command drives GitHub issue execution:
/flo <issue> # Full process (research → implement → test → PR)
/flo -t <issue> # Ticket only (research and update ticket, then stop)
/flo -r <issue> # Research only (analyze issue, output findings)
/flo -s <issue> # Swarm mode (multi-agent coordination)
/flo -h <issue> # Hive-mind mode (consensus-based coordination)
/flo -n <issue> # Normal mode (default, single agent, no swarm)
/flo -w <issue> # Worktree: run the work in a fresh git worktree (aliases: -wt, --worktree)
/flo -sd <issue> # SDD: spec → plan → implement → verify (implies --verify)
/flo -v <issue> # Verify-before-done only (no spec/plan front-half)
/flo -m <issue> # Auto-merge the PR once required checks pass
Flags compose: e.g. /flo -sd -m <issue> runs the SDD cycle and auto-merges. Each modifier has a --no-* form (--no-sdd, --no-verify, --no-merge) to override a moflo.yaml default for a single run — including --no-verify, since verify-before-done is on by default. For full options and details, type /flo with no arguments — Claude Code will display the complete skill documentation. Also available as /fl.
Provisioned worktrees (-w / flo worktree)
Running two tickets at once means two worktrees, and a bare git worktree add gives you a valid
checkout that you cannot actually run: no node_modules, none of your gitignored .env files, and
dev servers that fight the primary checkout over the same ports. /flo -w drives flo worktree add,
which creates the worktree and provisions it.
Provisioning is opt-in per project. With no worktree: block in moflo.yaml, flo worktree add
creates the worktree and provisions nothing — exactly what a plain git worktree add would do.
worktree:
dir: ../myrepo-worktrees # default: <repo-parent>/<repo>-worktrees
copy: [".env", ".env.*"] # gitignored files copied from the primary checkout
link: ["node_modules"] # symlinked (junctioned on Windows) from the primary checkout
setup: "npm ci" # run inside the new worktree after copy/link
Ports. MoFlo cannot rewrite your hardcoded ports — it has no way to know which files hold them.
Instead each worktree gets a small integer, unique among live worktrees and reused when one is
removed, exported to the setup command as MOFLO_WORKTREE_INDEX. Offset your own ports from it:
worktree:
setup: "npm ci && node -e \"require('fs').writeFileSync('.env.local','PORT='+(3000+Number(process.env.MOFLO_WORKTREE_INDEX)*20))\""
flo worktree remove refuses a tree with uncommitted changes unless you pass --force, and names
any gitignored files it discarded that provisioning did not create. MoFlo's own
.moflo/worktree.json never counts as "uncommitted work" — otherwise every worktree it created
would demand --force — but un-pushed specs under .moflo/specs/ do.
Memory needs no setup at all: durable learnings already converge across a repo's worktrees automatically — see Sharing learnings across installations.
Running it inside a Claude session
flo worktree is a plain CLI command with no MCP wrapper, so it works the same whether you type it
in a terminal or Claude runs it through Bash. /flo -w takes the second path — that is all the flag
does.
One thing to know if you drive it yourself from a session, and the reason /flo -w handles it for
you: Claude Code resets the Bash working directory to the project root after every call. Two
consequences, both silent when you get them wrong:
# ✗ the cd is gone by the next call — this resolves the WRONG repo
cd path/to/repo
flo worktree add feature/42-thing --json
# ✓ bind the directory to the call
cd path/to/repo && flo worktree add feature/42-thing --json
# ✗ runs the tests in the PRIMARY checkout; the run goes green and the PR is empty
cd "$WORKTREE"
npm test
# ✓ bind it, or skip cd entirely where the tool supports it
cd "$WORKTREE" && npm test
git -C "$WORKTREE" status
flo worktree resolves the repository from its working directory, so a call made from the wrong
place targets a different repository — usually reported as Not a registered worktree of this repo,
occasionally as work landing somewhere you did not intend. When editing files in the worktree, use
absolute paths under the path add printed rather than repo-relative ones.
Read the worktree location from --json rather than reconstructing it; the sibling-directory
convention lives in one tested function, and a second copy of that rule will drift from it.
If you are on a flo older than the skills synced into .claude/ — which happens in a MoFlo source
checkout before a change is published, or when a global flo lags the project's devDependency —
the command reports Unknown command: worktree. /flo -w falls back to a plain git worktree add
and tells you provisioning was skipped, rather than failing the run.
Spec-Driven Development (SDD)
/flo can run the full spec → plan → (review) → implement → verify cycle — the 2026 agentic-coding pattern — with two independent modifiers. Turning SDD on is opt-in, but once a run is armed for it (via -sd or sdd.default) both halves are enforced: the front half by an implement gate, the back half by verify-before-done.
-sd/--sdd(opt-in; enforced once on) — author a spec (the what + acceptance criteria) and a plan (the steps) before implementing. When armed, thecheck-before-implementgate blocks every sourceWrite/Edituntil the spec exists and its plan is reviewed (#1297) — a run can't skip straight to code. Artifacts persist as Markdown at<specs_dir>/<slug>/{spec,plan}.md(default.moflo/specs) and are indexed into memory, so prior specs are searchable across sessions. Implies--verify.-v/--verify(on by default) — the verify half: a normal run plus the verify-before-done gate. It runs the/verifyskill, which exercises the change end-to-end against its acceptance criteria and reports a per-criterion PASS/FAIL, reusing the run's own tests (no double verify). Runs by default;--no-verifyskips it. Separable from SDD, so you get "prove it works" without the spec ceremony.
Human review is optional and off by default. moflo stays autonomous: the front half self-advances its spec/plan review checkpoints without stopping. Set sdd.human_checkpoints: true to sit in the loop and approve each artifact by hand before the cycle proceeds.
Both compose with execution mode (-n/-s/-h) and --worktree, and default from moflo.yaml:
sdd:
default: false # true → every /flo run uses the SDD cycle unless --no-sdd
specs_dir: .moflo/specs # where spec/plan artifacts are written (see below)
human_checkpoints: false # true → pause for human approval at spec & plan review (default: autonomous)
embed_in_pr: true # true → append spec+plan to the PR body so reasoning is reviewable
gates:
verify_before_done: true # on by default (#1294); false → skip /verify unless -v. Per-run: --no-verify
sdd_gate: true # on by default (#1297); false → don't enforce the spec→plan front half
On upgrade, consumers with no verify_before_done key start enforcing verify-before-done; an explicit value is preserved. sdd_gate only bites when a run is actually armed for SDD, so non-SDD work is unaffected. Docs-only diffs are exempt, so a pure-docs PR is never blocked.
Where specs live — and making them reviewable. By default spec/plan artifacts are written under .moflo/specs, which flo init gitignores — so they stay local and never bloat source control — and (with embed_in_pr, the default) the spec + plan are appended to the PR body, so the reasoning is reviewable in the PR even while the files stay local. If you'd rather source-control the artifacts, point sdd.specs_dir at a tracked path (e.g. docs/specs or .specs) and commit them normally; no gitignore surgery required — the two mechanisms compose. The path is written with / and resolved cross-platform. If you set it to a directory already covered by guidance.directories, moflo indexes the specs once (as guidance) rather than twice.
--sdd implies --verify (a spec/plan without an enforced verify step drifts). Manage artifacts directly with flo sdd (spec, plan, review, check, embed, list), and start from a fuzzy idea with /commune, which can hand its synthesized spec straight into the SDD spine. Wiring status is reported by /healer (and /eldar).
Auto-merge
-m/--merge— after the PR is opened, await its merge preconditions and merge it, instead of stopping at "PR opened". Orthogonal to execution mode (-n/-s/-h),--worktree, and--sdd/--verify, and always runs after the quality gates (tests, simplify, learnings, verify) have letgh pr createthrough — so--mergenever bypasses a gate.
It prefers GitHub-native auto-merge, falls back to poll-then-merge once required checks are green, and — when the only remaining blocker is review-required on a repo you administer (e.g. a solo repo where GitHub blocks self-approval) — auto-attempts an admin squash-merge. If an unattended admin merge is denied by Claude Code's permission classifier (headless/cron runs), it hands you a copy-paste command rather than looping. It re-confirms checks are green before any admin merge, and never --admin over a red or pending required check.
Default seeds from moflo.yaml; the per-run flag overrides, and --no-merge opts a single run out:
merge:
auto: false # true → every /flo run auto-merges its PR unless --no-merge
Epic handling
When you pass an issue number, /flo automatically checks if it's an epic — no extra flag needed. An issue is treated as an epic if any of these are true:
- It has a label matching
epic,tracking,parent, orumbrella(case-insensitive) - Its body contains a
## Storiesor## Taskssection - Its body has checklist-linked issues:
- [ ] #101 - Its body has numbered issue references:
1. #101 - The issue has GitHub sub-issues (via the API)
When an epic is detected, /flo processes each child story sequentially — full process per story (research → implement → test → PR), one at a time, in the order listed.
For simple epics with independent stories, /flo <epic> is all you need. For complex features where you want state tracking, resume capability, and auto-merge between stories, use flo epic instead.
Feature Orchestration (flo epic)
flo epic is the robust epic runner — it adds persistent state, resume from failure, and per-story auto-merge on top of /flo. It takes a GitHub epic issue number:
flo epic 42 # Fetch epic #42, run all stories sequentially
flo epic 42 --dry-run # Preview execution plan without running
flo epic 42 --strategy auto-merge # Per-story PRs with auto-merge between stories
flo epic status 42 # Check progress (which stories passed/failed)
flo epic reset 42 # Reset state for re-run
flo epic fetches the epic from GitHub, extracts child stories from checklists, numbered references, and ## Stories / ## Tasks sections, then runs each through /flo with state tracking. If a story fails, you can fix the issue and re-run flo epic 42 — it resumes from where it left off, skipping already-passed stories. (flo epic run 42 is an explicit alias for the same shorthand.)
Spells
What are spells?
Spells are declarative YAML automations composed of pluggable step commands. They exist because shell scripts drift, ad-hoc prompts aren't reproducible, and CI/CD pipelines are the wrong tool for local automation. A spell is deterministic (same inputs → same steps), reviewable (a YAML file you read like a recipe), and replayable (re-cast it tomorrow and it behaves the same). Spells run from the CLI (flo spell cast), from an MCP tool call inside Claude Code, or on a schedule.
How do they work?
Each cast goes through the same lifecycle:
- Parse & validate — YAML is parsed and every step's
configis checked against its command's schema. - Resolve capabilities — every step declares what it needs (
shell,net,fs:read,fs:write,memory,credentials,browser,agent). Undeclared access is rejected before execution. - Execute the step graph — steps run sequentially by default, or in parallel groups, with
depends_onfor ordering andcondition/loopfor flow control. - Outputs flow forward — any step can reference a prior step's output as
{stepId.field}, so later steps can consume earlier results. - Persistence — memory writes, artifacts, and per-step logs persist between runs; pause/resume and dry-run are supported.
flo spell cast -n development # Cast a named spell
flo spell cast -f ./my-spell.yaml # Cast from a file
flo spell cast -n sa --dry-run # Validate without casting
flo spell list # List available spells and recent runs
flo spell grimoire list # Browse built-in spell templates
flo spell schedule list # List scheduled spells
Defining spells
name: my-spell
steps:
- name: lint
command: npm run lint
- name: test
command: npm test
- name: deploy
command: ./deploy.sh
depends_on: [lint, test]
Steps support shell (bash), agent spawns, memory reads/writes, conditionals, loops, parallel groups, browser automation, GitHub/IMAP/Outlook/Slack/MCP integrations, prompts, waits, graphs, and composite steps. See docs/SPELLS.md for the full schema.
Sandboxing and security
Spells run with least-privilege access. Each step command declares the capabilities it needs (shell, net, fs:read, fs:write, memory, credentials, browser, browser:evaluate, agent), and the runner blocks any undeclared access. Spell authors can further restrict capabilities per step — e.g. fs:read: ["./config/"] or shell: ["cat", "jq"] — but never expand them.
Bash steps also run inside an OS sandbox when one is available. MoFlo auto-selects the best tier installed on your machine:
The sandbox is network-off by default; a step must explicitly declare net to reach the outside world. Credentials referenced as {credentials.X} are resolved from the encrypted credential store, masked in logs, and never written to disk. A destructive-pattern checker refuses to run bash commands that look like rm -rf /, unscoped git push --force, and similar footguns. See docs/SPELL-SANDBOXING.md for the full model.
Reusability
You interact with spells at three tiers:
- Shipped spells — bundled with MoFlo and ready to cast. Browse them with
flo spell grimoire list. - User spells — YAML files you drop in
.claude/spells/. Override the location inmoflo.yaml:
A user spell with the samespells: userDirs: - .claude/spells - my/project/spellsnameas a shipped one wins — that's how you customize a shipped spell without forking. - Custom step commands and connectors — drop TypeScript/JavaScript files in
.claude/spells/steps/(new step types) and.claude/spells/connectors/(new connectors). They're auto-discovered at startup. Connectors that wrap heavy SDKs (IMAP, MCP) declare those SDKs asoptionalDependencies; install them only if your spells use them.
Scheduling
Spells can run on a schedule. The MoFlo background daemon polls for due spells once a minute and casts them — no external cron, no extra services.
Three timing options:
# Cron (5 fields: minute hour day-of-month month day-of-week)
flo spell schedule create -n nightly-audit --cron "0 2 * * *"
# Interval (e.g., 90s, 30m, 6h, 1d)
flo spell schedule create -n health-check --interval 30m
# One-time (ISO 8601 datetime)
flo spell schedule create -n migration --at 2026-04-15T09:00:00Z
You can also declare a schedule directly inside the spell YAML — that registers it on every daemon start:
name: nightly-audit
schedule:
cron: "0 2 * * *"
steps:
- id: audit
type: bash
config:
command: ./scripts/audit.sh
Daemon prerequisite. Schedules only fire while the daemon is running. To survive reboot:
flo daemon install # registers an OS-level autostart service
flo daemon status # shows whether the service is registered AND running
flo spell schedule create warns when the daemon isn't installed so you don't quietly miss runs.
Monitoring. The Luminarium — moflo's localhost daemon dashboard — surfaces live schedules, recent executions, and per-schedule controls (disable / re-enable / run now), alongside worker health, memory stats, and Claude Code session stats. Ask /luminarium in your Claude session and it'll print the link.
For full configuration (scheduler: block in moflo.yaml), event types, and the catch-up window after restarts, see docs/SPELLS.md#scheduling.
Building spells with the /spell-builder skill
Inside Claude Code, use the /spell-builder skill to create, edit, and validate spell definitions interactively. The skill understands the full spell schema and available step commands, so you can describe what you want in natural language and it will generate the YAML:
/spell-builder # Start the spell builder
Other AI-client skills shipped with MoFlo
Beyond /flo, /spell-builder, and /eldar, MoFlo ships a handful of focused slash-command skills that work in any consumer project once you flo init:
Run any of them with no arguments to see full usage, or browse the source in .claude/skills/ (each skill is a single SKILL.md file).
Epics
Epics are a specialized process for handling GitHub issues that contain multiple child stories. When you pass a GitHub issue to /flo and it's detected as an epic, MoFlo processes each child story sequentially through the full /flo process (research → implement → test → PR).
For simple epics, /flo <epic-number> is all you need. For complex features requiring state tracking, resume from failure, and auto-merge between stories, use the dedicated flo epic command:
flo epic 42 # Run all stories in epic #42
flo epic 42 --strategy auto-merge # Per-story PRs with auto-merge
flo epic 42 --dry-run # Preview execution plan
flo epic status 42 # Check progress
flo epic reset 42 # Reset state for re-run
See the Epic handling section above for detection criteria and the comparison between /flo <epic> and flo epic run.
The Luminarium
The Luminarium is moflo's localhost daemon dashboard. It boots automatically with the background daemon (no extra service to install) and stays running as long as the daemon is up.
Finding the URL
Inside a Claude Code session in a moflo project, ask /luminarium — the skill prints the dashboard URL for the current project. flo daemon status prints the same URL alongside the health summary. Each project binds its own port so two projects on the same machine never collide.
What it shows
Flags
flo daemon start --no-dashboard— disable the HTTP server entirely (the daemon itself still runs)flo daemon start --dashboard-port <N>— pin to a specific port, overriding the per-project default. Also accepts theMOFLO_DAEMON_PORTenv var, which the rest of moflo respects when talking to the daemon
Commands
You don't need to run these for normal use — flo init sets everything up, and the hooks handle memory, routing, and learning automatically. These commands are here for manual setup, debugging, and tweaking.
Memory
flo memory store -k "key" --value "data" # Store with 384-dim embedding
flo memory search -q "auth patterns" # Semantic search
flo memory index-guidance # Index guidance docs
flo memory code-map # Index code structure
flo memory rebuild-index # Regenerate all embeddings
flo memory refresh # Reindex all + rebuild + cleanup + vacuum
flo memory stats # Show statistics
Routing & Learning
flo hooks route --task "description" # Route task to optimal agent
flo hooks learn --pattern "..." --domain "." # Store a pattern
flo hooks patterns # List learned patterns
flo hooks consolidate # Promote/prune patterns
Gates
flo gate check-before-scan # Blocks Glob/Grep if memory not searched
flo gate check-before-agent # Blocks Agent tool if no TaskCreate
flo gate prompt-reminder # Context bracket tracking
flo gate session-reset # Reset gate state
Worktrees
flo worktree add feature/123-thing # Create a worktree and provision it (alias: flo wt)
flo worktree add feature/123 --json # {"path":…,"branch":…,"index":0,"provisioned":true}
flo worktree add feature/123 --from v2.1.0 # Branch off a specific ref
flo worktree add feature/123 --no-provision # Create it, skip copy/link/setup
flo worktree list # Every worktree and its provisioning state
flo worktree remove feature/123-thing # Refuses a dirty tree unless --force
Diagnostics
flo healer # Quick health check (environment, deps, config)
flo healer --fix # Auto-fix issues (memory DB, daemon, config, MCP, zombies)
flo diagnose # Full integration test (memory, swarm, hive, hooks, neural)
flo diagnose --suite memory # Run only memory tests
flo diagnose --json # JSON output for CI/automation
flo doctor is still accepted as an alias for flo healer — every flag and subcommand below works under either name.
flo healer — Health Check
flo healer runs 38 parallel health checks against your environment and reports pass/warn/fail for each:
Auto-fix mode (flo healer --fix) attempts to repair each failing check automatically:
After auto-fixing, healer re-runs all checks and shows the updated results. Issues that can't be fixed automatically are listed with manual fix commands.
Additional flags:
flo healer --install # Auto-install missing Claude Code CLI
flo healer --kill-zombies # Find and kill orphaned MoFlo processes
flo healer -c memory # Check only a specific component
flo healer -c embeddings # Check only embeddings health
flo healer --verbose # Verbose output
/eldar — Consult the Eldar (project setup audit + wizard)
Where the Healer checks your moflo install, /eldar audits how Claude is set up to use the project — guidance, CLAUDE.md, memory namespaces, hook/MCP wiring, model routing, and stack-aware guidance gaps — then walks you through fixing whichever findings you pick. Use it when starting in a new project, when Claude feels lost or inefficient, or as a periodic health check.
/eldar # Read-only audit; categorized report + top-3 ranked recommendation
/eldar --fix # Audit, then interactive triage menu — pick which findings to address
The Eldar consult the Healer (they call flo healer --json as one of the audit checks) — they don't replace it. Categories audited include setup health, index freshness, version skew, model/token routing, CLAUDE.md size + reference integrity, guidance content + structure, memory health, hook/MCP wiring, settings sanity, spell + subagent inventory, stack → guidance cross-reference (detects tech from package.json/pyproject.toml/Cargo.toml/go.mod and flags every detected technology with no matching guidance doc — the highest-leverage finding for new adopters), and best-effort anti-pattern detection from history.
In --fix mode, each chosen finding drives the appropriate sub-flow: Healer for setup repair, the /guidance skill for guidance authoring (wizard, never autogen), a stack-aware scaffold for missing CLAUDE.md, flo init --upgrade for hook/MCP wiring. Every write is confirmed before it lands.
flo diagnose — Integration Tests
While healer checks your environment, diagnose exercises every subsystem end-to-end: memory CRUD, embedding generation, semantic search, swarm lifecycle, hive-mind consensus, task management, hooks, config, neural patterns, and init idempotency. All test data is cleaned up after each test — nothing is left behind.
GitHub Repository Setup
flo github setup # One-shot: generate CI + apply repo settings + branch protection
flo github setup --dry-run # Preview everything without making changes
flo github ci # Generate .github/workflows/ci.yml from project config
flo github ci --dry-run # Print CI config to stdout
flo github settings # Apply repo settings + branch protection via gh CLI
flo github settings --dry-run # Preview settings changes
flo github ci auto-detects your package manager (npm/pnpm/yarn/bun), TypeScript, and test directories from moflo.yaml and package.json, then generates a GitHub Actions CI pipeline with install, build, lint, type-check, and test steps.
flo github settings applies recommended defaults via gh CLI: delete-branch-on-merge, squash merge with PR title/body, auto-merge, linear history, and configurable branch protection (required reviews, dismiss stale reviews, block force pushes). Requires gh auth login.
System
flo init # Initialize project (one-time setup)
flo --version # Show version
What Ships Out of the Box
flo init wires up the following systems automatically. Here's what each one does, why it matters, and whether it's enabled by default.
Hooks (enabled OOTB)
Hooks are shell commands that Claude Code runs automatically at specific points in its lifecycle. MoFlo installs 26 hook bindings across 8 lifecycle events. You don't invoke these — they fire automatically.
Systems (enabled OOTB)
These are the backend systems that hooks and commands interact with.
Systems (available but off by default)
The Two-Layer Task System
MoFlo doesn't replace Claude Code's task system — it wraps it. Claude Code handles spawning agents and running code. MoFlo adds a coordination layer on top that handles memory, routing, and learning.
┌──────────────────────────────────────────────────┐
│ CLAUDE CODE (Execution Layer) │
│ Spawns agents, runs code, streams output │
│ TaskCreate → Agent → TaskUpdate → results │
├──────────────────────────────────────────────────┤
│ MOFLO (Knowledge Layer) │
│ Routes tasks, gates agent spawns, stores │
│ patterns, learns from outcomes │
└──────────────────────────────────────────────────┘
Here's how a typical task flows through both layers:
- MoFlo routes — Before work starts, MoFlo analyzes the prompt and recommends an agent type and model tier via hook or MCP tool.
- MoFlo gates — Before an agent can spawn, MoFlo verifies that memory was searched and a task was registered. This prevents blind exploration.
- Claude Code executes — The actual agent runs through Claude Code's native task system. MoFlo doesn't manage the agent — Claude Code handles execution, output, and completion.
- MoFlo learns — After the agent finishes, MoFlo records what worked (or didn't) in its memory database. Successful patterns feed into future routing.
The key insight: Claude Code handles execution, MoFlo handles knowledge. Claude Code is good at spawning agents and running code. MoFlo is good at remembering what happened, routing to the right agent, and ensuring prior knowledge is checked before exploring from scratch.
For complex work, MoFlo structures tasks into waves — a research wave discovers context, then an implementation wave acts on it — with dependencies tracked through both Claude Code's task system and MoFlo's coordination layer. The full integration pattern is documented in .claude/guidance/moflo-claude-swarm-cohesion.md.
The /flo skill ties both systems together for GitHub issues — driving the full process (research → enhance → implement → test → simplify → PR) with Claude Code's agents for execution and MoFlo's memory for continuity.
Intelligent Agent Routing
MoFlo ships with 12 built-in task patterns that map common work to the right agent type:
When you route a task (flo hooks route --task "..." or via MCP), MoFlo runs semantic similarity against these patterns using HNSW vector search and returns a ranked recommendation with confidence scores.
The routing gets smarter over time. Every time a task completes successfully, MoFlo's post-task hook records the outcome — the full task description, which agent handled it, and whether it succeeded. These learned patterns are combined with the built-in seeds on every future route call. Because learned patterns contain rich task descriptions (not just short keywords), they discriminate better as they accumulate.
Routing outcomes persist across sessions. You can inspect them with flo hooks patterns or transfer them between projects with flo hooks transfer.
Memory & Knowledge Storage
MoFlo uses a SQLite database (via Node 22's built-in node:sqlite — no native deps) to store three types of knowledge:
Semantic search uses cosine similarity on neural embeddings (MiniLM-L6-v2, 384 dimensions). When Claude searches memory, it gets the most relevant chunks ranked by semantic similarity — not keyword matching.
Session start indexing — Background indexers (guidance, code map, tests) run on every session start. They're incremental — unchanged files are skipped — and run in parallel so they don't block the session.
Cross-session persistence — Everything stored in the database survives across sessions. Patterns learned on Monday are available on Friday. The stop hook exports session metrics, and the session-restore hook loads prior state.
For Claude
When flo init runs, it appends a section to your CLAUDE.md that teaches Claude:
- Always search memory before Glob/Grep/Read (enforced by gates)
- Use
mcp__moflo__memory_searchfor knowledge retrieval - Use
/flo <issue>(or/fl) for issue execution - Store learnings after task completion
Full Configuration Reference
flo init generates a moflo.yaml at your project root. Here's the complete set of options:
project:
name: "my-project"
guidance:
directories: [.claude/guidance]
namespace: guidance
code_map:
directories: [src, packages]
extensions: [".ts", ".tsx"]
exclude: [node_modules, dist]
namespace: code-map
tests:
directories: [tests, __tests__]
patterns: ["*.test.*", "*.spec.*", "*.test-*"]
extensions: [".ts", ".tsx", ".js", ".jsx"]
exclude: [node_modules, coverage, dist]
namespace: tests
gates:
memory_first: true # Must search memory before file exploration
task_create_first: true # Must TaskCreate before Agent tool
task_status_gate: block # Open tasks block `gh pr create`; warn → report only; off → silent
context_tracking: true # Report measured context-window usage once per band crossing
# context_limit: 200k # Optional window size (200000 / 200k / 1m) to get a % instead of raw tokens
verify_before_done: true # On by default (#1294); /verify before `gh pr create` (unless --no-verify). false to disable
sdd:
default: false # true → every /flo run uses the spec→plan→implement→verify cycle unless --no-sdd
merge:
auto: false # true → every /flo run auto-merges its PR once preconditions pass, unless --no-merge
auto_index:
guidance: true # Auto-index docs on session start
code_map: true # Auto-index code on session start
tests: true # Auto-index test files on session start
auto_meditate:
enabled: true # Distill durable session lessons into the learnings namespace
mcp:
tool_defer: true # Defer MCP tool schemas (100+); loaded on demand via ToolSearch
auto_start: false # Auto-start MCP server on session begin
hooks:
pre_edit: true # Track file edits for learning
post_edit: true # Record edit outcomes
pre_task: true # Agent routing before task spawn
post_task: true # Record task results for learning
gate: true # Gate enforcement
route: true # Intelligent task routing
stop_hook: true # Session-end persistence
session_restore: true # Restore session state on start
models:
default: opus
research: sonnet
review: opus
test: sonnet
model_routing:
enabled: false # Set to true for automatic model selection
confidence_threshold: 0.85
cost_optimization: true
circuit_breaker: true
status_line:
enabled: true
branding: "MoFlo V4"
mode: compact # single-line, compact, or dashboard
show_dir: true # current directory name (compact/dashboard only)
show_git: true
show_session: true
show_swarm: true
show_mcp: true
Tool Deferral
By default, tool_defer is true. MoFlo exposes 100+ MCP tools — loading all their schemas at conversation start consumes significant context. With deferral enabled, only tool names are listed at startup (compact), and full schemas are fetched on demand via ToolSearch when actually needed. Hooks and CLI commands continue to work normally since they call the daemon directly, not through MCP tool schemas.
Set tool_defer: false if you want all tool schemas available immediately (useful for offline/air-gapped environments where ToolSearch may not work).
Model Routing
By default, MoFlo uses static model preferences — each agent role uses the model specified in models:. This is predictable and gives you full control.
Set model_routing.enabled: true to enable intelligent routing, which analyzes each task's complexity and auto-selects the cheapest capable model:
The router learns from outcomes — if a model fails a task, the circuit breaker penalizes it and escalates to a more capable model.
You can pin specific agents even when routing is enabled:
model_routing:
enabled: true
agent_overrides:
security-architect: opus # Never downgrade security work
researcher: sonnet # Pin research to sonnet
Architecture
- 9 bin entries shipped with npm:
flo(main CLI),moflo,claude-flow(aliases),flo-setup,flo-codemap,flo-search,flo-embeddings,flo-index,flo-testmap - Project config system:
moflo.yamlfor per-project settings - One-stop init:
flo initgenerates everything needed for OOTB operation
Background
MoFlo began as a fork of Claude Flow but is now an independent project. The two share some early roots and a few namespace conventions, but the codebases, runtime, and design priorities have fully diverged.
MoFlo narrows the focus to one scenario: day-to-day local coding with Claude Code on a single project. Instead of a broad, highly configurable orchestration framework, it bakes in sensible defaults, adds automatic indexing and memory gating at session start, and tunes the out-of-box experience so that npm install and flo init get you straight to coding. Over time it grew its own architecture — workspace collapse, in-tree fastembed runtime, node:sqlite + HNSW memory layer, spell engine, daemon-driven scheduling — and ships as a single npm package.
Contributing
Contributions are welcome — bug reports, documentation, tests, and code. See CONTRIBUTING.md for setup, conventions, and how to open a pull request. By participating, you agree to abide by our Code of Conduct.
License
MIT