From beba6cf13d643d65b6aad54bac8093a4d2bcd8a3 Mon Sep 17 00:00:00 2001 From: Daniel Gee Date: Fri, 29 May 2026 21:12:17 +0100 Subject: [PATCH] create prompt to generate issue diagram --- .github/prompts/issues-diagram.prompt.md | 90 +++++++++ .github/skills/github-issues-status/SKILL.md | 105 ++++++++++ .github/skills/mermaid-html-diagram/SKILL.md | 199 +++++++++++++++++++ 3 files changed, 394 insertions(+) create mode 100644 .github/prompts/issues-diagram.prompt.md create mode 100644 .github/skills/github-issues-status/SKILL.md create mode 100644 .github/skills/mermaid-html-diagram/SKILL.md diff --git a/.github/prompts/issues-diagram.prompt.md b/.github/prompts/issues-diagram.prompt.md new file mode 100644 index 00000000..08d84826 --- /dev/null +++ b/.github/prompts/issues-diagram.prompt.md @@ -0,0 +1,90 @@ +--- +name: issues-diagram +description: Generate or refresh a self-contained HTML file with three interactive Mermaid dependency diagrams for the dgee2/Menu repo — epics only, child issues only, and a full combined view — with status-based colour coding and pan/zoom. +argument-hint: optional output path (defaults to docs/issues-diagram.html) +--- + +# Issues Dependency Diagram + +Generate (or refresh) the interactive HTML dependency diagram for this repository. + +## Skills to apply + +Apply both of these skills in order: + +1. **`github-issues-status`** — fetch all issues, parse epic task lists, and compute blocked / unblocked / in-progress / done status for every issue and epic. +2. **`mermaid-html-diagram`** — render the computed data as a self-contained HTML file. + +## Runtime context + +- Repository: `dgee2/Menu` +- Output path: `docs/issues-diagram.html` (override with the caller's argument if provided) +- Open the file after writing it + +## Three diagrams to produce + +### Diagram 1 — Epics only (`#epics-only`) + +- `rankDir: TB`, height `72vh` +- One node per epic; apply the epic's computed status class +- Labelled arrows between epics showing the dependency reason +- Node label includes: epic number, title, status indicator, and a one-line blocker summary + +### Diagram 2 — Child issues only (`#child-issues`) + +- `rankDir: LR`, height `85vh` +- Task nodes grouped into epic subgraphs; subgraph background colour matches epic status +- Within-epic arrows follow the natural implementation order (DB entity → API → frontend) +- Cross-epic arrows connect specific tasks at the boundary between dependent epics + (see the cross-epic wiring table below) +- Node label includes: issue number, short title, ✅ if closed + +### Diagram 3 — Full diagram (`#full-diagram`) + +- `rankDir: TB`, height `85vh` +- Epics as subgraph containers (styled by status) containing all child tasks +- Epic-level dependency arrows between subgraphs + +## Cross-epic task-level wiring (child issues diagram) + +These are the established dependencies inferred from epic bodies and domain ordering rules. +Re-verify closed state on each refresh — a closed issue promotes its dependents from BLOCKED to UNBLOCKED. + +| From | To | Reason | +|---|---|---| +| #1110 | #1111, #1112, #1113 | MenuUser.Id referenced by Recipe ownership | +| #1111, #1112, #1113 | #1114 | All DB changes before DTO expansion | +| #1114 | #1115, #1116, #1117 | DTOs before API endpoints | +| #1115 | #1118, #1123 | List endpoint before detail page / search index | +| #1116 | #1119, #1124, #1129 | Create/update before form, outbox, sharing | +| #1133 | #1134 | Public route group structural split required | +| #1117 | #1139 | Recipe CRUD complete before architectural restructure | +| #1110 | #1129, #1143, #1144, #1151, #1154 | User identity before all user-owned features | +| #1124 | #1148 | Outbox infra before metrics snapshot | +| #1125 | #1149 | RecipeViewed event before metrics consumer | +| #1143, #1145 | #1149 | Favourite/diary events feed metrics consumer | +| #1116 | #1143, #1151 | Recipe CRUD before favourite / collection features | + +## Known epic structure + +The table below is pre-populated from the 2026-05-28 snapshot. On each run, re-check issue states via `github-issues-status` and update statuses — do not use this table as a substitute for live data. + +| Epic | Title | Children | Depends on | +|-------|--------------------------------------------|-----------------|-------------------| +| #1097 | Identity & User Provisioning (MenuUser) | #1109, #1110 | — | +| #1098 | Core Recipe Model (DB Schema) | #1111–#1113 | #1097 | +| #1099 | Recipe Authoring API Expansion | #1114–#1117 | #1098 | +| #1100 | Frontend: Recipe Editor & Detail Pages | #1118–#1122 | #1099 | +| #1101 | Recipe Search | #1123–#1128 | #1099 | +| #1102 | Access Control & Sharing | #1129–#1133 | #1097, #1099 | +| #1103 | Recipe Publication | #1134–#1138 | #1102 (via #1133) | +| #1104 | Architectural Project Restructure | #1139–#1142 | #1099 | +| #1105 | Favourites & Diary | #1143–#1147 | #1097, #1099 | +| #1106 | Metrics & Engagement | #1148–#1150 | #1101, #1105 | +| #1107 | Curated Recipe Collections | #1151–#1153 | #1099 | +| #1108 | Communication Preferences | #1154–#1156 | #1097 | + +## Summary table + +Append an **Epic Summary** HTML table below the diagrams with columns: +Epic #, Title, Child Issues, Status, Depends on. diff --git a/.github/skills/github-issues-status/SKILL.md b/.github/skills/github-issues-status/SKILL.md new file mode 100644 index 00000000..b0d43fea --- /dev/null +++ b/.github/skills/github-issues-status/SKILL.md @@ -0,0 +1,105 @@ +--- +name: github-issues-status +description: Fetch all issues for a GitHub repo, parse Epic task lists, and compute a blocked/unblocked/in-progress/done status for every issue and epic transitively. +user-invokable: true +context: inline +--- + +# GitHub Issues Status + +## Purpose + +Use this skill whenever you need a structured view of issue states and blocking relationships — as input to a diagram, a sprint report, or any other artefact. It produces a data model (not a visual output) that other skills or prompts can consume. + +## Inputs + +| Name | Required | Description | +|---|---|---| +| `repo` | yes | `OWNER/REPO` slug, e.g. `dgee2/Menu` | +| `epic-pattern` | no | Title prefix that identifies epic issues. Default: `[Epic]` | + +## Step 1 — Fetch all issues + +```bash +gh issue list --repo --state all --limit 200 +``` + +Capture: `number`, `title`, `state` (OPEN / CLOSED), `labels`. + +## Step 2 — Identify epics and fetch their bodies + +Any issue whose title contains `[Epic]` (or the configured `epic-pattern`) is an **Epic**. + +For each epic, fetch the full body: + +```bash +gh issue view --repo --json title,body +``` + +Parse the body for GitHub task-list syntax to extract child issue references: + +``` +- [x] #NNNN ← completed child task +- [ ] #NNNN ← open child task +``` + +Build a map: `epic → [child issue numbers]`. + +## Step 3 — Infer cross-epic dependencies + +Read each epic body for explicit dependency language: + +> "depends on", "requires", "after", "once X exists", "built on top of", "comes first", "all subsequent" + +Also apply these domain ordering rules: +- DB schema / entity changes must precede API endpoint changes +- API endpoint changes must precede frontend changes +- User identity / auth foundation (MenuUser) must precede all feature epics +- Outbox / event infrastructure must precede projection consumers that read from it +- A "public route group" structural split must precede any public endpoints that use it + +Record each inferred dependency with a short reason label (used for arrow labels in diagrams). + +For cross-epic task-level wiring in child-issue diagrams, connect the last key output task of a prerequisite epic to the first task of the dependent epic. If multiple tasks must complete, wire each one explicitly. + +## Step 4 — Compute status for every issue + +Apply this algorithm **transitively**, starting from issues with no dependencies: + +``` +status(issue): + if issue.state == CLOSED → DONE + if all direct dependencies are DONE → UNBLOCKED + otherwise → BLOCKED +``` + +For **Epics**, derive status from their children and epic-level dependencies: + +``` +epicStatus(epic): + if all children DONE and all epic deps DONE → DONE + if some children DONE and next open child is UNBLOCKED + and all epic deps DONE → IN_PROGRESS + otherwise → BLOCKED +``` + +## Step 5 — Output the data model + +Produce a structured summary with these fields per issue: + +``` +{ + number: 1097, + title: "[Epic] Identity & User Provisioning (MenuUser)", + state: "OPEN", + status: "IN_PROGRESS", // DONE | UNBLOCKED | IN_PROGRESS | BLOCKED + isEpic: true, + children: [1109, 1110], // epic only + closedChildren: [1109], // epic only + deps: [], // issue numbers this one depends on + depLabels: {}, // dep number → reason string + blockedBy: [], // first-level open deps +} +``` + +This output is consumed by `mermaid-html-diagram` or other reporting skills. diff --git a/.github/skills/mermaid-html-diagram/SKILL.md b/.github/skills/mermaid-html-diagram/SKILL.md new file mode 100644 index 00000000..c9763c1e --- /dev/null +++ b/.github/skills/mermaid-html-diagram/SKILL.md @@ -0,0 +1,199 @@ +--- +name: mermaid-html-diagram +description: Generate a self-contained HTML file containing one or more interactive Mermaid diagrams with dark GitHub-style theming, status-based colour coding, and mouse/button pan-and-zoom via svg-pan-zoom. +user-invokable: true +context: inline +--- + +# Mermaid HTML Diagram + +## Purpose + +Use this skill to render any Mermaid diagram (flowchart, sequence, ER, state, etc.) as a polished, self-contained HTML file that can be opened directly in a browser. It handles the common pitfalls of embedding Mermaid SVGs in fixed-height containers and wiring up pan-and-zoom correctly. + +## Inputs + +| Name | Required | Description | +|---|---|---| +| `diagrams` | yes | List of `{ id, title, mermaidSource, height }` objects | +| `outputPath` | yes | Absolute path for the `.html` file | +| `pageTitle` | no | Browser tab title | +| `legend` | no | List of `{ label, fillColour, strokeColour }` items | + +## Colour palette — status-based nodes + +Use these consistently whenever nodes represent work items with a blocking status: + +| Status | Fill | Stroke | Text | Usage | +|-------------|---------|---------|---------|------------------------------------------| +| DONE | #2d1f6e | #8957e5 | #d2a8ff | Closed / completed issue | +| UNBLOCKED | #0d3020 | #3fb950 | #7ee787 | Open, all dependencies done — bold text | +| IN_PROGRESS | #3d2600 | #f0883e | #f0c674 | Partially done, next task ready — bold | +| BLOCKED | #2d1010 | #f85149 | #ffa198 | Open with at least one open dependency | + +Subgraph container backgrounds use the same fill/stroke as the group's status but slightly darker. + +Add status indicators to node labels: +- DONE: `✅` prefix or suffix +- IN_PROGRESS: `▶` prefix +- BLOCKED: `⛔` prefix + +## HTML structure + +```html + + + + + {pageTitle} + + + + + + + + + +``` + +## Critical CSS + +```css +* { box-sizing: border-box; } +body { font-family: system-ui, sans-serif; background: #0d1117; color: #c9d1d9; margin: 0; padding: 20px; } + +.mermaid-box { + width: 100%; overflow: hidden; + background: #161b22; border: 1px solid #30363d; border-radius: 8px; + cursor: grab; user-select: none; + display: block; position: relative; +} +.mermaid-box:active { cursor: grabbing; } +/* Mermaid injects a wrapper div — both it and the SVG must fill the container */ +.mermaid-box > .mermaid { + width: 100% !important; height: 100% !important; display: block !important; +} +.mermaid-box svg { + display: block !important; width: 100% !important; + height: 100% !important; max-width: none !important; +} + +.diagram-wrap { position: relative; } +.diagram-controls { + position: absolute; top: 10px; right: 10px; z-index: 10; display: flex; gap: 6px; +} +.diagram-controls button { + background: rgba(33,38,45,0.92); border: 1px solid #30363d; + color: #c9d1d9; border-radius: 6px; padding: 5px 12px; + cursor: pointer; font-size: 0.82rem; backdrop-filter: blur(4px); +} +.diagram-controls button:hover { background: #30363d; border-color: #58a6ff; color: #58a6ff; } +``` + +## Critical JS — initialisation + +Mermaid renders SVGs with **hardcoded pixel `width` and `height` attributes**. If you leave these in place, svg-pan-zoom will compute an incorrect viewport and the diagram will appear cut off or misaligned. The fix sequence is mandatory: + +```javascript +mermaid.initialize({ startOnLoad: false, theme: "dark", securityLevel: "loose" }); + +const pz = {}; + +document.addEventListener("DOMContentLoaded", async () => { + await mermaid.run({ querySelector: ".mermaid" }); + + const setups = [ + // { key, boxId, inId, outId, rstId } — one entry per diagram + ]; + + setups.forEach(({ key, boxId, inId, outId, rstId }) => { + const box = document.getElementById(boxId); + const svg = box && box.querySelector("svg"); + if (!svg) return; + + // 1. Strip Mermaid's hardcoded pixel dimensions (keep viewBox) + svg.removeAttribute("width"); + svg.removeAttribute("height"); + svg.style.cssText = "display:block;width:100%;height:100%;max-width:none;"; + + // 2. Make the inner .mermaid wrapper div fill the container too + const inner = svg.closest(".mermaid"); + if (inner) inner.style.cssText = "display:block;width:100%;height:100%;"; + + // 3. Initialise — do NOT pass fit/center:true here; call them explicitly after + pz[key] = svgPanZoom(svg, { + zoomEnabled: true, controlIconsEnabled: false, + fit: false, center: false, + minZoom: 0.04, maxZoom: 25, zoomScaleSensitivity: 0.3, + mouseWheelZoomEnabled: true, dblClickZoomEnabled: true, + preventMouseEventsDefault: true, + }); + + // 4. Resize to actual container, then fit and centre + pz[key].resize(); + pz[key].fit(); + pz[key].center(); + + // 5. Wire buttons + document.getElementById(inId) .addEventListener("click", () => pz[key].zoomIn()); + document.getElementById(outId).addEventListener("click", () => pz[key].zoomOut()); + document.getElementById(rstId).addEventListener("click", () => { + pz[key].resize(); pz[key].fit(); pz[key].center(); + }); + }); + + // 6. Re-fit on window resize + window.addEventListener("resize", () => { + Object.values(pz).forEach(p => { try { p.resize(); p.fit(); p.center(); } catch(e){} }); + }); +}); +``` + +## Container height guidelines + +| Diagram type | Recommended height | +|---|---| +| Simple (< 15 nodes) | `60vh` | +| Medium (15–30 nodes) | `72vh` | +| Large (30+ nodes) | `85vh` | + +## Per-diagram section HTML pattern + +```html +
+

{title}

+
+
+ + + +
+
+
+ {mermaidSource} +
+
+
+
+``` + +## Mermaid init block per diagram + +``` +%%{init: {"theme": "dark", "flowchart": {"rankDir": "TB", "nodeSpacing": 55, "rankSpacing": 80}}}%% +``` + +Use `rankDir: TB` (top-to-bottom) for dependency trees and `rankDir: LR` (left-to-right) for wide graphs with many parallel tracks. + +## After writing the file + +Open it immediately so the result is visible: + +```powershell +Start-Process "" +```