feat(skills): add mermaid-diagrammer skill and request flow diagram

This commit is contained in:
Aishanee Shah
2026-04-14 22:27:59 +00:00
parent 8d05bdbe49
commit 2736c69580
5 changed files with 205 additions and 0 deletions
@@ -0,0 +1,36 @@
---
name: mermaid-diagrammer
description: Create, convert, and validate Mermaid diagrams. Use this skill when asked to generate visual diagrams (flowcharts, sequence diagrams, class diagrams, etc.) and export them to PNG images. Follows best practices for syntax robustness, accessibility, and professional styling.
---
# Mermaid Diagrammer
This skill enables the creation of professional Mermaid diagrams and their conversion to high-quality PNG images. It emphasizes robust syntax, accessibility, and maintainable styling.
## Workflow
### 1. Create Mermaid Diagram
Select the appropriate diagram type based on the task (see `references/mermaid_syntax.md`).
- **Syntax Guardrails:** Always use double quotes for labels containing special characters: `A["Label (with Parens)"]`.
- **Accessibility:** Include `accTitle` and `accDescr` for all diagrams.
- **Styling:** Use `classDef` and `subgraph` for complex diagrams to ensure readability.
- Save to a `.mmd` file.
### 2. Convert to PNG
Use the `scripts/convert.cjs` script.
- **Command:** `node <skill_path>/scripts/convert.cjs <input.mmd> <output.png>`
- If conversion fails, check the Mermaid CLI output for syntax errors (e.g., mismatched brackets or unquoted special characters).
### 3. Validate & Verify
Validate the PNG using `scripts/validate_png.cjs`.
- **Command:** `node <skill_path>/scripts/validate_png.cjs <output.png>`
- **Human Verification:** Inform the user when the PNG is ready and where it is located.
## Resources
### scripts/
- `convert.cjs`: Converts Mermaid to PNG via `mermaid-cli`.
- `validate_png.cjs`: PNG integrity check.
### references/
- `mermaid_syntax.md`: Comprehensive reference with best practices for AI-generated Mermaid code, accessibility, and theming.
@@ -0,0 +1,62 @@
# Mermaid Syntax & Best Practices
Use this reference as a template and guide for generating high-quality, robust Mermaid diagrams.
## Core Rules for AI Generation
- **Syntax Robustness:** Always wrap labels in double quotes if they contain special characters (parentheses, brackets, etc.) to prevent renderer crashes.
- *Correct:* `A["User (Admin)"]`
- *Incorrect:* `A[User (Admin)]`
- **Reserved Words:** Avoid using reserved words (e.g., `end`, `graph`, `subgraph`) as node IDs.
- **Accessibility:** Always include `accTitle` and `accDescr` for screen readers.
## Diagram Selection Guide
| Use Case | Recommended Type | Layout |
| :--- | :--- | :--- |
| **Logic/Algorithms** | `flowchart` | `TD` (Top-Down) |
| **Data Pipelines/Process** | `flowchart` | `LR` (Left-Right) |
| **API/Interactions** | `sequenceDiagram` | N/A |
| **Database Schema** | `erDiagram` | N/A |
| **State Machines** | `stateDiagram-v2` | N/A |
## Flowchart (Best Practices)
Use `classDef` for consistent styling instead of inline styles.
```mermaid
graph TD
accTitle: System Logic
accDescr: High-level logic for the authentication service.
classDef primary fill:#f9f,stroke:#333,stroke-width:2px;
classDef database fill:#f96,stroke:#333,stroke-width:2px;
Start --> Auth{{"Authorized?"}}
Auth -- Yes --> Process[Process Request]:::primary
Auth -- No --> DB[(Log Error)]:::database
```
## Sequence Diagram
Use `participant` aliases for cleaner code.
```mermaid
sequenceDiagram
accTitle: API Authentication
participant U as User
participant A as Auth Service
U->>A: Request Token
A-->>U: JWT Token
```
## Styling and Theming
Prefer logical grouping using `subgraph` to manage complexity.
```mermaid
graph LR
subgraph Client
A[Mobile]
B[Web]
end
subgraph Server
C[API]
end
Client --> Server
```
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env node
/**
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const { spawnSync } = require('child_process');
const path = require('path');
const fs = require('fs');
const args = process.argv.slice(2);
if (args.length < 2) {
console.error('Usage: node convert.cjs <input.mmd> <output.png>');
process.exit(1);
}
const inputPath = path.resolve(args[0]);
const outputPath = path.resolve(args[1]);
if (!fs.existsSync(inputPath)) {
console.error(`Error: Input file not found: ${inputPath}`);
process.exit(1);
}
console.log(`Converting ${inputPath} to ${outputPath}...`);
const result = spawnSync('npx', [
'--yes',
'@mermaid-js/mermaid-cli',
'-i', inputPath,
'-o', outputPath,
'-b', 'transparent'
], { stdio: 'pipe', encoding: 'utf-8' });
if (result.status !== 0) {
console.error('Failed to convert Mermaid diagram:');
console.error(result.stderr);
process.exit(1);
}
console.log('Successfully converted Mermaid diagram to PNG.');
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env node
/**
* Copyright 2026 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const fs = require('fs');
const path = require('path');
const args = process.argv.slice(2);
if (args.length < 1) {
console.error('Usage: node validate_png.cjs <path_to_png>');
process.exit(1);
}
const filePath = path.resolve(args[0]);
if (!fs.existsSync(filePath)) {
console.error(`Error: File not found: ${filePath}`);
process.exit(1);
}
const stats = fs.statSync(filePath);
if (stats.size === 0) {
console.error(`Error: File is empty: ${filePath}`);
process.exit(1);
}
const buffer = Buffer.alloc(8);
const fd = fs.openSync(filePath, 'r');
fs.readSync(fd, buffer, 0, 8, 0);
fs.closeSync(fd);
// PNG Magic Numbers: 89 50 4E 47 0D 0A 1A 0A
const pngHeader = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
if (!buffer.equals(pngHeader)) {
console.error(`Error: File is not a valid PNG: ${filePath}`);
process.exit(1);
}
console.log(`Success: ${filePath} is a valid PNG file (${stats.size} bytes).`);
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB