Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Convert Python, JavaScript, and TypeScript functions into Mermaid flowcharts
.claude/skills/brycewang-stanford-code-flow-visualizer/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 85% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 63% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 80% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 91% | 0% |
Convert Python, JavaScript, and TypeScript functions into Mermaid flowcharts by analyzing control flow structures. This skill helps researchers document and understand complex algorithmic logic, data processing pipelines, and experimental workflows embedded in code.
Research code often contains intricate control flow: nested conditionals for data filtering, loops over experimental conditions, error handling for API calls, and branching logic for different analysis paths. Understanding this flow is critical for reproducibility, code review, and documentation, yet reading nested code can be cognitively demanding.
This skill translates source code into visual Mermaid flowcharts by parsing control flow structures (if/else, for/while loops, try/catch, match/switch, return statements) and mapping them to flowchart nodes and edges. The resulting diagrams serve as documentation supplements in README files, lab notebooks, and paper appendices.
The approach works by performing a lightweight static analysis of the code's abstract syntax tree (AST). Each control structure maps to a specific flowchart pattern: conditionals become diamond decision nodes, loops become cycles with back-edges, function calls become subroutine nodes, and return statements become terminal nodes.
| Code Structure | Flowchart Element | Mermaid Shape | |---------------|-------------------|---------------| | Function entry | Start node | ([Function Name]) | | Assignment / expression | Process node | [statement] | | if / else if | Decision diamond | {condition?} | | for / while loop | Decision + back-edge | {loop condition?} with cycle | | try / catch | Process + error path | [try block] with dashed error edge | | return / yield | Terminal / output node | ([return value]) | | Function call | Subroutine node | [[function_name()]] | | match / switch | Multi-branch decision | {value?} with labeled edges |
Input code:
pythondef process_papers(papers, min_citations=10): results = [] for paper in papers: if paper.year < 2015: continue if paper.citation_count < min_citations: continue try: abstract = fetch_abstract(paper.doi) embeddings = compute_embeddings(abstract) results.append({"paper": paper, "embedding": embeddings}) except APIError: log_error(paper.doi) return results
Output flowchart:
mermaidflowchart TD Start(["process_papers(papers, min_citations=10)"]) --> Init["results = [ ]"] Init --> Loop{"For each paper in papers?"} Loop -->|Done| Return(["Return results"]) Loop -->|Next paper| YearCheck{"paper.year < 2015?"} YearCheck -->|Yes| Loop YearCheck -->|No| CitCheck{"citation_count < min_citations?"} CitCheck -->|Yes| Loop CitCheck -->|No| TryBlock["abstract = fetch_abstract(paper.doi)"] TryBlock --> Embed["embeddings = compute_embeddings(abstract)"] Embed --> Append["results.append(...)"] Append --> Loop TryBlock -.->|APIError| LogErr["log_error(paper.doi)"] LogErr --> Loop
Input code:
typescriptasync function searchPapers(query: string, maxResults: number = 50): Promise<Paper[]> { const cached = await cache.get(query); if (cached) return cached; const results: Paper[] = []; let offset = 0; while (results.length < maxResults) { const batch = await api.search(query, offset, 10); if (batch.length === 0) break; for (const paper of batch) { if (paper.isRetracted) continue; results.push(paper); } offset += 10; } await cache.set(query, results); return results; }
Output flowchart:
mermaidflowchart TD Start(["searchPapers(query, maxResults=50)"]) --> Cache["cached = await cache.get(query)"] Cache --> CacheHit{"cached exists?"} CacheHit -->|Yes| ReturnCached(["Return cached"]) CacheHit -->|No| InitResults["results = [ ], offset = 0"] InitResults --> WhileLoop{"results.length < maxResults?"} WhileLoop -->|No| SaveCache["await cache.set(query, results)"] WhileLoop -->|Yes| Fetch["batch = await api.search(query, offset, 10)"] Fetch --> EmptyCheck{"batch.length === 0?"} EmptyCheck -->|Yes| SaveCache EmptyCheck -->|No| ForLoop{"For each paper in batch?"} ForLoop -->|Done| IncOffset["offset += 10"] IncOffset --> WhileLoop ForLoop -->|Next| Retracted{"paper.isRetracted?"} Retracted -->|Yes| ForLoop Retracted -->|No| Push["results.push(paper)"] Push --> ForLoop SaveCache --> Return(["Return results"])
Deeply nested if/else chains are flattened into a decision tree. Each branch is labeled with its condition, and nodes at the same depth are arranged vertically for readability.
Recursive calls are shown as subroutine nodes with a self-referencing edge back to the function start node. A note annotation indicates the recursion base case.
Python generators use yield as intermediate output nodes (shown as parallelogram shapes). The flowchart shows the suspension point and resumption path.
Multiple except clauses create parallel error paths from the try block, each labeled with the exception type. finally blocks are shown as a converging node that all paths pass through.
mermaid%%{init: { 'theme': 'base', 'themeVariables': { 'primaryColor': '#f8f9fa', 'primaryBorderColor': '#212529', 'primaryTextColor': '#212529', 'lineColor': '#495057', 'fontFamily': 'Times New Roman, serif', 'fontSize': '14px' } }}%% flowchart TD A["Step 1"] --> B{"Decision"} --> C["Step 2"]
bash# Render Mermaid to PDF for LaTeX inclusion mmdc -i flowchart.mmd -o flowchart.pdf -t neutral -b transparent
latex\begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{flowchart.pdf} \caption{Control flow of the data processing pipeline.} \label{fig:flowchart} \end{figure}
Promise.all) are noted but not fully modeled.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 16,712 | 23,438 | +40% | 1 | 1 | 0% | 2,843 | 5,272 | +85% | 0 | 0 | — |
case-02 | fail→pass | 12,951 | 9,804 | -24% | 1 | 1 | 0% | 2,341 | 3,807 | +63% | 0 | 0 | — |
case-03 | fail→pass | 10,575 | 8,410 | -20% | 1 | 1 | 0% | 1,992 | 3,241 | +63% | 0 | 0 | — |
case-04 | fail→pass | 12,483 | 12,660 | +1% | 1 | 1 | 0% | 2,148 | 3,857 | +80% | 0 | 0 | — |
case-05 | fail→pass | 12,265 | 9,019 | -26% | 1 | 1 | 0% | 1,813 | 3,469 | +91% | 0 | 0 | — |
case-06 | pass→pass | 13,894 | 8,314 | -40% | 1 | 1 | 0% | 2,112 | 3,049 | +44% | 0 | 0 | — |
case-07 | pass→pass | 11,409 | 5,570 | -51% | 1 | 1 | 0% | 1,800 | 2,919 | +62% | 0 | 0 | — |
case-08 | pass→pass | 15,338 | 14,469 | -6% | 1 | 1 | 0% | 2,277 | 4,281 | +88% | 0 | 0 | — |
case-09 | fail→pass | 12,566 | 13,049 | +4% | 1 | 1 | 0% | 2,148 | 3,967 | +85% | 0 | 0 | — |
case-10 | pass→pass | 12,029 | 11,705 | -3% | 1 | 1 | 0% | 2,013 | 3,803 | +89% | 0 | 0 | — |
case-11 | fail→pass | 12,834 | 12,738 | -1% | 1 | 1 | 0% | 2,093 | 4,092 | +96% | 0 | 0 | — |
case-12 | pass→pass | 15,730 | 14,826 | -6% | 1 | 1 | 0% | 2,073 | 4,154 | +100% | 0 | 0 | — |
case-13 | pass→pass | 6,969 | 3,487 | -50% | 1 | 1 | 0% | 1,072 | 2,345 | +119% | 0 | 0 | — |
case-14 | pass→pass | 11,953 | 10,569 | -12% | 1 | 1 | 0% | 1,991 | 3,735 | +88% | 0 | 0 | — |
case-15 | fail→pass | 11,549 | 10,641 | -8% | 1 | 1 | 0% | 1,955 | 3,734 | +91% | 0 | 0 | — |
case-16 | fail→pass | 15,662 | 9,724 | -38% | 1 | 1 | 0% | 2,207 | 3,583 | +62% | 0 | 0 | — |
case-17 | pass→pass | 15,567 | 16,596 | +7% | 1 | 1 | 0% | 2,568 | 4,558 | +77% | 0 | 0 | — |
case-18 | pass→pass | 6,441 | 3,397 | -47% | 1 | 1 | 0% | 923 | 2,319 | +151% | 0 | 0 | — |
case-19 | pass→pass | 10,024 | 8,252 | -18% | 1 | 1 | 0% | 1,422 | 3,399 | +139% | 0 | 0 | — |
case-20 | fail→pass | 13,287 | 10,419 | -22% | 1 | 1 | 0% | 1,993 | 3,698 | +86% | 0 | 0 | — |
case-21 | fail→pass | 16,364 | 18,112 | +11% | 1 | 1 | 0% | 3,174 | 4,649 | +46% | 0 | 0 | — |
case-22 | fail→fail | 14,500 | 14,440 | -0% | 1 | 1 | 0% | 2,338 | 4,462 | +91% | 0 | 0 | — |
case-23 | fail→fail | 13,309 | 10,664 | -20% | 1 | 1 | 0% | 2,273 | 3,440 | +51% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +48 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.