Power Bi Build
Build IPPF-branded Power BI artefacts from analytical input. Use when Ane asks to build, scaffold, or update a Power BI dashboard, semantic model, DAX measures, or .pbip project. Applies IPPF Visual Identity 2025 brand, MEL-standard DAX measures, and three standard page recipes (indicator dashboard, equity disaggregation, methodology card). Requires the pbi CLI (pbi-cli-tool, command name `pbi`) installed and Power BI Desktop running with a .pbip open.
- Skill ID
- gasserane/personal-skills/power-bi-build
- Publisher
- gasserane
- Repository
- personal-skills
- Installs
- 0
- Files
- 2
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
gasserane/personal-skills/power-bi-buildInstalls these files- CHANGELOG.md
- SKILL.md
What this skill tells the agent
/power-bi-build
Build IPPF-branded Power BI artefacts. v1 scope: writes DAX measures into the semantic model via the pbi CLI; writes the IPPF theme JSON into the .pbip folder directly; saves page recipes (indicator dashboard, equity, methodology) as JSON staging artefacts the user applies manually in Power BI Desktop. Full page-and-visual automation is v2.
Tooling reality
The pbi CLI (package pbi-cli-tool, command name pbi) wraps a Power BI MCP server for semantic model operations only:
- ✅
pbi measure create— add DAX measures. - ✅
pbi table,pbi column,pbi relationship— model structure. - ✅
pbi dax— execute and validate DAX. - ❌ No
pbi themecommand. Theme JSON is written directly to the.pbipfolder. - ❌ No
pbi pageorpbi visualcommand. Pages and visuals are created manually in Power BI Desktop using the staging recipe JSONs as a guide.
When the upstream tool adds report-layer commands, this skill will absorb them. v1 ships with the scope above.
Two routes. The v1 flow below (pbi CLI for measures + theme + staged page recipes) suits an existing model the user keeps building by hand. When the source is an Excel workbook and the user wants a complete, working dashboard handed over (data loaded, measures, theme, and report pages all built), use the full `.pbip` authoring route in the dedicated section below instead. That route was validated end-to-end (CERV Portfolio Dashboard, 2026-06-20).
Pre-flight
Run these checks in order. Stop with the indicated message on first failure.
- `pbi` installed.
- Run:
pipx list | grep pbi-cli-tool. - If empty: stop. Show: "pbi CLI is not installed. Run:
pipx install pbi-cli-tool && pipx ensurepath && pbi skills install. Open a fresh shell so PATH updates pick up."
- Power BI Desktop running with an active project, connection named.
- Run
pbi connect(bare) once to read the port from the "Auto-detected Power BI Desktop on localhost:<port>" line. Disconnect:pbi disconnect. - Re-connect with an explicit name matching the MCP server's internal label:
pbi connect -d localhost:<port> -n PBIDesktop-<pbip-basename>-<port>. The model-derived name is required — pbi-cli's default save-namelocalhost-<port>is rejected by the MCP server's measure/table operations with"Connection 'localhost-<port>' not found". - If
pbi connectreports no active project: stop. Show: "Open Power BI Desktop and load a.pbipproject, then re-run." - If the Analysis Services port shifts mid-session (Power BI Desktop sometimes restarts the engine on file reopen, Model-view switch, etc.), re-run this step with the new port.
- Active project is `.pbip` (text-format), not legacy `.pbix` binary.
- The
pbi connectoutput includes the project path. If it ends in.pbix: stop. Show: "Save your project as.pbipfirst — File → Save as → set Save as type to Power BI Project. The skill operates on the text-based PBIP format only."
- Brand layer importable.
- Verify
${WORK_FOLDER_ROOT}/ane_package/reporting/powerbi_dashboard/__init__.pyexists. - If missing: stop. Show: "Brand layer not found at
${WORK_FOLDER_ROOT}/ane_package/reporting/powerbi_dashboard/. Verify OneDrive sync."
Resolve intent
From the prompt and the most recent analytical artefact in this session, resolve:
- Indicators — keys from
MEL_DAX_LIBRARY. If ambiguous, ask Ane: "Which indicators? Available: {sorted(MEL_DAX_LIBRARY.keys())}". - Audience tier — Tier 1 working brief by default; Tier 2 publication only if the prompt names it.
- Page set — default
(indicator_dashboard, equity_disaggregation, methodology_card)per indicator. - Source line — derive from prior artefact; if absent, ask once.
- Staging directory — default
${PWD}/powerbi-build-output/. Holds theme.json, measures.json, and page recipes for the run.
Build (Python — produces all artefacts in memory)
import json
from pathlib import Path
from ane_package.reporting.powerbi_dashboard import (
MEL_DAX_LIBRARY,
build_equity_disaggregation_page,
build_indicator_dashboard_page,
build_ippf_theme,
build_methodology_card_page,
)
theme = build_ippf_theme()
measures = {k: MEL_DAX_LIBRARY[k] for k in selected_indicators}
pages = []
for indicator in selected_indicators:
pages.append(build_indicator_dashboard_page(indicator, target, source))
pages.append(build_equity_disaggregation_page(
indicator, ("age", "gender", "geography", "wgss_disability"), source))
pages.append(build_methodology_card_page(method_note, evidence_base_sources, glossary_terms))
staging = Path("powerbi-build-output")
staging.mkdir(exist_ok=True)
(staging / "theme.json").write_text(json.dumps(theme, indent=2))
(staging / "measures.json").write_text(json.dumps(measures, indent=2))
for i, page in enumerate(pages):
(staging / f"page_{page['page_id']}.json").write_text(json.dumps(page, indent=2))Apply
1. DAX measures via pbi measure create
For each measure, infer the table from the DAX expression's [bracketed] references (heuristic: first Table[Column] reference in the expression, or _Measures if the expression only references other measures).
pbi measure create <measure-key> \
--table <inferred-table> \
--expression "<dax-expression>"The measure name is positional (NOT a --name flag). Verified against pbi-cli-tool 0.5.6.
Surface any error verbatim. Never retry — pbi failures usually mean the table or column referenced does not exist in the model. pbi-cli rolls back the transaction on any "table not found"; the measure does NOT land with a red icon (contrary to older Power BI behaviour). Either pre-seed a stub table or correct the DAX before retry.
1a. Save discipline — mandatory after EACH pbi model write
Tell Ane to switch to Power BI Desktop and press Ctrl+S immediately after each pbi table / pbi measure / pbi column / pbi relationship write. External pbi writes are held in the Analysis Services engine's memory only; the .pbip on disk is updated by Power BI Desktop on File → Save. If the engine restarts before save (port shift, file reopen, sometimes Model-view switch), the writes are lost.
2. Theme JSON — direct write into the .pbip folder
The .pbip is a text-format project. The theme JSON goes into the report folder as a custom theme. Path layout (Power BI Desktop 2.140+):
<project>.pbip
<project>.Report/
StaticResources/
SharedResources/
BaseThemes/
ippf-visual-identity-2025.json ← write theme here
RegisteredResources/
ippf-visual-identity-2025.json ← also write here
definition/
report.json ← register the theme (see below)Write the theme JSON to both paths. Then update report.json to register it (Power BI Desktop reads the theme name from report.json metadata; without registration the theme appears in the Themes gallery but does not auto-apply).
If the user has not enabled the PBIP report-format preview in Power BI Desktop (File → Options → Preview features → Power BI Project (.pbip) source control), the theme path may differ. Surface a clear message if <project>.Report/ does not exist.
Cache-bust on retry. Power BI Desktop caches a registered theme by filename across failed imports — re-importing the same filename re-shows old validation errors even after the file is fixed. On any retry after a validation failure, write the new theme JSON under a versioned name (ippf-visual-identity-2025-v2.json, -v3, etc.) so Power BI parses it as new.
3. Page recipes — staging only in v1
Save each page recipe to the staging directory as JSON. Do NOT attempt to write PBIR page files into the .pbip folder in v1 (PBIR format is still in preview and the schema is unstable).
More from gasserane
Use this skill in a project
Open any RiverX project, search the Skills panel for gasserane/personal-skills/power-bi-build, and install it in one click.
