Exec Report
Generates a complete, self-contained HTML report by (1) interviewing the user or parsing their data, (2) constructing and validating a JSON document, then (3) rendering that JSON into HTML using assets/report-template.html. The JSON is the authoritative source of truth; the HTML is fully determined by it.
Step 1: Determine the Data Source
Check what the user has already provided before asking anything:
- SharePoint lists: Call
list_items on the relevant lists. Read all needed columns before proceeding.
- CSV or table pasted in chat: Parse all rows. Do not ask for data you already have.
- Verbal description only: Proceed to Step 2.
Step 2: Interview the User
If the data or intent is not fully clear, ask these questions in a single message — not one at a time:
- Topic: What is this report about? (e.g., "Q2 pipeline health," "IT project status," "department spend overview")
- Audience: Who is reading it? Exec team, department head, all-hands? This determines detail level.
- Narrative intent: What is the shape of the story? Pick the closest match:
- Achievement — "we hit a goal, here's how" (lead with the win: kpi-row + trend dominate)
- Problem — "something needs attention, here's what" (lead with urgency: status-grid or table comes first)
- Status — "here's where everything stands" (balanced overview: status-grid early, kpi-row supporting)
- Headline message: What should the reader walk away knowing? This becomes the hero sentence — one sentence.
- Sections wanted: Any specific sections — comparison to prior period, breakdown by category, status of open items, narrative highlights?
- Palette: Warm paper (cream/terra-cotta), deep ink (dark/gold), clean white (white/green), or slate (gray/blue)? Default to warm paper if no preference.
If the user's prompt already signals narrative intent (e.g., "the headline is the gap," "lead with urgency," "show the wins"), skip question 3 — you already have the answer.
Confirm your understanding before building the JSON.
Step 3: Choose Components and Narrative Order
The component sequence IS the story. Read references/components.md for the full component catalog, props schemas, and HTML patterns.
Always true:
- Open with
hero — sets the company, label, and hero sentence.
- Close with
highlights — narrative "so what" belongs last.
- Maximum one
trend, one table, and one highlights per report.
- Keep total block count to 4–8.
Narrative intent drives the block order:
| Intent |
Typical sequence |
Hero sentence shape |
| Achievement |
hero → kpi-row → trend → bar-list → compare → status-grid → highlights |
"We closed $X, up Y% from last quarter." |
| Problem |
hero → status-grid → compare → table → bar-list → highlights |
"We enter Q3 with X open roles and a gap in Y." |
| Status |
hero → status-grid → kpi-row → compare → bar-list → highlights |
"Here's where all six workstreams stand heading into Q3." |
The hero sentence signals intent to the reader. Achievement heroes lead with a number and a direction. Problem heroes lead with a situation. Status heroes lead with a scope statement.
Component selection guide:
| Data shape |
Component |
| 2–4 headline numbers worth celebrating or tracking |
kpi-row |
| Values over time (3+ periods) |
trend |
| Category breakdown with relative sizes |
bar-list |
| Structured numeric comparison (QoQ, YoY, plan vs. actual) |
compare |
| Detailed row data (5+ items with 3+ fields) |
table |
| Health or urgency status of multiple items |
status-grid |
| Narrative insights: bright spots, risks, actions |
highlights |
Hard rules:
- Never put a headline number in prose when
kpi-row can show it larger.
- Never use
table for 2–4 numbers — use kpi-row.
kpi-row is not mandatory — omit it when the story is problem- or urgency-forward and metrics are supporting context, not the lead.
Step 4: Build and Validate the JSON Document
Construct the JSON object. Top-level structure:
report object (document metadata):
| Field |
Required |
Description |
palette |
yes |
warm-paper, deep-ink, clean-white, or slate |
footer_l |
no |
Left footer text, e.g. "Generated May 28, 2026" |
footer_r |
no |
Right footer text, e.g. "47 deals analyzed" |
blocks array — ordered list of content blocks. Each block: type string + props object. See references/components.md for every component's full props schema.
Validation Checklist
Run every check before rendering. Fix any failure before proceeding.
Document level:
Per block:
Data integrity:
Step 5: Render the HTML
- Read
assets/report-template.html.
- Replace
{{REPORT_TITLE}} in <title> with a concise page title (company + report label).
- Replace
{{PALETTE_CLASS}} on <body> with palette- + the palette name (e.g. palette-warm-paper).
- Generate the
hero block HTML (.rpt-header + .hero) and replace {{HERO}}.
- Generate all remaining blocks in order and replace
{{BLOCKS}}.
- Replace
{{FOOTER_L}} and {{FOOTER_R}} with footer text (or empty strings).
- Generate the
{{INLINE_SCRIPT}} content. Include:
- Segment bar fill-in code (if any
bar-list blocks are present)
- Trend tooltip JS with embedded
TREND_DATA array (if a trend block is present)
- See the template's script comment block for the exact code patterns to use.
- Deliver the complete file as the response. No prose outside the file.
If the site context specifies a folder for report output, save the file there after delivering it.
Hard Constraints
- No external URLs, CDN links, or web fonts in the output HTML.
- No
<script src> tags. All JavaScript must be inline.
- All data values must be pre-rendered into the HTML — the page must be fully correct with JavaScript disabled. JS adds animations and tooltips but must never be required for correctness.
- Do not generate Python, PowerShell, or any other scripts — output is always the HTML file.
- Do not render until the validation checklist passes.
- Follow the no-Person-column-type rule for any accompanying SharePoint schema: use text columns only.
1---2name: exec-report3description: Generates a polished, self-contained HTML executive report or dashboard from any data source — SharePoint lists, CSV exports, or a user description. Use when asked to build an exec report, one-pager, summary page, status dashboard, project summary, business review, or any single-page visual summary of data. Interviews the user if data is incomplete, constructs a validated JSON document block by block, then renders it into a single sandbox-safe HTML file using the component library. No external dependencies — output runs inside a SharePoint sandboxed iframe.4---56# Exec Report78Generates a complete, self-contained HTML report by (1) interviewing the user or parsing their data, (2) constructing and validating a JSON document, then (3) rendering that JSON into HTML using `assets/report-template.html`. The JSON is the authoritative source of truth; the HTML is fully determined by it.910---1112## Step 1: Determine the Data Source1314Check what the user has already provided before asking anything:1516- **SharePoint lists**: Call `list_items` on the relevant lists. Read all needed columns before proceeding.17- **CSV or table pasted in chat**: Parse all rows. Do not ask for data you already have.18- **Verbal description only**: Proceed to Step 2.1920---2122## Step 2: Interview the User2324If the data or intent is not fully clear, ask these questions in a single message — not one at a time:25261. **Topic**: What is this report about? (e.g., "Q2 pipeline health," "IT project status," "department spend overview")272. **Audience**: Who is reading it? Exec team, department head, all-hands? This determines detail level.283. **Narrative intent**: What is the *shape* of the story? Pick the closest match:29 - **Achievement** — "we hit a goal, here's how" (lead with the win: kpi-row + trend dominate)30 - **Problem** — "something needs attention, here's what" (lead with urgency: status-grid or table comes first)31 - **Status** — "here's where everything stands" (balanced overview: status-grid early, kpi-row supporting)324. **Headline message**: What should the reader walk away knowing? This becomes the hero sentence — one sentence.335. **Sections wanted**: Any specific sections — comparison to prior period, breakdown by category, status of open items, narrative highlights?346. **Palette**: Warm paper (cream/terra-cotta), deep ink (dark/gold), clean white (white/green), or slate (gray/blue)? Default to warm paper if no preference.3536If the user's prompt already signals narrative intent (e.g., "the headline is the gap," "lead with urgency," "show the wins"), skip question 3 — you already have the answer.3738Confirm your understanding before building the JSON.3940---4142## Step 3: Choose Components and Narrative Order4344The component sequence IS the story. Read `references/components.md` for the full component catalog, props schemas, and HTML patterns.4546**Always true:**47- Open with `hero` — sets the company, label, and hero sentence.48- Close with `highlights` — narrative "so what" belongs last.49- Maximum one `trend`, one `table`, and one `highlights` per report.50- Keep total block count to 4–8.5152**Narrative intent drives the block order:**5354| Intent | Typical sequence | Hero sentence shape |55|---|---|---|56| **Achievement** | hero → kpi-row → trend → bar-list → compare → status-grid → highlights | "We closed $X, up Y% from last quarter." |57| **Problem** | hero → status-grid → compare → table → bar-list → highlights | "We enter Q3 with X open roles and a gap in Y." |58| **Status** | hero → status-grid → kpi-row → compare → bar-list → highlights | "Here's where all six workstreams stand heading into Q3." |5960The hero sentence signals intent to the reader. Achievement heroes lead with a number and a direction. Problem heroes lead with a situation. Status heroes lead with a scope statement.6162**Component selection guide:**6364| Data shape | Component |65|---|---|66| 2–4 headline numbers worth celebrating or tracking | `kpi-row` |67| Values over time (3+ periods) | `trend` |68| Category breakdown with relative sizes | `bar-list` |69| Structured numeric comparison (QoQ, YoY, plan vs. actual) | `compare` |70| Detailed row data (5+ items with 3+ fields) | `table` |71| Health or urgency status of multiple items | `status-grid` |72| Narrative insights: bright spots, risks, actions | `highlights` |7374**Hard rules:**75- Never put a headline number in prose when `kpi-row` can show it larger.76- Never use `table` for 2–4 numbers — use `kpi-row`.77- `kpi-row` is not mandatory — omit it when the story is problem- or urgency-forward and metrics are supporting context, not the lead.7879---8081## Step 4: Build and Validate the JSON Document8283Construct the JSON object. Top-level structure:8485**`report` object** (document metadata):8687| Field | Required | Description |88|---|---|---|89| `palette` | yes | `warm-paper`, `deep-ink`, `clean-white`, or `slate` |90| `footer_l` | no | Left footer text, e.g. `"Generated May 28, 2026"` |91| `footer_r` | no | Right footer text, e.g. `"47 deals analyzed"` |9293**`blocks` array** — ordered list of content blocks. Each block: `type` string + `props` object. See `references/components.md` for every component's full props schema.9495### Validation Checklist9697Run every check before rendering. Fix any failure before proceeding.9899**Document level:**100- [ ] `report.palette` is one of: `warm-paper`, `deep-ink`, `clean-white`, `slate`101- [ ] `blocks` array has at least one entry102- [ ] First block `type` is `hero`103- [ ] Last block `type` is `highlights`104- [ ] Block order reflects the declared narrative intent (achievement / problem / status)105106**Per block:**107- [ ] `type` is one of: `hero`, `kpi-row`, `trend`, `bar-list`, `compare`, `table`, `status-grid`, `highlights`108- [ ] All required props are present (see components.md)109- [ ] Numeric values are numbers, not strings with embedded units110- [ ] No block exceeds its item count limits (see components.md limits table)111112**Data integrity:**113- [ ] `kpi-row` items count is 2–4114- [ ] `bar-list` shares: largest item = 1.0, all others ≤ 1.0115- [ ] `trend` data and labels arrays have the same length (3–12)116- [ ] `trend` prior_data (if present) same length as data117- [ ] `compare` rows have `dir` set to `"up"` or `"down"` on every row118- [ ] `table` headers count matches every row's cell count119- [ ] `highlights` items count is 3–5120121---122123## Step 5: Render the HTML1241251. Read `assets/report-template.html`.1262. Replace `{{REPORT_TITLE}}` in `<title>` with a concise page title (company + report label).1273. Replace `{{PALETTE_CLASS}}` on `<body>` with `palette-` + the palette name (e.g. `palette-warm-paper`).1284. Generate the `hero` block HTML (`.rpt-header` + `.hero`) and replace `{{HERO}}`.1295. Generate all remaining blocks in order and replace `{{BLOCKS}}`.1306. Replace `{{FOOTER_L}}` and `{{FOOTER_R}}` with footer text (or empty strings).1317. Generate the `{{INLINE_SCRIPT}}` content. Include:132 - Segment bar fill-in code (if any `bar-list` blocks are present)133 - Trend tooltip JS with embedded `TREND_DATA` array (if a `trend` block is present)134 - See the template's script comment block for the exact code patterns to use.1358. Deliver the complete file as the response. No prose outside the file.136137If the site context specifies a folder for report output, save the file there after delivering it.138139---140141## Hard Constraints142143- No external URLs, CDN links, or web fonts in the output HTML.144- No `<script src>` tags. All JavaScript must be inline.145- All data values must be pre-rendered into the HTML — the page must be fully correct with JavaScript disabled. JS adds animations and tooltips but must never be required for correctness.146- Do not generate Python, PowerShell, or any other scripts — output is always the HTML file.147- Do not render until the validation checklist passes.148- Follow the no-Person-column-type rule for any accompanying SharePoint schema: use text columns only.