--- name: create-sheet description: Use this skill when the user wants to create, draft, build, or generate a new spreadsheet, financial model, budget, forecast, dashboard, tracker, or register in this open-sheet workspace. Triggers on phrases like "build me a budget model", "make a spreadsheet for X", "draft an FY26 forecast", "put this data in a workbook", or when the user asks to add something under `sheets/`. Do NOT use for editing the framework itself — only for authoring content inside `sheets//`. --- # Create a workbook in open-sheet This skill owns the **workflow**. The technical reference — file contract, components, references, formats — lives in the **`sheet-authoring`** skill. Read it before writing code; do not duplicate its rules here. You only write files under `sheets//`. Never modify `package.json`, `open-sheet.config.ts`, or an existing workbook unless asked. ## Step 0 — Pick a theme List `themes/`. If any theme markdown exists, offer each theme id via `AskUserQuestion` plus a final **"no theme — design from scratch"** option. If the user picks one, read `themes/.md` end to end, copy its palette and components, and set `meta.theme`. ## Step 1 — Get the numbers before anything else A spreadsheet is judged entirely on whether its numbers are right. Before structure, before layout, establish: - **Purpose** — what decision does this workbook support? A budget to approve, a forecast to argue with, a register to maintain? - **Audience** — a CFO wants assumptions they can change; an analyst wants the working; an ops team wants a list they can filter. - **The data** — where does it come from? Ask for the file, the query, the figures. If the user has none yet, build the structure and leave explicit `TODO:` markers. > **Never invent a figure.** Not a revenue number, not a growth rate, not a > headcount, not a "typical industry" benchmark. A fabricated number in a > spreadsheet is indistinguishable from a real one — it will be formatted, > totalled, and charted exactly like the truth, and someone will make a decision > on it. This matters more here than in a slide deck or a report. > > If you need a placeholder to demonstrate structure, make it obviously fake > (`0`, or `1` with a `` saying so) and tell the user. ## Step 2 — Clarify the shape (ask before writing code) One `AskUserQuestion` call, skipping anything the user has already settled: 1. **Workbook type** — propose three that fit *this* request, with what each implies structurally: - *"our FY26 numbers"* → **driver model** (assumptions sheet drives a P&L) · **budget vs actual** (variance columns and a data bar) · **exec summary** (one sheet, KPI band, no working shown) - *"track our vendors"* → **register** (one row per vendor, filterable) · **spend analysis** (grouped totals, top-N) · **scorecard** (weighted criteria) 2. **Assumptions** — which numbers should the reader be able to change? This is the question that decides whether the export is a model or a picture. 3. **Sheets** — one sheet or several? Assumptions separate from calculations is the default and should only be collapsed for a genuinely trivial workbook. 4. **Output** — is this opened in Excel (the usual case), printed as a report, or read as a dashboard? It changes formats, widths, and whether to add a `--html` pass. ## Step 3 — Pick an id **kebab-case**, short, descriptive: `fy26-budget`, `vendor-register`, `unit-economics`. Check `sheets/` for collisions. ## Step 4 — Plan the sheets before writing One line per sheet, with its role. Typical shapes: | Type | Sheets | | --- | --- | | Driver model | Assumptions · P&L · (Cash flow) · (Summary) | | Budget vs actual | Assumptions · Budget · Actual · Variance | | Register | Data · (Lookups) · (Summary) | | Dashboard | Assumptions · Data · Dashboard | Rules: - **Assumptions get their own sheet**, as a `kind="keyValue"` table. Every key becomes an Excel defined name, so exported formulas read `=B5*growth`. - Calculations reference assumptions. A rate written inside a formula is a rate the reader cannot change. - The reverse is also true: **an assumption that drives nothing is noise.** If you add a key and no formula references it, either wire it up or drop it — a reader who changes it and sees nothing move learns not to trust the sheet. - A KPI band belongs at the top of the sheet a reader opens first. Show the plan before writing if it runs past three sheets. ## Step 5 — Write `sheets//index.tsx` Read **`sheet-authoring`** first. While writing: - Structure in JSX, rows in a plain TypeScript array - Every computed column uses `formula`, never a value pre-computed in `data` — a pre-computed value exports as a dead number - Guard `r.prev()` / `r.next()` with `r.isFirst` / `r.isLast` - Set a `format` on every numeric column - `bar: true` where a reader compares magnitudes down a column - No cell addresses. None. ## Step 6 — Check it Look at the viewer, and: - [ ] Do the totals match what you would get by hand? - [ ] Is anything showing `#NOT_EVALUATED` that should not be? - [ ] Change an assumption in the viewer's source and confirm the dependent numbers move. If they do not, something is a literal that should be a formula. - [ ] Run the self-review checklist in `sheet-authoring`. Then tell the user what you assumed and what you left as `TODO`.