| name | brokk-flow-graph |
| description | Use when asked to map, visualize, or understand how a codebase flows from entry points to outcomes - generates a Mermaid flowchart per entry point showing branches, calls, and terminal states |
brokk-flow-graph
Overview
Systematically locate every entry point in a codebase, trace its execution paths using ripgrep, and emit one Mermaid flowchart TD diagram per entry point showing branches, function calls, and terminal outcomes (return, error, exit).
Prerequisites
Check for ripgrep before starting:
rg --version 2>/dev/null || echo "MISSING"
If missing: pip install ripgrep or cargo install ripgrep or winget install BurntSushi.ripgrep (Windows). Offer to install before proceeding.
Step 1 — Detect Language(s)
rg --files | rg -o "\.[^.]+$" | sort | uniq -c | sort -rn | head -20
Note all significant languages — a polyglot repo needs language-specific entry point patterns applied to the right directories.
Step 2 — Find Entry Points
Run the patterns for each detected language:
| Language | Entry Point Patterns |
|---|
| Python | if __name__ == .?__main__, def main\(, @app.route, @router.(get|post|put|delete|patch), @click.command |
| JS/TS | app\.listen\(, server\.listen\(, app\.(get|post|put|delete|patch)\(, export default function, addEventListener\( |
| Java | public static void main\(String, @(Get|Post|Put|Delete|Request)Mapping |
| Go | func main\(\), http\.Handle(Func)?\( |
| Ruby | get ['"], post ['"], put ['"] (Sinatra/Rails routes) |
| PHP | check index.php and route files |
| C# | static (async )?Task Main\(, app\.Map(Get|Post|Put|Delete) |
| Rust | fn main\(\), #\[tokio::main\] |
rg -n "if __name__|def main\(|@app\.route|@router\.(get|post|put|delete)|@click\.command" --type py
List all found entry points. Each becomes one Mermaid diagram.
Step 3 — Trace Execution Per Entry Point
For each entry point, trace 3 levels deep:
- Read the entry function — note every function call, conditional branch, and terminal (return/raise/exit/throw)
- For each called function, use ripgrep to find its definition and read it
- Repeat one more level — 3 levels is enough for most legacy codebases; note if paths go deeper
rg -n "def <function_name>|function <function_name>|func <function_name>" --type <lang>
Track a node list and edge list as you read:
nodes: [A, B, C, D, E]
edges: [A→B, A→C, B→D, C→D, D→E(error), D→F(success)]
Mark terminal nodes:
[success] — normal return/response
[error] — exception/error response
[exit] — process exit
Step 4 — Emit Mermaid Diagram
One flowchart TD per entry point. Use subgraphs to group layers.
flowchart TD
A["POST /api/users\n(entry)"] --> B["validate_request()"]
B -->|invalid| E1["400 Bad Request\n[error]"]
B -->|valid| C["create_user()"]
C --> D["hash_password()"]
C --> F["send_welcome_email()"]
D --> G["db.save()"]
G -->|fail| E2["500 DB Error\n[error]"]
G -->|ok| H["201 Created\n[success]"]
F -->|fail| I["log warning\n[continue]"]
Naming rules:
- Node IDs: short alphanumeric, no spaces (
createUser, E1, DB1)
- Node labels: use quotes for spaces/special chars
- Edge labels: use
|condition| to name branches
- Keep diagrams to ~20 nodes max; split deeply nested paths into a linked sub-diagram
Step 5 — Output
For each entry point emit:
## Entry: <method> <path or function name>
**File:** `path/to/file.py:42`
```mermaid
flowchart TD
...
Notes:
- Any paths deeper than 3 levels (list them)
- Any unclear/dynamic dispatch that couldn't be traced
After all diagrams, emit a summary table:
| Entry Point | File | Terminal Outcomes | Depth |
|-------------|------|-------------------|-------|
| POST /api/users | routes/users.py:14 | 201, 400, 500 | 4 |
## Windows Notes
- Use `rg` (ripgrep) — works natively on Windows
- Path separators in output: `rg` returns OS-native paths; normalise with forward slashes in diagrams for readability
- Avoid `grep`, `find`, `wc` — use `rg --count` and `rg --files` instead
## Common Mistakes
| Mistake | Fix |
|---------|-----|
| One giant diagram for whole codebase | One diagram per entry point |
| Tracing only happy path | Always trace error branches |
| Ignoring async/callback flows | Mark async edges with `-.->` (dashed) |
| Node IDs with spaces/slashes | Use short alphanumeric IDs, put display name in label |
| Stopping at function name | Actually read the called function's body |