This document provides a complete example of using flow to manage a multi-step workflow.
Prerequisites
Before starting, ensure flow is installed and API keys are configured. For detailed instructions, see the Grove installation guide.
A summary of prerequisites:
grove install flow: Installs theflowbinary.grove setup: Configures API keys for either Gemini or Anthropic models.- A git repository to serve as the working project.
The workflow described uses models and features that are tested with Anthropic’s Claude and Google’s Gemini models. Support for other models like codex or opencode is experimental.
Example: Implementing a Feature with the Chef-Cook-Critic Recipe
This example demonstrates a full workflow lifecycle by creating and executing a plan to make a grilled cheese sandwich. It uses a built-in recipe called chef-cook-critic that defines a sequence of jobs with different roles (personas).
Step 1: Initialize a Plan
A plan is created using flow plan init. This command launches a terminal interface to configure the new plan. The following example creates a plan named grilled-cheese-sandwich based on the chef-cook-critic recipe, with an associated git worktree for isolation.
{
"src": "/docs/flow/asciicasts/01-plan-init.cast"
}./videos/01-plan-init.mp4
/Users/solom4/Code/grovetools/flow/docs/videos/01-plan-init.mp4
This creates a directory named grilled-cheese-sandwich/ containing a series of job files (.md) that form a dependency chain. The flow status command displays this chain in its terminal interface.
{
"src": "/docs/flow/asciicasts/01-plan-init-status.cast"
}Understanding Briefing Files (What Agents Receive)
Each job generates a briefing XML file that is sent to the LLM. This file contains:
- System instructions derived from a template.
- Context files gathered from the repository.
- The job’s prompt or the current state of a conversation.
The template field in a job’s frontmatter determines which system instructions are included in the briefing’s <system_instructions> tag. The agent reads this file to get its task.
Below is an example of a briefing file generated from a chef template:
<prompt>
<system_instructions>
when prompted with a food, write an amazing recipe for the cook to execute.
if a critic gives you feedback, write a new recipe version with the suggestions but act annoyed about it.
</system_instructions>
<conversation_note>
This is a multi-turn conversation. Focus on the turn marked status="awaiting_response" -
that is the message requiring your reply. The respond_as attribute indicates what persona
to use. Previous responses may have been generated by different prompts or personas;
interpret and continue through YOUR current system instructions.
</conversation_note>
<context>
<uploaded_context_file file="context" type="repository" importance="medium" description="Concatenated project/source code files from the current repository."/>
</context>
<conversation>
<turn role="user" status="awaiting_response">
Today's food is grilled-cheese-sandwich
Make sure to use gouda!
</turn>
</conversation>
</prompt>Step 2a: Run a Chat Job
A oneshot job can be converted to a chat job by changing the type field in its frontmatter. This allows for multi-turn conversations with the LLM. The flow run <file> command (or a text editor integration) executes the next turn in the chat.
{
"src": "/docs/flow/asciicasts/02a-chat-job.cast"
}The LLM’s response is appended to the markdown file. The conversation can be continued by adding more user text and re-running the command, or it can be marked as complete from the flow status interface.
<!-- grove: {"id": "1b3047"} -->
## LLM Response (2026-01-13 08:08:53)
Alright, a "grilled-cheese-sandwich," you say? And you *insist* on gouda. Fine. Prepare yourself for something beyond your wildest dairy-induced dreams. This isn't just a grilled cheese; it's an experience.
## The Elysian Gouda Grill
**Yields:** 1 sublime sandwich
**Prep time:** 5 minutes
**Cook time:** 8-10 minutes
...etc...Step 2b: Add a Dynamic Feedback Job
New jobs can be added to a running plan using the flow add command, which provides a terminal interface for defining the new job’s properties, such as its title, type, and dependencies.
{
"src": "/docs/flow/asciicasts/02b-add-job.cast"
}The flow status interface has a column visibility toggle (T) to customize the display. When a job is run, log output and token usage information are displayed.
{
"src": "/docs/flow/asciicasts/02b-add-job-run.cast"
}The token usage panel shows a breakdown of cached context (Cold), uncached context (Hot), and the user prompt, along with API response time and cost estimates.
{
"src": "/docs/flow/asciicasts/02b-add-job-tokens.cast"
}Step 3: Run an Interactive Agent
A headless_agent job runs autonomously. Changing its type to interactive_agent (using the Y key in the flow status TUI) will cause it to launch in an interactive tmux session.
{
"src": "/docs/flow/asciicasts/03-interactive-agent.cast"
}The agent’s log output streams into the flow status interface. The full transcript of the interactive session is preserved in the job’s markdown file after completion.
Step 4: Execute the Rest of the Plan
Multiple jobs can be selected in the status TUI and run in sequence by pressing r. The interface displays the progress through the dependency graph. The logs for any job, including headless_agent jobs, can be viewed in the detail pane.
{
"src": "/docs/flow/asciicasts/04-execute-plan.cast"
}The final output of a job is appended to its markdown file.
Step 5: Explore the Notebook Artifacts
All artifacts generated during a plan’s execution, including briefing files, logs, and agent transcripts, are stored in a .artifacts/ subdirectory within the plan’s directory. These artifacts can be browsed using the nb notebook TUI.
{
"src": "/docs/flow/asciicasts/05-notebook-artifacts.cast"
}The agent transcript is appended to the body of the corresponding job’s markdown file, providing a record of the agent’s actions.
Step 6: Commit and Merge Work
Changes made by agents within a git worktree can be viewed using gmux sz. The flow status TUI indicates if a worktree is “dirty” (has uncommitted changes) and will not allow it to be merged.
{
"src": "/docs/flow/asciicasts/06-commit-merge.cast"
}After committing changes, the worktree is “clean” and can be merged into the main branch by pressing M in the status TUI. The git log confirms the merge.
Step 7: Clean Up (Optional)
After a plan is complete and the work is merged, the flow finish command or the C-x keybinding in the status TUI can be used to clean up associated resources, such as deleting the git worktree and branch.
{
"src": "/docs/flow/asciicasts/07-cleanup.cast"
}What Just Happened
This example demonstrated a workflow that:
- Created a plan from a recipe with an isolated git worktree.
- Executed a sequence of seven jobs according to a dependency graph.
- Utilized multiple job types:
chatfor conversation,oneshotfor single LLM calls,headless_agentfor autonomous execution, andinteractive_agentfor user collaboration. - Preserved all generated artifacts, including briefings and transcripts, for auditing and debugging.
- Managed the lifecycle of the worktree from creation to merge and cleanup.
Key concepts demonstrated:
- Templates: Define agent personas and system instructions within briefing XML files.
- Dependencies: Control the execution order of jobs in a directed acyclic graph (DAG).
- TUI: Provides real-time visibility into job status, logs, and git state.
- Artifacts: All inputs and outputs are stored for reproducibility and review.
TEST
{
"src": "/docs/flow/asciicasts/test.cast"
}