Carta レポート用の内部サブスキルです。Carta レポートのデータをブランド化(企業のロゴやデザインを施した)Excel ファイルにエクスポート(データを別形式に変換して出力)します。 以下の場合に実行されます: - ユーザーが Excel 形式での出力をリクエストした時に、carta-reporting または carta-reporting-markdown スキルから呼び出される - メインスキルが「Generate Carta Excel —」で始まるメッセージを受け取った時(アーティファクト(生成結果の表示領域)のプロンプトバーから送信されたペイロード(データ)の場合)
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).
スキル呼び出し時に必要な前提情報(セッションに存在していること):
user_report_pk — キャッシュされたレポートファイルの確認と、ファイルがない場合の新しいダウンロードURLの取得に必要corporation_id — read_tool({"name": "reporting__get__download_url", ...}) の実行に必要carta-reporting-markdown の「カスタマイズチェックポイント」で確認(Claude Code)as_of_date(基準日)、ユーザーのフルネーム — excel_exporter.py の --title、--as-of-date、--generated-by 引数として使用ユーザーがアーティファクトプロンプトバーのペイロードを貼り付けると、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
Corporation: の行でエクスポート対象の会社を確認してください。Columns: の下のインデントされた行がそれぞれExcelのシートタブです。これは常に1つのExcelファイルで、シートごとに1つのタブです。各シート行を解析し、シート ごとの sheets 辞書形式を使用してすべてのシートを report_processor.py に一度に渡します。追加の確認は不要です。
アーティファクトの列リストが確定版です。過去の会話と統合したり上書きしたりしないでください。
プロンプトバーのフィールドを report_processor.py の設定にパース:
| プロンプトバーのフィールド | report_processor.py シート単位のキー |
|---|---|
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: は必ず aggregations に変換してください — これが Excel の数式(=SUM(...)、=AVERAGE(...))を生成する唯一の方法です。aggregations を省略すると、出力の合計行はAPI の値がハードコーディングされ、ライブ数式にはなりません。
ユーザーがペイロードなしで Excel をリクエストした場合は、次のように聞いてください: 「アーティファクトの下部にあるExcel エクスポートバーをクリックして選択し、ここにコピー&ペーストしてください。正確な列でExcelを生成します。」
このパスではスコープのコンテキストはありません。 プロンプトバーから新規に開始する場合、このスキルはアカウントが「種類別株式スコープ」(特定の株式種類に限定した表示)かどうかを知ることができないため、スコープ対象の割合列にラベル付けしたり、対象範囲内のクラスに名前を付けたりすることはできません。これは label_overrides と同じ制限です。数値は正確で既にスコープ適用済みです。ラベル付けのみ汎用です。合計をカンパニー全体のものとして説明しないでください。
「カスタマイズチェックポイント」で確認された列リストを使用します(carta-reporting-markdown で解決)。
/tmp/carta_report_<user_report_pk>.json が利用可能かどうか確認します(このセッションの user_report_pk を使用):
"local_file" として report_processor.py に渡します。read_tool({"name": "reporting__get__download_url", "arguments": { user_report_pk, corporation_id }}) を呼び出して新しい署名済みURLを取得し、代わりに "download_url" として渡します。データサイズや複雑さに関係なく、常に report_processor.py → excel_exporter.py をパイプして処理してください。 openpyxl やその他のライブラリで直接Excelファイルを作成しないでください。スクリプトは Carta のブランディング(ロゴ、ヘッダー、フォント、数値形式)を処理し、単発の実装では失われます。データセットが小さい場合(例:3行)やシートを統合する必要がある場合も同じです。
複数のシートを1つのタブに統合する場合は、report_processor.py の呼び出しで merge_sheets を使用してください。
sheets 辞書を使用してすべてのシートを一度に渡します。excel_exporter.py にパイプします。親セッションが解決した場合はキャッシュされた _report_processor_path を再利用します(新規の Generate Carta Excel — プロンプトバーパスでは設定されていない可能性があります。find フォールバックが対応します):
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
スクリプトは成功時に絶対パスを出力します。クリック可能なリンクとして表示します: computer://<absolute-path>(例:computer:///Users/jane/meetly-equity-grants.xlsx)。ユーザーにファイルが開く準備ができたことを伝え、次のステップを提案します:
| 要素 | 値 |
|---|---|
| ヘッダーの背景色 | #c6ebf4 |
| ヘッダーのフォント | Arial 12pt 太字、#2f3943 |
| ロゴ | <skill_base_dir>/assets/Carta_Logo.png、セルA2、120×50px |
| タイトル | セルB2、Arial 16pt 太字 |
| サブタイトル | セル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" |
| ヘッダー行 | 行5(オートフィルター有効)、行A6でペイン固定、データは行6から開始 |
列タイプ → 数値形式: money → $#,##0.00 · percentage → 0.00% · integer → #,##0 · date → mmm d, yyyy · decimal → #,##0.0000
列幅: 文字列/日付 → 35、数値型 → 18
<!-- carta:plugin-version --> <carta-plugin>carta-cap-table:6.96.0</carta-plugin>
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 absentcorporation_id — needed for read_tool({"name": "reporting__get__download_url", ...})carta-reporting-markdown (Claude Code)as_of_date, user full name — used as --title, --as-of-date, --generated-by args to excel_exporter.pyWhen 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.
Use the column list confirmed during the Customization Checkpoint (resolved in carta-reporting-markdown).
Check if /tmp/carta_report_<user_report_pk>.json is available (use user_report_pk from this session):
"local_file" to report_processor.py.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):
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:
| 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.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。