Dashboard Generator — SKILL.md

SkillMonitoring & ops

Generate monitoring dashboards for Grafana and DataDog with alert integration

Use Dashboard Generator — SKILL.md in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Dashboard Generator — SKILL.md and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the Dashboard Generator skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Dashboard Generator — SKILL.mdStart free

What this skill tells your AI

The instructions your AI receives, as published by a5c-ai/babysitter in library/specializations/software-architecture/skills/dashboard-generator/SKILL.md and read by ahel’s review.

Role: Step 8 — Generate the Mode C HTML dashboard from analysis-result.json. Triggered by: CLAUDE.md when output_mode = "C" after Step 7 (Analyst Agent completes analysis) Reads: run-local analysis-result.json, references/html-template.md, references/color-system.md Writes: output/reports/{ticker}_C_{lang}_{YYYY-MM-DD}.html References: html-template.md, color-system.md, docs/adr/0001-mode-c-rendering-strategy.ko.md


Instructions

Step 8.1 — Load Inputs

Load in this order:

  1. Read references/html-template.md — complete HTML skeleton with all 11 sections
  2. Read references/color-system.md — Tailwind CSS classes and Chart.js color configs
  3. Read run-local analysis-result.json — analysis output from Analyst Agent
  4. Verify all required sections are present in run-local analysis-result.json

Step 8.2 — Compute Data Confidence Indicator

From run-local analysis-result.json, count the data_quality_used grade distribution:

Grade A count: {N}
Grade B count: {N}
Grade C count: {N}
Grade D count: {N}

Overall:
- All critical metrics (price, revenue, net_income) Grade A → Overall A
- ≥6 of 10 key metrics Grade A or B → Overall B
- ≥4 of 10 key metrics Grade A, B, or C → Overall C
- Otherwise → Overall D (add warning banner)

Translate to Data Confidence Indicator text:

  • Grade A: Data Confidence: A — All key metrics independently verified
  • Grade B: Data Confidence: B — {N} of 10 key metrics cross-referenced
  • Grade C: Data Confidence: C — Limited source verification. Review with caution.
  • Grade D: Data Confidence: D — ⚠️ Insufficient verified data

Step 8.3 — Section-by-Section Population

Populate each section of html-template.md with data from analysis-result.json.

JSON field → HTML placeholder mapping:

