
Business Intelligence
Turn a JSON list of KPI definitions into a structured dashboard layout spec with chart types, filters, and recommended visualizations for an indie SaaS metrics stack.
Overview
business-intelligence is an agent skill for the Grow phase that generates dashboard layout specifications from KPI definition JSON via a Python CLI.
Install
npx skills add https://github.com/borghei/claude-skills --skill business-intelligenceWhat is this skill?
- CLI generator: dashboard_spec_generator.py reads KPI definitions JSON and emits layout specs
- Chart-selection rules map hints (trend, comparison, composition, distribution) to line, bar, donut, histogram, scorecard
- Supports layout flags such as 2-column and optional --json machine-readable output
- KPI schema covers name, type, aggregation, dimensions, time grain, targets, and chart_hint
- Produces titled dashboard packages suitable for handoff to BI or front-end chart libraries
- CHART_RULES categories include trend, comparison, composition, distribution, and kpi_card
- CLI supports --definitions, optional --title, --layout, and --json flags
Adoption & trust: 1.1k installs on skills.sh; 227 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You have KPIs listed in a spreadsheet or JSON but no consistent plan for charts, layout, and filters on a founder dashboard.
Who is it for?
Indie SaaS founders documenting metrics in JSON who want a repeatable spec before building analytics screens.
Skip if: Live warehouse querying, ETL pipeline design, or production observability alerting—the skill specs layouts, it does not ingest streaming data.
When should I use this skill?
You have a KPI definitions JSON file and need automated dashboard layout and chart-type recommendations.
What do I get? / Deliverables
You get a named dashboard spec with chart types, layout, and visualization notes per KPI, ready to implement in your BI or app UI.
- Structured dashboard specification with chart types and layout positions
- Optional JSON export for downstream implementation
Recommended Skills
Journey fit
Grow is where solo builders define what to measure and how to present revenue, funnel, and product KPIs after launch. Analytics is the right subphase because the artifact is a dashboard specification driven by KPI semantics—not generic frontend styling or infra monitoring.
How it compares
A KPI-to-dashboard spec generator, not a hosted BI product or SQL exploration skill.
Common Questions / FAQ
Who is business-intelligence for?
Solo builders and small teams in Grow who need a first-pass dashboard blueprint from structured KPI definitions.
When should I use business-intelligence?
After you have defined metrics (revenue, activation, retention) and before implementing charts in Grow/analytics or investor reporting views.
Is business-intelligence safe to install?
The script reads local definition files; review the Security Audits panel on this page and audit the Python source before running it on sensitive paths.
SKILL.md
READMESKILL.md - Business Intelligence
#!/usr/bin/env python3 """Generate dashboard layout specifications from KPI definitions. Reads a KPI definitions file and produces a structured dashboard specification with chart types, layout positions, filters, and recommended visualizations. Usage: python dashboard_spec_generator.py --definitions kpis.json python dashboard_spec_generator.py --definitions kpis.json --title "Sales Dashboard" --json python dashboard_spec_generator.py --definitions kpis.json --layout 2-column KPI definition format: [ { "name": "Monthly Revenue", "type": "currency", "aggregation": "sum", "dimensions": ["region", "product"], "time_grain": "monthly", "target": 100000, "chart_hint": "trend" } ] """ import argparse import json import os import sys from datetime import datetime # --------------------------------------------------------------------------- # Chart type selection logic # --------------------------------------------------------------------------- CHART_RULES = { "trend": {"chart": "line", "alt": "area", "reason": "Shows metric change over time"}, "comparison": {"chart": "bar", "alt": "column", "reason": "Compares values across categories"}, "composition": {"chart": "donut", "alt": "stacked_bar", "reason": "Shows parts of a whole"}, "distribution": {"chart": "histogram", "alt": "box_plot", "reason": "Shows data distribution"}, "kpi_card": {"chart": "scorecard", "alt": "gauge", "reason": "Highlights a single key metric"}, "table": {"chart": "data_table", "alt": "pivot_table", "reason": "Shows detailed records"}, "geographic": {"chart": "choropleth", "alt": "bubble_map", "reason": "Maps data geographically"}, } def _infer_chart_type(kpi: dict) -> str: """Infer best chart type from KPI definition.""" if kpi.get("chart_hint"): return kpi["chart_hint"] agg = kpi.get("aggregation", "sum") dims = kpi.get("dimensions", []) time_grain = kpi.get("time_grain") if time_grain and not dims: return "trend" if time_grain and dims: return "trend" # trend with dimension breakdown if len(dims) == 0: return "kpi_card" if len(dims) == 1: return "comparison" if any(d in ("region", "country", "state", "city") for d in dims): return "geographic" return "comparison" def _generate_widget(kpi: dict, position: int, layout: str) -> dict: chart_key = _infer_chart_type(kpi) chart_info = CHART_RULES.get(chart_key, CHART_RULES["kpi_card"]) # Calculate grid position if layout == "2-column": cols = 2 elif layout == "3-column": cols = 3 else: cols = 2 row = position // cols col = position % cols widget = { "id": f"widget_{position + 1}", "title": kpi["name"], "chart_type": chart_info["chart"], "alt_chart_type": chart_info["alt"], "chart_rationale": chart_info["reason"], "metric": { "name": kpi["name"], "aggregation": kpi.get("aggregation", "sum"), "type": kpi.get("type", "number"), }, "layout": { "row": row, "col": col, "width": 1, "height": 1, }, } if kpi.get("dimensions"): widget["dimensions"] = kpi["dimensions"] if kpi.get("time_grain"): widget["time_grain"] = kpi["time_grain"] if kpi.get("target") is not None: widget["target"] = kpi["target"] widget["show_target_line"] = True if kpi.get("filters"): widget["filters"] = kpi["filters"] return widget def generate_dashboard_spec(kpi_defs: list, title: str, layout: str) -> dict: widgets = [] # KPI cards come first (top row) kpi_cards = [] detail_widgets = [] for kpi in kpi_defs: chart_type = _infer_chart_type(kpi) if chart_type == "kpi_card": kpi_cards.append(kpi) else: