Agent-almanac generate-workflow-diagram
git clone https://github.com/pjt222/agent-almanac
T=$(mktemp -d) && git clone --depth=1 https://github.com/pjt222/agent-almanac "$T" && mkdir -p ~/.claude/skills && cp -r "$T/i18n/wenyan/skills/generate-workflow-diagram" ~/.claude/skills/pjt222-agent-almanac-generate-workflow-diagram-9560b4 && rm -rf "$T"
i18n/wenyan/skills/generate-workflow-diagram/SKILL.mdGenerate Workflow Diagram
Generate a themed Mermaid flowchart diagram from putior workflow data and embed it in documentation.
When to Use
- After annotating source files and ready to produce the visual diagram
- Regenerating a diagram after workflow changes
- Switching themes or output formats for different audiences
- Embedding workflow diagrams in README, Quarto, or R Markdown documents
Inputs
- Required: Workflow data from
,put()
, orput_auto()put_merge() - Optional: Theme name (default:
; options: light, dark, auto, minimal, github, viridis, magma, plasma, cividis)"light" - Optional: Output target: console, file path, clipboard, or raw string
- Optional: Interactive features:
,show_source_infoenable_clicks
Procedure
Step 1: Extract Workflow Data
Obtain workflow data from one of three sources.
library(putior) # From manual annotations workflow <- put("./src/") # From manual annotations, excluding specific files workflow <- put("./src/", exclude = c("build-workflow\\.R$", "test_")) # From auto-detection only workflow <- put_auto("./src/") # From merged (manual + auto) workflow <- put_merge("./src/", merge_strategy = "supplement")
The workflow data frame may include a
node_type column from annotations. Node types control Mermaid shapes:
| Mermaid Shape | Use Case |
|---|---|---|
| Stadium | Data sources, configuration files |
| Subroutine | Generated artifacts, reports |
| Rectangle | Processing steps (default) |
| Diamond | Conditional logic, branching |
/ | Stadium | Entry/terminal nodes |
Each
node_type also receives a corresponding CSS class (e.g., class nodeId input;) for theme-based styling.
Expected: A data frame with at least one row, containing
id, label, and optionally input, output, source_file, node_type columns.
On failure: If the data frame is empty, no annotations or patterns were found. Run
analyze-codebase-workflow first, or check that annotations are syntactically valid with put("./src/", validate = TRUE).
Step 2: Select Theme and Options
Choose a theme appropriate for the target audience.
# List all available themes get_diagram_themes() # Standard themes # "light" — Default, bright colors # "dark" — For dark mode environments # "auto" — GitHub-adaptive with solid colors # "minimal" — Grayscale, print-friendly # "github" — Optimized for GitHub README files # Colorblind-safe themes (viridis family) # "viridis" — Purple→Blue→Green→Yellow, general accessibility # "magma" — Purple→Red→Yellow, high contrast for print # "plasma" — Purple→Pink→Orange→Yellow, presentations # "cividis" — Blue→Gray→Yellow, maximum accessibility (no red-green)
Additional parameters:
: Diagram flow direction —direction
(top-down, default),"TD"
(left-right),"LR"
,"RL""BT"
:show_artifacts
/TRUE
— show artifact nodes (files, data); can be noisy for large workflows (e.g., 16+ extra nodes)FALSE
:show_workflow_boundaries
/TRUE
— wrap each source file's nodes in a Mermaid subgraphFALSE
: How source file info is displayed on nodes (e.g., as subtitle)source_info_style
: Format for node label textnode_labels
Expected: Theme names printed. Select one based on context.
On failure: If a theme name is not recognized,
put_diagram() falls back to "light". Check spelling.
Step 3: Custom Palette with put_theme()
(Optional)
put_theme()If the 9 built-in themes don't match your project's palette, create a custom theme with
put_theme().
# Create custom palette — unspecified types inherit from base theme cyberpunk <- put_theme( base = "dark", input = c(fill = "#1a1a2e", stroke = "#00ff88", color = "#00ff88"), process = c(fill = "#16213e", stroke = "#44ddff", color = "#44ddff"), output = c(fill = "#0f3460", stroke = "#ff3366", color = "#ff3366"), decision = c(fill = "#1a1a2e", stroke = "#ffaa33", color = "#ffaa33") ) # Use the palette parameter (overrides theme when provided) mermaid_content <- put_diagram(workflow, palette = cyberpunk, output = "raw") writeLines(mermaid_content, "workflow.mmd")
put_theme() accepts input, process, output, decision, artifact, start, and end node types. Each takes a named vector c(fill = "#hex", stroke = "#hex", color = "#hex"). Unset types inherit from the base theme.
Expected: Mermaid output with your custom classDef lines. Node shapes from
node_type are preserved; only colors change. All node types use stroke-width:2px — override not currently supported via put_theme().
On failure: If the palette object is not a
putior_theme class, put_diagram() raises a descriptive error. Ensure you pass the return value of put_theme(), not a raw list.
Fallback — manual classDef replacement: For fine-grained control beyond what
put_theme() offers (e.g., per-type stroke widths), generate with a base theme and replace classDef lines manually:
mermaid_content <- put_diagram(workflow, theme = "dark", output = "raw") lines <- strsplit(mermaid_content, "\n")[[1]] lines <- lines[!grepl("^\\s*classDef ", lines)] custom_defs <- c(" classDef input fill:#1a1a2e,stroke:#00ff88,stroke-width:3px,color:#00ff88") mermaid_content <- paste(c(lines, custom_defs), collapse = "\n")
Step 4: Generate Mermaid Output
Produce the diagram in the desired output mode.
# Print to console (default) cat(put_diagram(workflow, theme = "github")) # Save to file writeLines(put_diagram(workflow, theme = "github"), "docs/workflow.md") # Get raw string for embedding mermaid_code <- put_diagram(workflow, output = "raw", theme = "github") # With source file info (shows which file each node comes from) cat(put_diagram(workflow, theme = "github", show_source_info = TRUE)) # With clickable nodes (for VS Code, RStudio, or file:// protocol) cat(put_diagram(workflow, theme = "github", enable_clicks = TRUE, click_protocol = "vscode" # or "rstudio", "file" )) # Full-featured cat(put_diagram(workflow, theme = "viridis", show_source_info = TRUE, enable_clicks = TRUE, click_protocol = "vscode" ))
Expected: Valid Mermaid code starting with
flowchart TD (or LR depending on direction). Nodes are connected by arrows showing data flow.
On failure: If the output is
flowchart TD with no nodes, the workflow data frame is empty. If connections are missing, check that output filenames match input filenames across nodes.
Step 5: Embed in Target Document
Insert the diagram into the appropriate documentation format.
GitHub README (```mermaid code fence):
## Workflow ```mermaid flowchart TD A["Extract Data"] --> B["Transform"] B --> C["Load"] ```
Quarto document (native mermaid chunk via knit_child):
# Chunk 1: Generate code (visible, foldable) workflow <- put("./src/") mermaid_code <- put_diagram(workflow, output = "raw", theme = "github")
# Chunk 2: Output as native mermaid chunk (hidden) #| output: asis #| echo: false mermaid_chunk <- paste0("```{mermaid}\n", mermaid_code, "\n```") cat(knitr::knit_child(text = mermaid_chunk, quiet = TRUE))
R Markdown (with mermaid.js CDN or DiagrammeR):
DiagrammeR::mermaid(put_diagram(workflow, output = "raw"))
Expected: Diagram renders correctly in the target format. GitHub renders mermaid code fences natively.
On failure: If GitHub doesn't render the diagram, ensure the code fence uses exactly
```mermaid (no extra attributes). For Quarto, ensure the knit_child() approach is used since direct variable interpolation in {mermaid} chunks is not supported.
Validation
-
produces valid Mermaid code (starts withput_diagram()
)flowchart - All expected nodes appear in the diagram
- Data flow connections (arrows) are present between connected nodes
- Selected theme is applied (check init block in output for theme-specific colors)
- Diagram renders correctly in the target format (GitHub, Quarto, etc.)
Common Pitfalls
- Empty diagrams: Usually means
returned no rows. Check annotations exist and are syntactically valid.put() - All nodes disconnected: Output filenames must exactly match input filenames (including extension) for putior to draw connections.
anddata.csv
are different.Data.csv - Theme not visible on GitHub: GitHub's mermaid renderer has limited theme support. The
theme is specifically designed for GitHub rendering. The"github"
theme block may be ignored by some renderers.%%{init:...}%% - Quarto mermaid variable interpolation: Quarto's
chunks don't support R variables directly. Use the{mermaid}
technique described in Step 5.knit_child() - Clickable nodes not working: Click directives require a renderer that supports Mermaid interaction events. GitHub's static renderer does not support clicks. Use a local Mermaid renderer or the putior Shiny sandbox.
- Self-referential meta-pipeline files: Scanning a directory that includes the build script generating the diagram causes duplicate subgraph IDs and Mermaid errors. Use the
parameter to skip them at scan time:excludeworkflow <- put("./src/", exclude = c("build-workflow\\.R$", "build-workflow\\.js$"))
too noisy: Large projects may generate many artifact nodes (10–20+), cluttering the diagram. Useshow_artifacts = TRUE
and rely onshow_artifacts = FALSE
annotations to mark key inputs/outputs explicitly.node_type
Related Skills
— prerequisite: files must be annotated before diagram generationannotate-source-files
— auto-detection can supplement manual annotationsanalyze-codebase-workflow
— automate diagram regeneration in CI/CDsetup-putior-ci
— embed diagrams in Quarto reportscreate-quarto-report
— embed diagrams in pkgdown documentation sitesbuild-pkgdown-site