analysis-result.json fieldHTML SectionPlaceholder
tickerSection 1{TICKER}
company_nameSection 1{COMPANY_NAME}
exchangeSection 1{EXCHANGE}
price_at_analysisSection 1, 3{CURRENT_PRICE}
price_day_changeSection 1{DAY_CHANGE}
price_day_change_pctSection 1{DAY_CHANGE_PCT}
data_modeSection 1badge class
analysis_dateSection 1{ANALYSIS_DATE}
key_metrics.market_capSection 3{MARKET_CAP}
key_metrics.pe_ratioSection 3{PE_RATIO}
key_metrics.ev_ebitdaSection 3{EV_EBITDA}
key_metrics.fcf_yieldSection 3{FCF_YIELD}
key_metrics.revenue_growth_yoySection 3{REV_GROWTH}
key_metrics.operating_marginSection 3{OP_MARGIN}
scenarios.bull.*Section 2bull card values
scenarios.base.*Section 2base card values
scenarios.bear.*Section 2bear card values
rr_scoreSection 2R/R badge
verdictSection 2verdict badge
sections.variant_view_q1Section 4Q1 text
sections.variant_view_q2Section 4Q2 text
sections.variant_view_q3Section 4Q3 text
sections.precision_risksSection 4risk table rows
sections.valuation_metricsSection 5valuation table
sections.sotpSection 5SOTP section
sections.dcf_analysisSection 5DCF subsection (after SOTP)
valuation_bridge (top-level)Section 5b{VALUATION_BRIDGE_SECTION} (4 anchors + weighted fair value + reconciliation paragraph)
sections.macro_contextSection 4/6Macro Environment section
sections.peer_comparisonSection 6peer table rows
output/runs/{run_id}/peers/*.json minimum collection_timestampSection 6{PEER_COLLECTED_AT_MIN}
output/runs/{run_id}/peers/*.json maximum collection_timestampSection 6{PEER_COLLECTED_AT_MAX}
sections.analyst_coverageSection 7analyst data
historical_pricesSection 8Chart 1 data array
income_statementsSection 8, 9Charts 2/3, quarterly table
sections.qoe_summarySection 9QoE section
sections.portfolio_strategySection 10strategy text
sections.what_would_make_me_wrongSection 10WWMMW list
upcoming_catalystsSection 10catalyst table

Step 8.4 — Chart.js Data Arrays

Convert structured data to Chart.js format:

Chart 1 — 12-Month Price History:

// From historical_prices array: [{date: "2025-03-12", close: 165.20}, ...]
const priceLabels = historical_prices.map(d => d.date);
const priceData = historical_prices.map(d => d.close);
// Apply color-system.md priceChart config

Chart 2 — Quarterly Revenue + Operating Income:

// From income_statements (last 8 quarters, oldest first)
const quarters = income_statements.slice(-8).map(q => q.period_label || q.period);
const revenueData = income_statements.slice(-8).map(q => q.revenue / 1000000); // in billions
const opIncomeData = income_statements.slice(-8).map(q => q.operating_income / 1000000);
// Apply color-system.md revenueBar and operatingIncomeBar configs

Chart 3 — Margin Trends:

// From income_statements (last 8 quarters)
const grossMarginData = income_statements.slice(-8).map(q =>
  q.gross_profit && q.revenue ? (q.gross_profit / q.revenue * 100).toFixed(1) : null
);
const opMarginData = income_statements.slice(-8).map(q =>
  q.operating_income && q.revenue ? (q.operating_income / q.revenue * 100).toFixed(1) : null
);
const netMarginData = income_statements.slice(-8).map(q =>
  q.net_income && q.revenue ? (q.net_income / q.revenue * 100).toFixed(1) : null
);
// Apply color-system.md grossMarginLine, operatingMarginLine, netMarginLine configs

If historical_prices unavailable (Standard Mode without price API): Replace Chart 1 canvas with a text table:

<div class="text-gray-400 text-sm italic p-4">
  Price chart data not available in Standard Mode. Use Enhanced Mode for historical price chart.
</div>

Step 8.5 — Apply Color System

From color-system.md:

R/R Score badge:

rr_score > 3.0 → class: "bg-emerald-900 text-emerald-300 border border-emerald-700"
rr_score 1.0–3.0 → class: "bg-yellow-900 text-yellow-300 border border-yellow-700"
rr_score < 1.0 → class: "bg-red-900 text-red-300 border border-red-700"

Price change colors:

day_change_pct > 0 → text-emerald-400, ▲
day_change_pct < 0 → text-red-400, ▼
day_change_pct = 0 → text-gray-400, —

Verdict badges:

Overweight / 비중확대 → bg-emerald-900 text-emerald-300
Underweight / 비중축소 → bg-red-900 text-red-300
Neutral / 중립 → bg-gray-700 text-gray-300
Watch / 관찰 → bg-blue-900 text-blue-300

Data confidence badge colors:

Grade A → bg-emerald-900 text-emerald-300
Grade B → bg-blue-900 text-blue-300
Grade C → bg-amber-900 text-amber-300
Grade D → bg-red-900 text-red-300

DCF Valuation Rendering (if sections.dcf_analysis exists)

Place AFTER the Valuation + SOTP section.

HTML structure:

  • Subsection heading: "DCF Valuation"
  • Base case highlight: large text showing "${fair_value} ({upside_pct}%)" with color (green/red based on sign)
  • Sensitivity table: HTML with WACC rows × terminal growth columns
    • Header row: terminal growth rates
    • Each cell: "${fair_value}" with color badge
    • Green: upside > 10%, Gray: -10% to +10%, Red: downside > 10%
  • Bull/Bear line: "Bull: ${X} (+Y%) | Bear: ${X} (-Y%)"
  • Methodology note: small text below showing WACC, terminal growth, forecast years
  • If dcf_analysis is absent or null: omit entire subsection

Valuation Bridge Rendering (if top-level valuation_bridge exists)

Place AFTER the DCF / Reverse DCF subsection and BEFORE the Peer Comparison section (Section 5b). The bridge reconciles 4 valuation anchors (DCF Base, Comp Multiples, Analyst Median Target, our Base Scenario) into a weighted fair value plus a ≥50-word reconciliation_logic paragraph.

Substitute the {VALUATION_BRIDGE_SECTION} placeholder in html-template.md with the full section markup shown in the Section 5b comment block when valuation_bridge is present in analysis-result.json. When the field is absent (older snapshots, or runs without all three input anchors), replace the placeholder with an empty string — do NOT render an empty stub.

Rendering rules:

  • 4 anchor cards in a md:grid-cols-4 grid; show value, weight × 100 as integer percentage, method, and source tag.
  • Implied view colour: text-red-600 if negative, text-green-600 if positive, text-gray-600 if ~0.
  • Pass reconciliation_logic through verbatim — do NOT truncate.
  • Display decision_anchor as a small footnote so the reader knows which anchor drives the verdict (typically scenarios.base).

Macro Context Rendering (if sections.macro_context exists)

Place BETWEEN Precision Risk and Peer Comparison sections.

HTML structure:

  • Section heading: "Macro Environment" with globe icon
  • If macro_context.structured.status == "available": render only the provided series[] values, with [Macro]/grade labels.
  • If macro_context.structured.status == "unavailable": show "Macro data unavailable" plus the reason, and do not render quantitative macro cards.
  • Narrative paragraph(s)
  • Factor cards (horizontally laid out, 2-3 cards):
    • Factor name (bold)
    • Impact line (normal text)
    • Confidence badge: High (green), Medium (amber), Low (gray)
  • If risk_slot_allocated is true: note with link to Precision Risk section
  • If macro_context is absent or null: omit entire section

Auto Delta Banner Rendering (Phase B — {DELTA_BANNER} placeholder)

The dashboard skeleton in references/html-template.md reserves a {DELTA_BANNER} placeholder at the top of <main>, above the Scenario Valuation section. This is the Mode C surface for Phase B Auto Delta Mode.

Substitution rules:

  1. If the orchestrator pipeline state holds auto_delta_payload.html (stdout of delta-comparator.py compare ... --format html), substitute that string verbatim.
  2. If no payload is available (no prior snapshot, --no-delta toggle, sanitization failure, or empty stdout), substitute the empty string. Do NOT render an empty stub, a fabricated banner, or the literal placeholder. Empty-string substitution leaves the surrounding space-y-8 layout intact because the banner is a peer of other <section> blocks.
  3. Never modify the Scenario Valuation, Hero, or Variant View sections to make room for the banner — the placeholder is positioned to keep the rest of the document untouched.
  4. The banner is a self-contained <section class="delta-banner ...">. Do not wrap it in another <section> or strip its outer element.

When pipeline_state.auto_delta == false (because --no-delta was passed), treat the placeholder substitution as the empty string and skip the delta-comparator call entirely.

Step 8.6 — Missing Data Handling

For any section where data is null or Grade D:

<!-- Instead of leaving empty or omitting: -->
<div class="text-gray-500 text-sm italic">[Data unavailable]</div>

Do NOT remove the section from the HTML. Do NOT substitute fabricated data. Always show the placeholder.

Sections with all-null data: collapse the section with a note:

<div class="bg-gray-800/50 border border-gray-700 rounded-lg p-4 text-gray-500 text-sm">
  Section data not available for this analysis. Data confidence insufficient.
</div>

Step 8.7 — Write HTML File

  1. Replace all placeholders with actual values
  2. Ensure Chart.js initialization code is complete with actual data arrays
  3. Verify HTML is well-formed (all tags closed)
  4. Write to: output/reports/{ticker}_C_{lang}_{YYYY-MM-DD}.html
  5. Report path to user

Do not use scripts/render-dashboard.py for final delivery or critic patch-loop rerenders. That script is eval-only. If a Mode C patch changes analysis-result.json, repopulate the full html-template.md manually/template-guided from the patched artifact and run the rendered output validator again before delivery.

Language suffixes: EN or KR Example: output/reports/AAPL_C_EN_2026-03-12.html


Multi-Ticker Mode B HTML Generation

When called for Mode B (comparison), use mode-b-template.md instead of html-template.md.

Path: output/reports/{T1}_{T2}_{T3}_B_{lang}_{YYYY-MM-DD}.html

Load each ticker's validated-data from the run-local artifact root, or from output/data/{ticker}/latest.json refs when explicitly reusing a fresh snapshot.


Completion Check

  • html-template.md loaded
  • color-system.md loaded
  • analysis-result.json loaded and all required fields present
  • Data Confidence Indicator computed
  • All 11 sections populated (or placeholder for missing)
  • Chart.js data arrays correctly formatted (labels array, datasets array)
  • R/R Score badge uses correct color class
  • Verdict badge uses correct color class
  • Missing data uses [Data unavailable] placeholder (NOT removed)
  • HTML written to correct path
  • File path reported to user

Signals

GitHub stars
2k
Forks
112
Last commit
Sep 2026
Advanced
Item type
skill
Key
dashboard-generator
Source
github.com/a5c-ai/babysitter