Skip to content
Back to skills

Source A697577186380e5516ecab61

ASecurity

Internal subskill for carta-reporting. Exports Carta report data to a branded Excel file. Invoked by carta-reporting or carta-reporting-markdown when the user requests Excel output. Also the entry point when the main skill receives a message starting with "Generate Carta Excel —" (the artifact prompt bar payload).

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentspythongobashapi

Works with

  • claude code
  • claude desktop
  • cli
  • api
  • mcp

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned November 7, 2026

npx -y skills add gutsofpratik/OpenClaude-Skills --skill source-a697577186380e5516ecab61 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Source A697577186380e5516ecab61?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Source A697577186380e5516ecab61
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gutsofpratik-source-a697577186380e5516ecab61/badge)](https://www.skillsdirectory.com/skills/gutsofpratik-source-a697577186380e5516ecab61)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: carta-reporting-excel
description: >-
  Internal subskill for carta-reporting. Exports Carta report data to a branded
  Excel file. Invoked by carta-reporting or carta-reporting-markdown when the user requests Excel output. Also the entry point
  when the main skill receives a message starting with "Generate Carta Excel —"
  (the artifact prompt bar payload).
model: sonnet
allowed-tools:
  - mcp__carta__call_tool
  - mcp__carta__read_tool
  - mcp__claude_ai_Carta__call_tool
  - mcp__claude_ai_Carta__read_tool
  - mcp__2827383e-1775-4df3-b6ff-04d5392f6d18__call_tool
  - mcp__2827383e-1775-4df3-b6ff-04d5392f6d18__read_tool
  - Bash(find * -name "report_processor.py"*)
  - Bash(find ~ -name "report_processor.py"*)
  - Bash(find * -name "excel_exporter.py"*)
  - Bash(find ~ -name "excel_exporter.py"*)
  - Bash(UV_PYTHON_DOWNLOADS=never uv run*)
---

<!-- carta:plugin-version -->
<carta-plugin>carta-cap-table:6.96.0</carta-plugin>

# Excel Export

**Context expected from the calling skill (must be in session before this skill is invoked):**
- `user_report_pk` — needed to check for the cached report file and to fetch a fresh download URL if the file is absent
- `corporation_id` — needed for `read_tool({"name": "reporting__get__download_url", ...})`
- Column config — either parsed from the artifact prompt bar payload (Claude Desktop) or confirmed during the Customization Checkpoint in `carta-reporting-markdown` (Claude Code)
- Corporation legal name, `as_of_date`, user full name — used as `--title`, `--as-of-date`, `--generated-by` args to `excel_exporter.py`

## Column source (Claude Desktop — artifact prompt bar)

When the user pastes an **artifact prompt bar payload**, it arrives as a complete instruction starting with `Generate Carta Excel —`:

```
Generate Carta Excel —
Corporation: Meetly, Inc. (ID: 7)
Columns:
  Equity Grants: columns: Grant ID, Award Type, Exercise Price; sorted by: Grant Date desc
  Vesting Schedule: columns: Grant ID, Vest Date, Shares Vested; totals: Shares Vested sum
```

Use the `Corporation:` line to confirm which company the export is for. Each indented line under `Columns:` is one sheet tab. This is always **one Excel file** with one tab per sheet. Parse each sheet line and pass all sheets to `report_processor.py` in a single run using the per-sheet `sheets` dict format. No further questions needed.

**The column list from the artifact is authoritative; do not merge with or override it from the earlier conversation.**

**Parsing segment fields into `report_processor.py` config:**

| Prompt bar field | `report_processor.py` per-sheet key |
|---|---|
| `columns: A, B, C` | `"columns": ["A", "B", "C"]` |
| `sorted by: Col asc` | `"sort": [{"column": "Col", "direction": "asc"}]` |
| `totals: Col sum, Col2 avg` | `"aggregations": {"type": "summary", "columns": {"Col": "sum", "Col2": "avg"}}` |

**`totals:` must become `aggregations`** — this is the only way Excel formulas (`=SUM(...)`, `=AVERAGE(...)`) are generated. If `aggregations` is omitted, any total rows in the output are hardcoded API values, not live formulas.

If the user asks for Excel without pasting a payload, ask: "Click the **Excel export** bar at the bottom of the artifact to select it, copy and paste it here — I'll generate the Excel with exactly those columns."

**No scope context on this path.** Entering fresh from the prompt bar, this skill cannot know
whether the account is share-class-scoped, so it cannot label a percentage column for the scope or
name the in-scope classes — the same limitation as `label_overrides`. The numbers are correct and
already scoped; only the labelling is generic. Do not describe any total as company-wide.

## Column source (Claude Code)

Use the column list confirmed during the Customization Checkpoint (resolved in `carta-reporting-markdown`).

## Running the export

Check if `/tmp/carta_report_<user_report_pk>.json` is available (use `user_report_pk` from this session):
- **File ready** → pass it as `"local_file"` to `report_processor.py`.
- **Not ready** → call `read_tool({"name": "reporting__get__download_url", "arguments": { user_report_pk, corporation_id }})` to get a fresh presigned URL and pass it as `"download_url"` instead.

**Always pipe through `report_processor.py` → `excel_exporter.py`, regardless of data size or complexity.** Never write Excel files directly with openpyxl or any other library — the scripts handle Carta branding (logo, header, fonts, number formats) that will be missing from any ad-hoc implementation. This applies even when the dataset is small (e.g. 3 rows) or when sheets need to be combined.

For combining sheets into one tab, use `merge_sheets` in the `report_processor.py` call.

Pass all sheets in one run using the `sheets` dict. Pipe into `excel_exporter.py`. Reuse the cached `_report_processor_path` if the parent session resolved it (it may be unset on the fresh `Generate Carta Excel —` prompt-bar path — the `find` fallback handles that):

```bash
UV_PYTHON_DOWNLOADS=never uv run "${_report_processor_path:-$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)}" <<'EOF' | \
    UV_PYTHON_DOWNLOADS=never uv run "$(find ~ -name "excel_exporter.py" -path "*/carta-reporting-excel/scripts/*" 2>/dev/null | head -1)" \
        --title "Securities Ledger Report" \
        --as-of-date 2024-01-15 \
        --generated-by "Jane Doe" \
        --output ./{report-slug}.xlsx
{
  "local_file": "<path or use download_url if file not ready>",
  "sheets": {
    "Equity Grants":    {"columns": ["Grant ID", "Award Type", "Exercise Price"],
                         "aggregations": {"type": "summary", "columns": {"Exercise Price": "sum"}}},
    "Vesting Schedule": {"columns": ["Grant ID", "Vest Date", "Shares Vested"],
                         "sort": [{"column": "Vest Date", "direction": "asc"}]}
  }
}
EOF
```

The script prints the absolute output path on success. Present it as a clickable link: `computer://<absolute-path>` (e.g. `computer:///Users/jane/meetly-equity-grants.xlsx`). Tell the user their file is ready to open, then offer next steps:

- **Run another report** — for a different company or report type
- **Customize this export** — adjust filters, columns, or formulas
- **Change the date range or filters** — re-run with different parameters

## Carta Excel Formatting Conventions

| Element | Value |
|---|---|
| Header background | `#c6ebf4` |
| Header font | Arial 12pt bold, `#2f3943` |
| Logo | `<skill_base_dir>/assets/Carta_Logo.png`, cell A2, 120×50px |
| Title | Cell B2, Arial 16pt bold |
| Subtitle | Cell B3, Arial 10pt, `#666666` — `"As of MMM d, yyyy • Generated with Claude AI by {user} at MMM d, yyyy h:mm:ss AM/PM TZ • Date format: MMM D, YYYY"` |
| Header row | Row 5 with auto-filter; freeze panes at A6; data starts at row 6 |

Column type → number format: `money` → `$#,##0.00` · `percentage` → `0.00%` · `integer` → `#,##0` · `date` → `mmm d, yyyy` · `decimal` → `#,##0.0000`

Column widths: string/date → **35**, number types → **18**.

Files in this skill

  • PROVENANCE.json215 B
  • SKILL.md7 KB
  • UPSTREAM-LICENSE.txt11 KB
  • assets/Carta_Logo.png5.2 KB
  • scripts/excel_exporter.py11.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.