diff --git a/docs/diagrams/.gitignore b/docs/diagrams/.gitignore new file mode 100644 index 00000000..1876a153 --- /dev/null +++ b/docs/diagrams/.gitignore @@ -0,0 +1,3 @@ +*.png +*.jpg +*.svg diff --git a/docs/diagrams/README.md b/docs/diagrams/README.md new file mode 100644 index 00000000..6abc38b9 --- /dev/null +++ b/docs/diagrams/README.md @@ -0,0 +1,257 @@ +# BMM Workflow Diagram + +This directory contains the BMM (BMad Method) workflow diagram and tools for generating it. + +## Files + +| File | Description | +| ---------------------------------- | --------------------------------------------------- | +| `workflow-manifest.yaml` | Workflow structure manifest (source of truth) | +| `generate-manifest.md` | Agentic prompt to generate/update manifest | +| `bmm-workflow.d2` | D2 source diagram | +| `bmm-workflow.svg` | Vector output (74KB) | +| `bmm-workflow.png` | Standard PNG (1600×1502, 257KB) | +| `bmm-workflow-print.png` | High-res for Nano-Banana input (4000×3755, 732KB) | +| `bmm-workflow-vintage.jpg` | Print-ready vintage version (2144×1984, 1.1MB) | +| `bmm-workflow-vintage-web.jpg` | Web-optimized vintage (1400×1296, 281KB) | +| `generate-bmm-workflow-diagram.md` | Generation prompt for Claude | +| `gracefully-age.prompt.md` | Nano-Banana Pro prompt for vintage treatment | +| `post-process-svg.py` | SVG post-processing (labels, title, legend, footer) | +| `red-herring.png` | Fish stamp asset | +| `fonts/` | ShareTechMono font files | + +## Workflow Manifest System + +The workflow manifest (`workflow-manifest.yaml`) is the **source of truth** for BMM workflow structure. It contains: + +- All workflows organized by phase +- Workflow connections and dependencies +- Decision points (e.g., "Has UI?") +- Feedback loops (e.g., code review → dev) +- Cross-phase connections +- Output file patterns + +### Generating/Updating the Manifest + +Use the `generate-manifest.md` agentic prompt to create or update the manifest: + +1. Feed `generate-manifest.md` to an agentic LLM (Claude, Gemini, etc.) +2. The agent will: + - Scan `src/modules/bmm/workflows/` for all workflows + - Extract workflow names, descriptions, and outputs from `workflow.yaml` files + - Build the manifest with all connections and dependencies + - Compare with existing manifest (if present) + - **HARD STOP** if Quick Flow changes detected + - Prompt for approval if main workflow changes detected + - Write updated manifest to `workflow-manifest.yaml` + +### When to Regenerate + +Regenerate the manifest when: + +- Adding new workflows +- Removing workflows +- Changing workflow outputs +- Changing workflow connections or dependencies +- Updating Quick Flow workflows (requires careful review) + +### Change Detection + +The manifest system includes intelligent change detection: + +- **Quick Flow changes**: HARD STOP - these are critical paths +- **Main workflow changes**: User approval required +- **No changes**: Proceeds silently + +## Generation Pipeline + +### Step 1: Generate Base Diagram + +Run the generation prompt with Claude: + +```bash +# Claude will read generate-bmm-workflow-diagram.md and: +# 1. Analyze BMM workflow structure +# 2. Generate/update bmm-workflow.d2 +# 3. Run d2 to create SVG +# 4. Post-process SVG +# 5. Convert to PNG +``` + +Or manually: + +```bash +# Generate SVG from D2 +d2 --font-regular=fonts/ShareTechMono-Regular.ttf \ + --font-bold=fonts/ShareTechMono-Regular.ttf \ + bmm-workflow.d2 bmm-workflow-technical.svg + +# Post-process (shrink labels, outline title, add legend/footer/stamp) +python3 post-process-svg.py + +# Convert to standard PNG +rsvg-convert bmm-workflow.svg -w 1600 -o bmm-workflow.png + +# Convert to high-res PNG for Nano-Banana +rsvg-convert bmm-workflow.svg -w 4000 -o bmm-workflow-print.png + +# Clean up +rm bmm-workflow-technical.svg +``` + +### Step 2: Vintage Treatment with Nano-Banana Pro + +1. Go to [Nano-Banana Pro](https://nanobanana.org/) or use via Pixlr/Recraft + +2. Upload `bmm-workflow-print.png` (the 4000px version) + +3. Use the prompt from `gracefully-age.prompt.md`: + - Applies aged paper texture, fold creases, coffee stains + - Adds ink bleed and printing artifacts + - Preserves all text, boxes, and arrows exactly + - Does NOT apply sepia/fading (original colors are already vintage-toned) + +4. Download the result (will be named something like `Gemini_Generated_Image_*.png`) + +### Step 3: Remove the Watermark + +Nano-Banana Pro adds a 4-pointed star watermark in the lower-right corner. Remove it: + +```bash +# Set input file (adjust filename as needed) +INPUT=~/Downloads/Gemini_Generated_Image_XXXXX.png + +# Find the watermark location (it's near the fish, bottom-right) +# The watermark is approximately at position (1950-2060, 1790-1900) + +# Remove watermark by patching with nearby paper texture +magick "$INPUT" \ + \( -clone 0 -crop 120x120+1950+1680 +repage \ + \( -size 120x120 xc:black -fill white -draw "circle 60,60 60,5" -blur 0x12 \) \ + -alpha off -compose CopyOpacity -composite \) \ + -geometry +1950+1795 -compose over -composite \ + bmm-workflow-vintage-clean.png +``` + +**How this works:** + +- Crops a 120×120 patch of clean paper texture from above the watermark (at +1950+1680) +- Creates a circular feathered mask to blend edges +- Composites the patch over the watermark location (+1950+1795) + +**Verify the fix:** + +```bash +# Crop the corner to check +magick bmm-workflow-vintage-clean.png -crop 600x600+1544+1384 /tmp/check.png +open /tmp/check.png # or use any image viewer +``` + +The fish should be intact, watermark gone, no visible patch edges. + +### Step 4: Fix the Legend + +Nano-Banana garbles the small text in the legend. Fix by: + +1. Covering the garbled text with vintage paper texture +2. Applying clean text with darken blend (preserves texture, shows text) + +```bash +# Extract legend content from original (without outer borders) +magick bmm-workflow-print.png -crop 1600x450+1950+250 /tmp/legend-orig.png +magick /tmp/legend-orig.png -shave 25x25 /tmp/legend-content.png + +# Scale to match Nano-Banana output +magick /tmp/legend-content.png -resize 831x211! /tmp/legend-content-scaled.png + +# Sample clean paper texture (find an empty area - e.g., right of title) +magick bmm-workflow-vintage-clean.png -crop 100x100+900+120 /tmp/texture-patch.png + +# Tile texture to cover legend area +magick /tmp/texture-patch.png -write mpr:tile +delete \ + -size 850x220 tile:mpr:tile /tmp/texture-tiled.png + +# Cover garbled legend with tiled texture +magick bmm-workflow-vintage-clean.png \ + /tmp/texture-tiled.png -geometry +1055+143 -composite \ + /tmp/vintage-erased.png + +# Apply clean text with darken blend (white becomes transparent) +magick /tmp/vintage-erased.png \ + /tmp/legend-content-scaled.png \ + -geometry +1059+147 -compose darken -composite \ + bmm-workflow-vintage-fixed.png +``` + +**Verify:** + +```bash +magick bmm-workflow-vintage-fixed.png -crop 700x350+900+80 /tmp/legend-check.png +open /tmp/legend-check.png +``` + +The legend should have clean text on vintage paper texture, with box borders preserved. + +### Step 5: Create Final Versions + +```bash +# Print version (JPEG, 92% quality) +magick bmm-workflow-vintage-fixed.png \ + -quality 92 \ + bmm-workflow-vintage.jpg + +# Web version (1400px wide, 85% quality) +magick bmm-workflow-vintage-fixed.png \ + -resize 1400x \ + -quality 85 \ + bmm-workflow-vintage-web.jpg + +# Clean up +rm bmm-workflow-vintage-clean.png bmm-workflow-vintage-fixed.png +``` + +**File sizes:** + +- Print: ~1.1MB (2144×1984 at 92% JPEG) +- Web: ~280KB (1400×1296 at 85% JPEG) + +## Troubleshooting + +### Watermark in wrong position + +The watermark location varies slightly between Nano-Banana runs. To find it: + +```bash +# Create a corner crop to locate the watermark +magick input.png -crop 600x600+1544+1384 /tmp/corner.png +open /tmp/corner.png +``` + +Look for the 4-pointed star shape near the fish. Adjust the patch coordinates accordingly. + +### Patch is visible + +If the patched area looks different from surroundings: + +- Sample texture from a different location (try areas with similar color/texture) +- Increase blur radius for softer blending +- Use a smaller patch size + +### Colors too dark/faded after Nano-Banana + +The prompt in `gracefully-age.prompt.md` explicitly tells Nano-Banana NOT to apply sepia/fading since our original colors are already vintage-toned. If results are too dark, emphasize this more in the prompt. + +### Legend position is off + +The legend position depends on the Nano-Banana output dimensions. If dimensions differ from 2144×1984: + +1. Calculate new scale factors: `new_width/4000` and `new_height/3755` +2. Adjust crop position: `1950 * width_scale`, `250 * height_scale` +3. Adjust legend size: `1600 * width_scale`, `450 * height_scale` + +## Dependencies + +- [D2](https://d2lang.com/) - Diagram scripting language +- [rsvg-convert](https://wiki.gnome.org/Projects/LibRsvg) - SVG to PNG conversion +- [ImageMagick](https://imagemagick.org/) (magick command) - Image manipulation +- Python 3 - For post-processing scripts diff --git a/docs/diagrams/bmm-workflow.d2 b/docs/diagrams/bmm-workflow.d2 new file mode 100644 index 00000000..f319b1d5 --- /dev/null +++ b/docs/diagrams/bmm-workflow.d2 @@ -0,0 +1,308 @@ +direction: down + +# Top-level vertical layout +grid-rows: 4 +grid-columns: 1 +grid-gap: 20 + +# Title row - left aligned via grid +title-row: "" { + style.fill: transparent + style.stroke: transparent + grid-rows: 1 + grid-columns: 1 + horizontal-gap: 0 + + title: "BMAD METHOD V6.0.0-ALPHA.12" { + style.fill: transparent + style.stroke: transparent + style.font-size: 48 + style.bold: true + style.font-color: "#1a3a5c" + label.near: top-left + } +} + +# Legend - positioned near title-row (handled by inject-legend.py post-processor) + + +vars: { + d2-config: { + layout-engine: elk + } +} + +classes: { + phase1-box: { + style: { + fill: "#e8f4f8" + stroke: "#2d7d9a" + stroke-width: 3 + border-radius: 12 + font-size: 27 + bold: true + font-color: "#1a5568" + } + } + phase2-box: { + style: { + fill: "#f0e8f8" + stroke: "#7d2d9a" + stroke-width: 3 + border-radius: 12 + font-size: 27 + bold: true + font-color: "#4a1a68" + } + } + phase3-box: { + style: { + fill: "#f8f0e8" + stroke: "#9a7d2d" + stroke-width: 3 + border-radius: 12 + font-size: 27 + bold: true + font-color: "#685a1a" + } + } + phase4-box: { + style: { + fill: "#e8f8f0" + stroke: "#2d9a7d" + stroke-width: 3 + border-radius: 12 + font-size: 27 + bold: true + font-color: "#1a684a" + } + } + entry: { + style: { + fill: "#333" + stroke: "#111" + stroke-width: 2 + border-radius: 8 + font-size: 27 + font-color: "#fff" + bold: true + } + } + n1: { + style: { + fill: "#fff" + stroke: "#2d7d9a" + stroke-width: 2 + border-radius: 4 + font-size: 27 + } + } + n2: { + style: { + fill: "#fff" + stroke: "#7d2d9a" + stroke-width: 2 + border-radius: 4 + font-size: 27 + } + } + n3: { + style: { + fill: "#fff" + stroke: "#9a7d2d" + stroke-width: 2 + border-radius: 4 + font-size: 27 + } + } + n4: { + style: { + fill: "#fff" + stroke: "#2d9a7d" + stroke-width: 2 + border-radius: 4 + font-size: 27 + } + } + decision: { + shape: diamond + style: { + fill: "#fff8e8" + stroke: "#7d2d9a" + stroke-width: 2 + font-size: 27 + } + } + opt: { + style: { + fill: "#f8f8f8" + stroke: "#888" + stroke-width: 2 + stroke-dash: 5 + border-radius: 4 + font-size: 27 + } + } +} + +# Entry point row - positioned above border between Phase 1 and 2 +init-row: "" { + style.fill: transparent + style.stroke: transparent + + grid-rows: 1 + grid-columns: 4 + grid-gap: 25 + + spacer-left: "" { style.opacity: 0 } + init: "/workflow-init\n@bmm-workflow-status.yaml" { class: n1 } + spacer-right1: "" { style.opacity: 0 } + spacer-right2: "" { style.opacity: 0 } +} + +# Lanes container (horizontal) - wider gaps for A4 landscape ratio +lanes: "" { + style.fill: transparent + style.stroke: transparent + + grid-rows: 1 + grid-columns: 4 + grid-gap: 90 + + # PHASE 1: DISCOVERY - activities in any order, ending with Product Brief + phase1: "PHASE 1: DISCOVERY\n " { + class: phase1-box + style.stroke-dash: 5 + width: 400 + + # Group of parallel/unordered activities - stacked vertically + activities: "Activities (any order)" { + style.fill: "transparent" + style.stroke: "#2d7d9a" + style.stroke-dash: 3 + style.font-size: 26 + style.font-color: "#666" + style.italic: true + style.border-radius: 8 + + grid-rows: 4 + grid-columns: 1 + grid-gap: 6 + + brain: "/brainstorm" { class: n1 } + research: "/research" { class: n1 } + domain: "/domain-research" { class: n1 } + doc: "/document-project" { class: n1 } + } + + brief: "/product-brief\n@product-brief.md" { class: n1 } + + activities -> brief + } + + # PHASE 2: PLANNING - no internal grid + phase2: "PHASE 2: PLANNING\n " { + class: phase2-box + width: 350 + + tech: "/tech-spec\n@tech-spec.md" { class: opt } + prd: "/prd\n@PRD.md" { class: n2 } + hasui: "Has UI?" { class: decision } + ux: "/ux-design\n@ux-design.md" { class: n2 } + + # Force Tech Spec above PRD + tech -> prd: { style.opacity: 0 } + prd -> hasui + hasui -> ux: Yes + } + + # PHASE 3: SOLUTIONING - no internal grid + phase3: "PHASE 3: SOLUTIONING\n " { + class: phase3-box + width: 400 + + # Invisible spacer to push content down + spacer: "" { + style.opacity: 0 + height: 60 + } + arch: "/architecture\n@architecture.md" { class: n3 } + epics: "/create-epics-and-stories\n@epics.md" { class: n3 } + impl: "/implementation-readiness\n@impl-readiness-report.md" { class: n3 } + + spacer -> arch: { style.opacity: 0 } + arch -> epics + epics -> impl + } + + # PHASE 4: IMPLEMENTATION - no internal grid, let loops show + phase4: "PHASE 4: IMPLEMENTATION\n " { + class: phase4-box + width: 520 + + sprint: "/sprint-planning\n@sprint-status.yaml" { class: n4 } + create: "/create-story\n@{epic}-{story}-*.md" { class: n4 } + dev: "/dev-story" { class: n4 } + review: "/code-review" { class: n4 } + done: "/story-done" { class: n4 } + retro: "/retrospective" { class: n4 } + + # Standalone utility - not connected to main flow, forced to bottom + course-container: "" { + style.fill: transparent + style.stroke: transparent + grid-rows: 2 + grid-columns: 1 + grid-gap: 4 + + course: "/correct-course\n@sprint-change-proposal.md" { class: n4 } + course-label: "(run when issues arise)" { + style.fill: transparent + style.stroke: transparent + style.font-size: 21 + style.italic: true + style.font-color: "#666" + } + } + # Force course-container below dev (the lowest node in the flow) + dev -> course-container: { style.opacity: 0 } + + # Main flow + sprint -> create + create -> dev + dev -> review + review -> done + done -> retro + + # Feedback loops - these should now be visible + review -> dev: fixes { style.stroke-dash: 3; style.stroke: "#f57c00"; style.font-size: 21; style.italic: true } + done -> create: next story { style.stroke-dash: 3; style.stroke: "#f57c00"; style.font-size: 21; style.italic: true } + retro -> sprint: next epic { style.stroke-dash: 3; style.stroke: "#f57c00"; style.font-size: 21; style.italic: true } + } +} + +# Entry to lanes +init-row.init -> lanes.phase1.activities: { style.stroke: "#2d7d9a"; style.stroke-width: 2 } +init-row.init -> lanes.phase2.tech: Quick-flow { style.stroke-dash: 5; style.stroke: "#999"; style.font-size: 21; style.italic: true } + +# Cross-phase flows +lanes.phase1.brief -> lanes.phase2.prd +lanes.phase2.hasui -> lanes.phase3.arch: No +lanes.phase2.ux -> lanes.phase3.arch +lanes.phase2.tech -> lanes.phase3.epics: { style.stroke-dash: 5; style.stroke: "#999" } +lanes.phase3.impl -> lanes.phase4.sprint + +# Footer row +footer-row: "" { + style.fill: transparent + style.stroke: transparent + + footer: "DRAFTED: 2025-11-29 • REPOSITORY: github.com/bmad-code-org/BMAD-METHOD • LICENSE: MIT • UNCLASSIFIED • DISTRIBUTION: UNLIMITED • SUPERSEDES: ALL PREVIOUS EDITIONS" { + style.fill: transparent + style.stroke: transparent + style.font-size: 21 + style.font-color: "#555" + style.italic: true + label.near: bottom-left + } +} diff --git a/docs/diagrams/composite-quickflow.py b/docs/diagrams/composite-quickflow.py new file mode 100644 index 00000000..a2f9893c --- /dev/null +++ b/docs/diagrams/composite-quickflow.py @@ -0,0 +1,139 @@ +#!/usr/bin/env python3 +""" +Composite Quick Flow diagram onto main BMM workflow as a paper overlay. + +SCALING PRINCIPLE: Both diagrams use the same font sizes in D2 (27px for workflow boxes). +To maintain visual consistency, the Quick Flow must be scaled by the same factor as the +main diagram. This is calculated from the SVG viewBox dimensions and target PNG width. + +Formula: + scale_factor = main_png_width / main_svg_native_width + quick_flow_width = quick_flow_svg_native_width * scale_factor +""" + +import re +from PIL import Image, ImageDraw, ImageFilter + +# Configuration +MAIN_SVG = "bmm-workflow.svg" +MAIN_IMAGE = "bmm-workflow.png" +OVERLAY_SVG = "quick-flow.svg" +OVERLAY_IMAGE = "quick-flow.png" +OUTPUT_IMAGE = "bmm-workflow-with-quickflow.png" + +# Overlay positioning +OVERLAY_X = 150 # Left margin +OVERLAY_Y_FROM_BOTTOM = 140 # Distance from bottom + +# Paper effect settings +SHADOW_OFFSET = 0 +SHADOW_BLUR = 0 +SHADOW_COLOR = (0, 0, 0, 0) +BORDER_COLOR = (255, 255, 255) # No visible border +BORDER_WIDTH = 0 +PAPER_PADDING = 0 +ROTATION_ANGLE = -5 # 5° clockwise + + +def get_svg_native_width(svg_path): + """Extract native width from SVG viewBox attribute.""" + with open(svg_path, 'r') as f: + content = f.read() + + # Match the first viewBox (the main SVG element) + match = re.search(r'viewBox="[0-9.-]+\s+[0-9.-]+\s+([0-9.]+)\s+[0-9.]+"', content) + if match: + return float(match.group(1)) + raise ValueError(f"Could not find viewBox in {svg_path}") + + +def add_paper_effect(overlay): + """Add paper-like styling: padding, border, shadow.""" + + # Add padding (white border around content) + padded_w = overlay.width + PAPER_PADDING * 2 + padded_h = overlay.height + PAPER_PADDING * 2 + + paper = Image.new('RGBA', (padded_w, padded_h), (255, 255, 255, 255)) + paper.paste(overlay, (PAPER_PADDING, PAPER_PADDING)) + + # Draw border + draw = ImageDraw.Draw(paper) + draw.rectangle( + [0, 0, padded_w - 1, padded_h - 1], + outline=BORDER_COLOR, + width=BORDER_WIDTH + ) + + # Slight rotation for natural "placed" look + paper = paper.rotate(ROTATION_ANGLE, expand=True, fillcolor=(255, 255, 255, 0), resample=Image.BICUBIC) + + # Create shadow + shadow_size = (paper.width + SHADOW_OFFSET * 2 + SHADOW_BLUR * 2, + paper.height + SHADOW_OFFSET * 2 + SHADOW_BLUR * 2) + shadow = Image.new('RGBA', shadow_size, (0, 0, 0, 0)) + + # Draw shadow rectangle + shadow_draw = ImageDraw.Draw(shadow) + shadow_draw.rectangle( + [SHADOW_BLUR + SHADOW_OFFSET, + SHADOW_BLUR + SHADOW_OFFSET, + SHADOW_BLUR + SHADOW_OFFSET + paper.width, + SHADOW_BLUR + SHADOW_OFFSET + paper.height], + fill=SHADOW_COLOR + ) + shadow = shadow.filter(ImageFilter.GaussianBlur(SHADOW_BLUR)) + + # Composite paper onto shadow + shadow.paste(paper, (SHADOW_BLUR, SHADOW_BLUR), paper) + + return shadow + + +def main(): + # Load images + main_img = Image.open(MAIN_IMAGE).convert('RGBA') + overlay_img = Image.open(OVERLAY_IMAGE).convert('RGBA') + + print(f"Main image: {main_img.size}") + print(f"Overlay image: {overlay_img.size}") + + # Calculate proportional scale factor from SVG dimensions + main_svg_width = get_svg_native_width(MAIN_SVG) + overlay_svg_width = get_svg_native_width(OVERLAY_SVG) + + scale_factor = main_img.width / main_svg_width + target_overlay_width = int(overlay_svg_width * scale_factor) + + print(f"Main SVG native width: {main_svg_width}px") + print(f"Overlay SVG native width: {overlay_svg_width}px") + print(f"Scale factor: {scale_factor:.4f}") + print(f"Target overlay width: {target_overlay_width}px") + + # Resize overlay to maintain font scale parity + aspect = overlay_img.height / overlay_img.width + new_height = int(target_overlay_width * aspect) + overlay_img = overlay_img.resize((target_overlay_width, new_height), Image.LANCZOS) + print(f"Overlay resized to: {overlay_img.size}") + + # Add paper effect + paper_overlay = add_paper_effect(overlay_img) + + # Calculate position (bottom-left area) + pos_x = OVERLAY_X + pos_y = main_img.height - paper_overlay.height - OVERLAY_Y_FROM_BOTTOM + + print(f"Placing overlay at: ({pos_x}, {pos_y})") + + # Composite + main_img.paste(paper_overlay, (pos_x, pos_y), paper_overlay) + + # Save (convert to RGB for PNG without alpha issues) + main_img = main_img.convert('RGB') + main_img.save(OUTPUT_IMAGE, 'PNG') + + print(f"Saved: {OUTPUT_IMAGE}") + + +if __name__ == "__main__": + main() diff --git a/docs/diagrams/fonts/ArchitectsDaughter-Regular.ttf b/docs/diagrams/fonts/ArchitectsDaughter-Regular.ttf new file mode 100644 index 00000000..d0d88ba0 Binary files /dev/null and b/docs/diagrams/fonts/ArchitectsDaughter-Regular.ttf differ diff --git a/docs/diagrams/fonts/IndieFlower-Regular.ttf b/docs/diagrams/fonts/IndieFlower-Regular.ttf new file mode 100644 index 00000000..547ca580 Binary files /dev/null and b/docs/diagrams/fonts/IndieFlower-Regular.ttf differ diff --git a/docs/diagrams/fonts/Kalam-Regular.ttf b/docs/diagrams/fonts/Kalam-Regular.ttf new file mode 100644 index 00000000..0c956a29 Binary files /dev/null and b/docs/diagrams/fonts/Kalam-Regular.ttf differ diff --git a/docs/diagrams/fonts/Orbitron-Bold.ttf b/docs/diagrams/fonts/Orbitron-Bold.ttf new file mode 100644 index 00000000..9539cb4a --- /dev/null +++ b/docs/diagrams/fonts/Orbitron-Bold.ttf @@ -0,0 +1,1437 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page not found · GitHub · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ Skip to content + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + +
+
+ +
+
+ 404 “This is not the web page you are looking for” + + + + + + + + + + + + +
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + diff --git a/docs/diagrams/fonts/Raleway-Regular.ttf b/docs/diagrams/fonts/Raleway-Regular.ttf new file mode 100644 index 00000000..8e571af0 --- /dev/null +++ b/docs/diagrams/fonts/Raleway-Regular.ttf @@ -0,0 +1,1437 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Page not found · GitHub · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ Skip to content + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + + + + +
+ + + + + + + + + +
+
+ + + +
+
+ +
+
+ 404 “This is not the web page you are looking for” + + + + + + + + + + + + +
+
+ +
+
+ +
+ + +
+
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + diff --git a/docs/diagrams/fonts/ShareTechMono-Regular.ttf b/docs/diagrams/fonts/ShareTechMono-Regular.ttf new file mode 100644 index 00000000..1611474a Binary files /dev/null and b/docs/diagrams/fonts/ShareTechMono-Regular.ttf differ diff --git a/docs/diagrams/generate-bmm-workflow-diagram.md b/docs/diagrams/generate-bmm-workflow-diagram.md new file mode 100644 index 00000000..ef84ff0d --- /dev/null +++ b/docs/diagrams/generate-bmm-workflow-diagram.md @@ -0,0 +1,284 @@ +# Generate BMM Workflow Diagram + +This prompt generates a D2 diagram showing the BMad Method (BMM) workflow phases and their workflows. + +## Instructions + +Read workflow structure from the manifest and generate a D2 diagram with the following specifications: + +### 1. Load Workflow Manifest + +Read `docs/diagrams/workflow-manifest.yaml` to get: + +- **Version info**: `bmad_version` for the diagram title +- **Entry point**: `entry.workflow-init` with its output file +- **Phases**: All 4 phases (discovery, planning, solutioning, implementation) + - Phase labels, directories, optional flags + - Workflows within each phase (id, name, outputs) + - Connections within phases + - Decision points (e.g., "Has UI?") + - Feedback loops (Phase 4) +- **Quick Flow**: Separate diagram with its own entry and workflows +- **Cross-phase connections**: How phases connect to each other +- **Legend**: All output documents with descriptions + +**Do NOT scan the codebase** - all workflow information is in the manifest. + +### 2. Diagram Structure + +``` +direction: down + +# Top-level vertical layout +grid-rows: 3 +grid-columns: 1 +grid-gap: 20 + +# Row 1: Title +title: "BMAD METHOD V{VERSION}" # Uppercase for blueprint aesthetic + +To get version: +1. Read `bmad_version` from workflow-manifest.yaml +2. Use verbatim with "V" prefix uppercase: e.g., "6.0.0-alpha.12" → "V6.0.0-ALPHA.12" + +# Row 2: Entry point (workflow-init) +# Position above border between Phase 1 and 2 using spacers: +init-row with grid-columns: 4 + - 1 spacer left + - workflow-init box + - 2 spacers right + +# Row 3: Lanes container +lanes with grid-columns: 4 for 4 phases side-by-side +``` + +### 3. Phase Layout + +Use ELK layout engine for better container width support: + +```d2 +vars: { + d2-config: { + layout-engine: elk + } +} +``` + +Each phase is a colored container with explicit width for A4 landscape ratio: + +- **Phase 1 (Discovery)**: Teal/cyan (#e8f4f8), dashed border (optional phase), width: 400 + - Contains "Activities (any order)" sub-container + - All activities flow to product-brief +- **Phase 2 (Planning)**: Purple/lavender (#f0e8f8), width: 350 + - tech-spec at top (quick-flow entry point) + - prd → Has UI? → ux-design flow +- **Phase 3 (Solutioning)**: Gold/amber (#f8f0e8), width: 400 + - Vertical flow: architecture → epics-and-stories → impl-readiness +- **Phase 4 (Implementation)**: Green/mint (#e8f8f0), width: 520 + - Vertical flow with feedback loops (orange dashed) + - Loops: fixes (review→dev), next story (dev→create), next epic (retro→sprint) + +Set `grid-gap: 90` on lanes container to achieve ~1.41:1 A4 landscape ratio. + +### 4. Naming Convention + +All workflow boxes use: + +- Forward slash prefix: `/workflow-name` +- Kebab-case: `/sprint-planning`, `/code-review` +- Decision diamonds don't get slashes: "Has UI?" + +### 5. Output Document Labels + +Workflows that produce artifacts show the output filename on a second line: + +```d2 +# Use newline to show output document +brief: "/product-brief\n@product-brief.md" { class: n1 } +prd: "/prd\n@PRD.md" { class: n2 } +``` + +**Get output documents from the manifest:** + +- Read each workflow's `outputs` array +- For each output file, show it on a second line with the workflow name +- Example: If workflow `product-brief` has output `@product-brief.md`, render as `/product-brief\n@product-brief.md` + +Post-process SVG to make `@*` lines smaller (14px) and gray (#777): + +```python +# In shrink-output-labels.py +pattern = r']*>@[^<]*' +# Add: font-size="14px" fill="#777777" +``` + +### 6. Cross-Phase Connections + +**Get connections from the manifest:** + +- Read `cross_phase_connections` array for main diagram connections +- Read `phases.*.connections` for within-phase connections +- Read `phases.*.decisions` for decision points +- Read `phases.*.feedback_loops` for Phase 4 loops + +**Note**: Quick-flow is a separate diagram (not connected to main diagram) + +### 7. Styling Classes + +```d2 +classes: { + phase1-box: { fill: "#e8f4f8", stroke: "#2d7d9a", stroke-width: 3, border-radius: 12 } + phase2-box: { fill: "#f0e8f8", stroke: "#7d2d9a", stroke-width: 3, border-radius: 12 } + phase3-box: { fill: "#f8f0e8", stroke: "#9a7d2d", stroke-width: 3, border-radius: 12 } + phase4-box: { fill: "#e8f8f0", stroke: "#2d9a7d", stroke-width: 3, border-radius: 12 } + n1: { fill: "#fff", stroke: "#2d7d9a", stroke-width: 2, border-radius: 4, font-size: 18 } + n2: { fill: "#fff", stroke: "#7d2d9a", stroke-width: 2, border-radius: 4, font-size: 18 } + n3: { fill: "#fff", stroke: "#9a7d2d", stroke-width: 2, border-radius: 4, font-size: 18 } + n4: { fill: "#fff", stroke: "#2d9a7d", stroke-width: 2, border-radius: 4, font-size: 18 } + decision: { shape: diamond, fill: "#fff8e8", stroke: "#7d2d9a" } + opt: { stroke: "#888", fill: "#f8f8f8", stroke-dash: 5 } +} +``` + +### 8. Title Styling + +Title should be: + +- Large font (48px) +- Bold +- Uppercase +- Dark blue color (#1a3a5c) + +Post-process to apply outline/hollow letter effect: + +```python +# In outline-title.py - make title have stroke but no fill +pattern = r'(]*)(fill="#[^"]*")([^>]*style="[^"]*font-size:48px">BMAD METHOD[^<]*)' +replacement = r'\1fill="none" stroke="#1a3a5c" stroke-width="2"\3' +``` + +### 9. Font + +Use ShareTechMono for technical/monospace aesthetic: + +```bash +d2 --font-regular=fonts/ShareTechMono-Regular.ttf \ + --font-bold=fonts/ShareTechMono-Regular.ttf \ + bmm-workflow.d2 bmm-workflow.svg +``` + +### 10. Output Generation + +Generate files in this order: + +1. `bmm-workflow.d2` - the diagram source +2. Generate base SVG: + ```bash + d2 --font-regular=fonts/ShareTechMono-Regular.ttf \ + --font-bold=fonts/ShareTechMono-Regular.ttf \ + bmm-workflow.d2 bmm-workflow-technical.svg + ``` +3. Post-process for output label styling: + ```bash + python3 scripts/shrink-output-labels.py bmm-workflow-technical.svg bmm-workflow.svg + ``` +4. Post-process for outline title: + ```bash + python3 scripts/outline-title.py bmm-workflow.svg bmm-workflow.svg + ``` +5. Left-align the title: + ```bash + python3 scripts/left-align-title.py bmm-workflow.svg bmm-workflow.svg + ``` +6. Inject legend into top-right: + ```bash + python3 scripts/inject-legend.py bmm-workflow.svg bmm-workflow.svg + ``` +7. Convert to PNG (max width 1600px to keep file size reasonable): + ```bash + rsvg-convert bmm-workflow.svg -w 1600 -o bmm-workflow.png + ``` +8. Verify PNG size before reading (must check dimensions first): + ```bash + identify bmm-workflow.png # Should be ~1600x1150 or smaller + ``` + If dimensions exceed 1600px width, regenerate with `-w 1600` flag. +9. Clean up intermediate file: + ```bash + rm bmm-workflow-technical.svg + ``` + +### 11. Post-Processing Scripts + +Located in `scripts/` directory: + +**shrink-output-labels.py** - Makes `@*.md` labels smaller and gray +**outline-title.py** - Applies hollow/outline effect to title text + +### 12. Self-Check + +Before finalizing, verify the following: + +**Manifest Loading:** + +- [ ] workflow-manifest.yaml loaded successfully +- [ ] Version extracted from manifest for title +- [ ] All 4 phases read from manifest +- [ ] Quick-flow section read from manifest +- [ ] All connections and decisions extracted + +**Layout & Structure** + +- [ ] Four phases displayed horizontally (left to right: Discovery → Planning → Solutioning → Implementation) +- [ ] Phase 1 has dashed border (optional phase) +- [ ] Phases 2-4 have solid borders +- [ ] All workflow boxes are consistent sizes (not shrunk or expanded) +- [ ] Aspect ratio is approximately 1.41:1 (A4 landscape) + +**Workflow Boxes** + +- [ ] All workflow names start with `/` prefix +- [ ] Decision diamond ("Has UI?") has no `/` prefix +- [ ] Workflows with outputs show `@filename.md` on second line +- [ ] Output labels are smaller and grayed (after post-processing) + +**Connections** + +- [ ] `/workflow-init` connects to Phase 1 activities (solid line) +- [ ] `/workflow-init` connects to `/tech-spec` (dashed line, "Quick-flow" label) +- [ ] `/product-brief` → `/prd` connection exists +- [ ] "Has UI?" diamond has "Yes" → `/ux-design` and "No" → `/architecture` +- [ ] `/tech-spec` → `/epics-and-stories` (dashed line, quick-flow path) +- [ ] `/impl-readiness` → `/sprint-planning` connection exists + +**Phase 4 Feedback Loops** + +- [ ] `/code-review` → `/dev-story` loop exists (orange dashed, "fixes" label) +- [ ] `/dev-story` → `/create-story` loop exists (orange dashed, "next story" label) +- [ ] `/retrospective` → `/sprint-planning` loop exists (orange dashed, "next epic" label) + +**Title** + +- [ ] Title is uppercase: "BMAD METHOD V{VERSION}" +- [ ] Title has outline/hollow letter effect (after post-processing) +- [ ] Version matches current release tag + +**Output Documents** + +- [ ] `/product-brief` shows `@product-brief.md` +- [ ] `/tech-spec` shows `@tech-spec.md` +- [ ] `/prd` shows `@PRD.md` +- [ ] `/ux-design` shows `@ux-design.md` +- [ ] `/architecture` shows `@architecture.md` +- [ ] `/epics-and-stories` shows `@epics/*.md` +- [ ] `/create-story` shows `@story-*.md` + +**Final Output** + +- [ ] SVG renders correctly in browser +- [ ] PNG converts without font issues (use `rsvg-convert`) +- [ ] No text overflow or clipping in boxes +- [ ] Colors match phase scheme (teal, purple, gold, green) +- [ ] Legend box in top-right with all output document descriptions +- [ ] Red herring fish stamp visible in bottom-right corner, rotated +- [ ] Footer with metadata (date, repository, license, distribution statement) diff --git a/docs/diagrams/generate-manifest.md b/docs/diagrams/generate-manifest.md new file mode 100644 index 00000000..30b00ac3 --- /dev/null +++ b/docs/diagrams/generate-manifest.md @@ -0,0 +1,283 @@ +# Generate BMM Workflow Manifest + +This prompt generates a YAML manifest of all BMM workflows, their connections, and dependencies. The manifest serves as the source of truth for diagram generation and workflow documentation. + +## Instructions + +You are an agentic assistant tasked with researching the BMM workflow structure and generating a comprehensive manifest. Follow these steps: + +### 1. Research Phase + +Scan the BMM workflow structure to discover all workflows: + +**Locations to scan:** + +- `src/modules/bmm/workflows/1-analysis/` - Phase 1 (Discovery) workflows +- `src/modules/bmm/workflows/2-plan-workflows/` - Phase 2 (Planning) workflows +- `src/modules/bmm/workflows/3-solutioning/` - Phase 3 (Solutioning) workflows +- `src/modules/bmm/workflows/4-implementation/` - Phase 4 (Implementation) workflows +- `src/modules/bmm/workflows/bmad-quick-flow/` - Quick Flow workflows +- `src/modules/bmm/workflows/workflow-status/init/` - Entry point workflow + +**For each workflow directory, extract from `workflow.yaml`:** + +- `name` - The workflow name (e.g., "product-brief") +- `default_output_file` or output patterns - What files the workflow produces +- **DO NOT extract descriptions** - they cause false change detection and aren't used in diagrams + +**Additional information to gather:** + +- Read `package.json` to get the current BMAD version +- Get the current git commit hash (short form): `git rev-parse --short HEAD` +- Current timestamp in ISO format +- **Reference `docs/diagrams/bmm-workflow.d2`** for workflow connections (not descriptions) + +### 2. Understand Workflow Connections + +Study the existing `docs/diagrams/bmm-workflow.d2` file to understand: + +**Within-phase connections:** + +- Phase 1: All activities (brainstorm, research, domain-research, document-project) converge to product-brief +- Phase 3: architecture → create-epics-and-stories → implementation-readiness (sequential) +- Phase 4: sprint-planning → create-story → dev-story → code-review → story-done → retrospective (sequential) + +**Decision points:** + +- Phase 2: After `/prd`, there's a "Has UI?" decision + - Yes → `/ux-design` + - No → `/architecture` (cross-phase to Phase 3) + +**Feedback loops (Phase 4):** + +- code-review → dev-story (label: "fixes") +- story-done → create-story (label: "next story") +- retrospective → sprint-planning (label: "next epic") + +**Cross-phase connections:** + +- Entry: workflow-init → Phase 1 activities (main flow) +- Entry: workflow-init → quick-flow/create-tech-spec (quick-flow path) +- Phase 1: product-brief → Phase 2 prd +- Phase 2: ux-design → Phase 3 architecture +- Phase 2: tech-spec → Phase 3 create-epics-and-stories (quick-flow path, dashed) +- Phase 3: implementation-readiness → Phase 4 sprint-planning + +**Standalone workflows:** + +- Phase 4: `/correct-course` - Not part of main flow, run when issues arise + +### 3. Build Manifest + +Create a YAML manifest with this structure: + +```yaml +version: '1.0' +generated: '' +source_commit: '' +bmad_version: '' + +# Entry point +entry: + id: workflow-init + name: /workflow-init + outputs: + - file: '@bmm-workflow-status.yaml' + +phases: + discovery: + label: 'PHASE 1: DISCOVERY' + directory: '1-analysis' + optional: true + parallel: true # Activities can run in any order + workflows: + - id: + name: / + outputs: + - file: '@filename.md' + description: '...' # Only output files have descriptions (for legend) + + connections: + - from: [brainstorm-project, research, domain-research, document-project] + to: product-brief + type: converge + + planning: + label: 'PHASE 2: PLANNING' + directory: '2-plan-workflows' + optional: false + parallel: false + workflows: [...] + + decisions: + - id: has-ui + label: 'Has UI?' + after: prd + branches: + - condition: 'Yes' + to: ux-design + - condition: 'No' + to: architecture + + connections: + - from: ux-design + to: architecture + + solutioning: + label: 'PHASE 3: SOLUTIONING' + directory: '3-solutioning' + optional: false + parallel: false + workflows: [...] + + connections: + - from: architecture + to: create-epics-and-stories + type: sequential + - from: create-epics-and-stories + to: implementation-readiness + type: sequential + + implementation: + label: 'PHASE 4: IMPLEMENTATION' + directory: '4-implementation' + optional: false + parallel: false + workflows: [...] + + connections: + - from: sprint-planning + to: create-story + type: sequential + # ... etc + + feedback_loops: + - from: code-review + to: dev-story + label: 'fixes' + description: 'Return to dev for fixes' + # ... etc + +quick_flow: + auto_regenerate: false + directory: 'bmad-quick-flow' + description: 'Fast-track path for experienced teams' + workflows: [...] + + connections: + - from: create-tech-spec + to: quick-dev + type: sequential + +cross_phase_connections: + - from: entry.workflow-init + to: phases.discovery.activities + label: 'Main flow' + type: entry + - from: entry.workflow-init + to: quick_flow.create-tech-spec + label: 'Quick-flow' + type: quick_flow + # ... etc + +legend: + title: 'OUTPUTS' + items: + - file: '@filename.md' + description: '...' + # ... all output files from all workflows +``` + +### 4. Compare with Previous Manifest (if exists) + +If `docs/diagrams/workflow-manifest.yaml` already exists: + +1. Load the existing manifest +2. Compare with the newly generated manifest +3. Detect changes: + - Added workflows + - Removed workflows + - Changed workflow outputs + - Changed output file descriptions (in legend) + - Changed connections or dependencies + - Changed decision points or feedback loops + +4. Categorize changes: + - **Quick Flow changes**: Any changes in the `quick_flow` section + - **Main workflow changes**: Any changes in `phases` or `cross_phase_connections` + +### 5. Decision Point + +**If Quick Flow changes detected:** + +- **HARD STOP** - Do not proceed +- Report what changed in detail +- Ask user: "Quick Flow has changed. What would you like to do?" + - Option 1: Update manifest with changes + - Option 2: Keep existing manifest + - Option 3: Review changes and decide + +**If main workflow changes detected:** + +- Report what changed +- Ask user: "Main workflows have changed. Approve updating the manifest?" + - If approved: Proceed to write + - If rejected: Keep existing manifest + +**If no changes detected:** + +- Proceed silently to write manifest + +### 6. Write Manifest + +Write the manifest to `docs/diagrams/workflow-manifest.yaml` + +Report summary: + +- Number of workflows discovered +- Number of phases +- Number of output documents +- Any changes detected (if comparing) + +## Self-Check + +Before finalizing, verify: + +**Completeness:** + +- [ ] All workflow directories scanned +- [ ] All workflow.yaml files read +- [ ] All output files extracted +- [ ] Version and commit info included +- [ ] Timestamp is current + +**Connections:** + +- [ ] Within-phase connections defined +- [ ] Cross-phase connections defined +- [ ] Decision points defined +- [ ] Feedback loops defined +- [ ] Quick-flow paths defined + +**Accuracy:** + +- [ ] Workflow names match directory names +- [ ] Workflows do NOT have description fields (prevents false change detection) +- [ ] Output file descriptions are clear and concise (appear in legend) +- [ ] Output files match workflow.yaml patterns +- [ ] Connections match bmm-workflow.d2 + +**Change Detection (if applicable):** + +- [ ] Previous manifest loaded correctly +- [ ] All changes detected +- [ ] Changes categorized correctly +- [ ] User prompted appropriately + +## Notes + +- This is an **agentic prompt**, not a formal BMAD workflow +- The manifest is the **source of truth** for diagram generation +- Quick Flow changes require **hard stop** - they're critical +- Main workflow changes require **user approval** - they're important +- The manifest should be **version controlled** in git diff --git a/docs/diagrams/gracefully-age.prompt.md b/docs/diagrams/gracefully-age.prompt.md new file mode 100644 index 00000000..172edd6b --- /dev/null +++ b/docs/diagrams/gracefully-age.prompt.md @@ -0,0 +1,26 @@ +# Gracefully Age - Nano-Banana Pro Prompt + +Age this technical diagram to look like a 1960s archival document. + +CRITICAL - TEXT MUST BE PERFECT: + +- Every letter, number, and symbol must remain crisp and undistorted +- No warping, smearing, or altering of ANY text +- No changes to lines, arrows, or box shapes +- Preserve all elements exactly as shown + +ONLY apply: + +- Aged paper texture (cream/yellowed) - Keep in mind that this image already looks like old paper, with its yellowish background and faded pastel tones. +- Subtle coffee stain in top-left corner +- Subtle fold creases +- Lightly worn edges and corners +- Light vignette + +DO NOT apply any effect that distorts text. If in doubt, leave it alone. + +NO watermarks or AI signatures. + +## POST-PROCESSING + +Nano-Banana will add a 4-pointed star watermark in the bottom-right. Remove it using the instructions in README.md. diff --git a/docs/diagrams/post-process-quickflow.py b/docs/diagrams/post-process-quickflow.py new file mode 100644 index 00000000..9486a2ae --- /dev/null +++ b/docs/diagrams/post-process-quickflow.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +Post-process Quick Flow SVG to style output labels like main diagram. +""" + +import re + +INPUT_FILE = "quick-flow.svg" +OUTPUT_FILE = "quick-flow.svg" + + +def shrink_output_labels(content): + """Make @*.md output labels smaller and grayed.""" + + def shrink_tspan(match): + tspan = match.group(0) + return tspan.replace(']*>(@[^<]*|Shortcut for[^<]*|Can run standalone)' + content = re.sub(pattern, shrink_tspan, content) + return content + + +def outline_title(content): + """Make the title text have an outline/stencil effect.""" + # Match title text with font-size 4Xpx and fill color + pattern = r'(]*)(fill="#1a3a5c")([^>]*style="[^"]*font-size:4\dpx[^"]*")' + replacement = r'\1fill="none" stroke="#1a3a5c" stroke-width="1.5"\3' + return re.sub(pattern, replacement, content) + + +def main(): + with open(INPUT_FILE, 'r') as f: + content = f.read() + + content = shrink_output_labels(content) + content = outline_title(content) + + with open(OUTPUT_FILE, 'w') as f: + f.write(content) + + print(f"Post-processed: {INPUT_FILE}") + + +if __name__ == "__main__": + main() diff --git a/docs/diagrams/post-process-svg.py b/docs/diagrams/post-process-svg.py new file mode 100755 index 00000000..be9afce6 --- /dev/null +++ b/docs/diagrams/post-process-svg.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python3 +""" +Post-process BMM workflow diagram SVG. + +Transforms raw D2 output into the final styled diagram. +Run from docs/diagrams directory. +""" + +import re +import base64 + +# ============================================================================= +# CONFIGURATION +# ============================================================================= + +INPUT_FILE = "bmm-workflow-technical.svg" +OUTPUT_FILE = "bmm-workflow.svg" +STAMP_FILE = "red-herring.png" + +# ============================================================================= +# PROCESSING STEPS +# ============================================================================= + +def process_svg(): + """Run all SVG post-processing steps in order.""" + with open(INPUT_FILE, 'r') as f: + content = f.read() + + content = shrink_output_labels(content) + content = outline_title(content) + content = left_align_title(content) + content = inject_legend(content) + content = inject_stamp(content) + + with open(OUTPUT_FILE, 'w') as f: + f.write(content) + + print(f"Post-processed: {INPUT_FILE} -> {OUTPUT_FILE}") + + +# ============================================================================= +# STEP 1: Shrink output labels (@*.md) +# ============================================================================= + +def shrink_output_labels(content): + """Make @*.md output labels smaller and grayed.""" + + def shrink_tspan(match): + tspan = match.group(0) + return tspan.replace(']*>@[^<]*' + content = re.sub(pattern, shrink_tspan, content) + + return content + + +# ============================================================================= +# STEP 2: Outline title text +# ============================================================================= + +def outline_title(content): + """Make the title text have an outline/hollow effect.""" + + # Pattern: + pattern = r'(]*)(fill="#1a3a5c")([^>]*style="[^"]*font-size:4\dpx[^"]*")' + replacement = r'\1fill="none" stroke="#1a3a5c" stroke-width="1.5"\3' + + return re.sub(pattern, replacement, content) + + +# ============================================================================= +# STEP 3: Left-align title +# ============================================================================= + +def left_align_title(content): + """Left-align the title text.""" + + def align_title(match): + text_elem = match.group(0) + text_elem = text_elem.replace('text-anchor:middle', 'text-anchor:start') + text_elem = re.sub(r'x="[^"]*"', 'x="50"', text_elem) + return text_elem + + pattern = r']*font-size:4[0-9]px[^>]*>BMAD METHOD[^<]*' + return re.sub(pattern, align_title, content) + + +# ============================================================================= +# STEP 4: Inject legend +# ============================================================================= + +LEGEND_WIDTH = 1200 +LEGEND_SVG = ''' + + + + + + OUTPUTS + + + + + + + @bmm-workflow-status.yaml + · Workflow tracking + + + @product-brief.md + · Product vision and scope + + + @tech-spec.md + · Quick-flow technical spec + + + @PRD.md + · Product requirements + + + @ux-design.md + · UX/UI design spec + + + @architecture.md + · System architecture + + + @impl-readiness-report.md + · Readiness validation + + + + + @epics.md + · Epic and story breakdown + + + @sprint-status.yaml + · Sprint progress tracking + + + @{{epic}}-{{story}}-*.md + · Implementation stories + + + @sprint-change-proposal.md + · Course correction + + +''' + +def inject_legend(content): + """Inject legend box in top-right corner.""" + + legend_y = 180 + + # Find Phase 4 right edge + phase4_match = re.search( + r'phase4-box[^>]*>.*?]*x="([0-9.]+)"[^>]*width="([0-9.]+)"', + content, re.DOTALL + ) + + if phase4_match: + phase4_x = float(phase4_match.group(1)) + phase4_w = float(phase4_match.group(2)) + legend_x = phase4_x + phase4_w - LEGEND_WIDTH + 97 + else: + legend_x = 2314 - LEGEND_WIDTH + 97 + + legend = LEGEND_SVG.format(x=legend_x, y=legend_y) + + last_svg_pos = content.rfind('') + if last_svg_pos != -1: + content = content[:last_svg_pos] + legend + '\n' + content[last_svg_pos:] + + return content + + +# ============================================================================= +# STEP 5: Inject red herring stamp +# ============================================================================= + +STAMP_WIDTH = 200 +STAMP_HEIGHT = 134 +STAMP_MARGIN_X = 220 +STAMP_MARGIN_Y = 85 +STAMP_ROTATION = 10 + +def inject_stamp(content): + """Inject red herring stamp in lower-right corner.""" + + # Read and encode stamp image + with open(STAMP_FILE, 'rb') as f: + stamp_data = base64.b64encode(f.read()).decode('utf-8') + + # Get SVG dimensions + viewbox_match = re.search(r'viewBox="(\d+)\s+(\d+)\s+(\d+)\s+(\d+)"', content) + if viewbox_match: + svg_width = int(viewbox_match.group(3)) + svg_height = int(viewbox_match.group(4)) + else: + svg_width, svg_height = 2000, 1500 + + stamp_x = svg_width - STAMP_WIDTH - STAMP_MARGIN_X + stamp_y = svg_height - STAMP_HEIGHT - STAMP_MARGIN_Y + + center_x = STAMP_WIDTH / 2 + center_y = STAMP_HEIGHT / 2 + + stamp_svg = f''' + + + +''' + + last_svg_pos = content.rfind('') + if last_svg_pos != -1: + content = content[:last_svg_pos] + stamp_svg + '\n' + content[last_svg_pos:] + + return content + + +# ============================================================================= +# MAIN +# ============================================================================= + +if __name__ == "__main__": + process_svg() diff --git a/docs/diagrams/quick-flow.d2 b/docs/diagrams/quick-flow.d2 new file mode 100644 index 00000000..40a4acba --- /dev/null +++ b/docs/diagrams/quick-flow.d2 @@ -0,0 +1,98 @@ +direction: down + +vars: { + d2-config: { + layout-engine: elk + } +} + +classes: { + terminal: { + style: { + fill: "#1a3a5c" + stroke: "#0d1f30" + stroke-width: 2 + border-radius: 40 + font-size: 24 + font-color: "#fff" + italic: true + } + } + workflow: { + style: { + fill: "#fff" + stroke: "#7d2d9a" + stroke-width: 2 + border-radius: 6 + font-size: 27 + } + } + workflow-impl: { + style: { + fill: "#fff" + stroke: "#2d9a7d" + stroke-width: 2 + border-radius: 6 + font-size: 27 + } + } +} + +# Outer container: 3 rows x 1 column +outer: "" { + style.fill: transparent + style.stroke: transparent + + grid-rows: 3 + grid-columns: 1 + vertical-gap: 20 + + # Row 1: Title + title: "QUICK FLOW" { + style.fill: transparent + style.stroke: transparent + style.font-size: 48 + style.bold: true + style.font-color: "#1a3a5c" + } + + # Row 2: Flow grid (3x3) + flow: "" { + style.fill: transparent + style.stroke: transparent + + grid-rows: 3 + grid-columns: 3 + vertical-gap: 0 + horizontal-gap: 60 + + # Row 1: spacer, spacer, exit + s1: "" { style.opacity: 0 } + s2: "" { style.opacity: 0 } + exit: "to /epics-and-stories" { class: terminal } + + # Row 2: entry, tech-spec, spacer + entry: "from /workflow-init" { class: terminal } + tech: "/create-tech-spec\n@tech-spec.md\nShortcut for planning/arch" { class: workflow } + s3: "" { style.opacity: 0 } + + # Row 3: spacer, spacer, quick-dev + s4: "" { style.opacity: 0 } + s5: "" { style.opacity: 0 } + quickdev: "/quick-dev\nShortcut for implementation\nCan run standalone" { class: workflow-impl } + } + + # Row 3: Explanation + caption: "Fast track for simple changes" { + style.fill: transparent + style.stroke: transparent + style.font-size: 20 + style.italic: true + style.font-color: "#666" + } +} + +# Flow connections +outer.flow.entry -> outer.flow.tech: { style.stroke-width: 2; style.stroke: "#555" } +outer.flow.tech -> outer.flow.exit: { style.stroke-width: 2; style.stroke: "#888"; style.stroke-dash: 3 } +outer.flow.tech -> outer.flow.quickdev: { style.stroke-width: 2; style.stroke: "#555" } diff --git a/docs/diagrams/workflow-manifest.yaml b/docs/diagrams/workflow-manifest.yaml new file mode 100644 index 00000000..9c573f00 --- /dev/null +++ b/docs/diagrams/workflow-manifest.yaml @@ -0,0 +1,254 @@ +version: "1.0" +generated: "2025-11-30T14:11:39Z" +source_commit: "31bdb1df" +bmad_version: "6.0.0-alpha.12" + +# Entry point +entry: + id: workflow-init + name: /workflow-init + outputs: + - file: "@bmm-workflow-status.yaml" + description: "BMM workflow tracking status" + +phases: + discovery: + label: "PHASE 1: DISCOVERY" + directory: "1-analysis" + optional: true + parallel: true # Activities can run in any order + workflows: + - id: brainstorm-project + name: /brainstorm-project + outputs: [] + - id: research + name: /research + outputs: [] + - id: domain-research + name: /domain-research + outputs: [] + - id: document-project + name: /document-project + outputs: [] + - id: product-brief + name: /product-brief + outputs: + - file: "@product-brief.md" + description: "Product vision and requirements" + + # Connections within this phase + connections: + - from: [brainstorm-project, research, domain-research, document-project] + to: product-brief + type: converge # All activities converge to product-brief + + planning: + label: "PHASE 2: PLANNING" + directory: "2-plan-workflows" + optional: false + parallel: false + workflows: + - id: tech-spec + name: /tech-spec + outputs: + - file: "@tech-spec.md" + description: "Technical specification" + optional: true # Part of quick-flow, not main flow + - id: prd + name: /prd + outputs: + - file: "@PRD.md" + description: "Product requirements document" + - id: ux-design + name: /ux-design + outputs: + - file: "@ux-design.md" + description: "UX design and wireframes" + + # Decision points + decisions: + - id: has-ui + label: "Has UI?" + after: prd + branches: + - condition: "Yes" + to: ux-design + - condition: "No" + to: architecture # Cross-phase connection + + connections: + - from: ux-design + to: architecture # Cross-phase connection + + solutioning: + label: "PHASE 3: SOLUTIONING" + directory: "3-solutioning" + optional: false + parallel: false + workflows: + - id: architecture + name: /architecture + outputs: + - file: "@architecture.md" + description: "System architecture and design" + - id: create-epics-and-stories + name: /create-epics-and-stories + outputs: + - file: "@epics.md" + description: "Epic and story breakdown" + - id: implementation-readiness + name: /implementation-readiness + outputs: + - file: "@impl-readiness-report.md" + description: "Implementation readiness report" + + connections: + - from: architecture + to: create-epics-and-stories + type: sequential + - from: create-epics-and-stories + to: implementation-readiness + type: sequential + + implementation: + label: "PHASE 4: IMPLEMENTATION" + directory: "4-implementation" + optional: false + parallel: false + workflows: + - id: sprint-planning + name: /sprint-planning + outputs: + - file: "@sprint-status.yaml" + description: "Sprint status and planning" + - id: create-story + name: /create-story + outputs: + - file: "@{epic}-{story}-*.md" + description: "Story implementation details" + - id: dev-story + name: /dev-story + outputs: [] + - id: code-review + name: /code-review + outputs: [] + - id: story-done + name: /story-done + outputs: [] + - id: retrospective + name: /retrospective + outputs: [] + - id: correct-course + name: /correct-course + outputs: + - file: "@sprint-change-proposal.md" + description: "Sprint change proposal" + standalone: true # Not part of main flow + + # Main flow + connections: + - from: sprint-planning + to: create-story + type: sequential + - from: create-story + to: dev-story + type: sequential + - from: dev-story + to: code-review + type: sequential + - from: code-review + to: story-done + type: sequential + - from: story-done + to: retrospective + type: sequential + + # Feedback loops (iterative flows) + feedback_loops: + - from: code-review + to: dev-story + label: "fixes" + description: "Return to dev for fixes" + - from: story-done + to: create-story + label: "next story" + description: "Continue with next story in epic" + - from: retrospective + to: sprint-planning + label: "next epic" + description: "Start next epic/sprint" + +# Quick Flow (separate diagram, composited into main diagram) +quick_flow: + auto_regenerate: false + directory: "bmad-quick-flow" + description: "Fast-track path for experienced teams" + + # Quick-flow includes its own workflow-init node + entry: + id: workflow-init + name: /workflow-init + outputs: + - file: "@bmm-workflow-status.yaml" + + workflows: + - id: create-tech-spec + name: /create-tech-spec + outputs: + - file: "@tech-spec.md" + description: "Technical specification" + - id: quick-dev + name: /quick-dev + outputs: [] + + connections: + - from: workflow-init + to: create-tech-spec + type: sequential + - from: create-tech-spec + to: quick-dev + type: sequential + +# Cross-phase connections (main diagram only) +cross_phase_connections: + - from: entry.workflow-init + to: phases.discovery.activities + label: "Main flow" + type: entry + - from: phases.discovery.product-brief + to: phases.planning.prd + type: sequential + - from: phases.planning.tech-spec + to: phases.solutioning.create-epics-and-stories + label: "Quick-flow path" + type: quick_flow + - from: phases.solutioning.implementation-readiness + to: phases.implementation.sprint-planning + type: sequential + +# Legend for diagram generation +legend: + title: "OUTPUTS" + items: + - file: "@bmm-workflow-status.yaml" + description: "BMM workflow tracking status" + - file: "@product-brief.md" + description: "Product vision and requirements" + - file: "@tech-spec.md" + description: "Technical specification" + - file: "@PRD.md" + description: "Product requirements document" + - file: "@ux-design.md" + description: "UX design and wireframes" + - file: "@architecture.md" + description: "System architecture and design" + - file: "@epics.md" + description: "Epic and story breakdown" + - file: "@impl-readiness-report.md" + description: "Implementation readiness report" + - file: "@sprint-status.yaml" + description: "Sprint status and planning" + - file: "@{epic}-{story}-*.md" + description: "Story implementation details" + - file: "@sprint-change-proposal.md" + description: "Sprint change proposal"