📊carta-reporting-markdown
- プラグイン
- carta-cap-table
- ソース
- GitHub で見る ↗
説明
carta-reporting の内部サブスキル。 Claude Code によるインタラクションの全工程を主導します: スキーマのプレビュー、カスタマイズのチェックポイント、変換設定(フィルタリング、ソート、数式、集計)、出力プレビュー、および carta-reporting-excel へのハンドオフ。 プレビューファイルが生成された後、carta-reporting(Claude Code パス)によって呼び出されます。 ユーザーが直接呼び出すものではありません。
原文を表示
Internal subskill for carta-reporting. Drives the full Claude Code interaction: schema preview, customization checkpoint, transform config (filtering, sorting, formulas, aggregations), output preview, and hand-off to carta-reporting-excel. Invoked by carta-reporting (Claude Code path) after the preview file lands. Not for direct user invocation.
ユースケース
- ✓スキーマをプレビューするとき
- ✓カスタマイズ内容をチェックするとき
- ✓データの変換設定を行うとき
- ✓出力結果をプレビューするとき
- ✓Excel出力へ引き継ぐとき
本文(日本語訳)
変換設定
carta-reporting ステップ 4d(Claude Code / MARKDOWN パス)から呼び出されます。
このセッション内で解決済みの値(データファイルパス、corporation_id、user_report_pk)を使用してください。
スキーマプレビュー
変換なしで report_processor.py をデータファイルに対して実行し、カラム名と型を抽出します:
UV_PYTHON_DOWNLOADS=never uv run "$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)" <<'EOF'
{
"local_file": "<プレビューまたはフルレポートのファイルパス>"
}
EOF
まず簡潔な結果サマリー(例: 「Securities Ledger レポートです。フルデータをバックグラウンドで読み込んでいます。」)を提示し、その後カラム一覧を表示してください。
カラム一覧のフォーマット — カテゴリ別にグループ化した番号付きリスト。28カラムのレポートの例:
**全 28 カラム:**
Identity(識別情報)
1 — Stakeholder Name (text) 2 — Grant ID (text) 3 — Equity Plan (text)
Grant details(付与詳細)
4 — Grant Date (date) 5 — Grant Type (text) 6 — Exercise Price (money)
7 — Expiration Date (date)
Share counts(株数)
8 — Shares Issued (integer) 9 — Shares Vested (integer)
10 — Shares Unvested (integer) 11 — Shares Cancelled (integer)
...
グルーピングのヒューリスティクス(順番に適用し、該当なし → "Other"):
- Identity: カラム名に Stakeholder / Name / ID / Email / Type / Plan / Grant を含む
- Dates: 型が
date - Share counts: 型が
integer、かつカラム名に Share / Quantity / Count / Units を含む - Money: 型が
money - Percentages: 型が
percentage
カスタマイズチェックポイント
カラム・フィルター・並び順・フォーマットを一括で確認する AskUserQuestion を1回実行します。
内容は、元のプロンプトで既に指定された内容に応じて変わります。
プロンプトで詳細が指定されていた場合:
ご要望に基づき、以下の設定を適用します:
- カラム: Stakeholder Name, Grant Date, Shares Issued, Vested %
- フィルター: Vested % > 50%
- 並び順: Grant Date 降順
この設定で続行 と返信するか、必要に応じて変更してください。 追加オプション: 計算式カラム(合計比 %、累計、比率、差分)、集計(合計行、グループ集計)
プロンプトが曖昧だった場合:
カスタマイズ内容をお知らせください。全カラム・フィルターなし と返信するとデータセットをそのまま取得できます。または以下を指定してください:
- カラム — 含めるカラムを選択
- フィルター — 例: "Vested % > 50"、"Grant Date after 2024-01-01"、"Name contains Smith"
- 並び順 — 例: "Grant Date 新しい順"、"Shares Issued 降順"
- 計算式 — 合計比 %、累計、比率(A ÷ B)、差分(行間の変化)
- 集計 — 合計行またはグループ集計
カラム名のバリデーション
設定を構築する前に、ユーザーが指定したすべてのカラム名とフィルター対象を、スキーマプレビューで取得した実際のカラム名と照合してください。 ユーザーの表現はレポートのカラム名と異なる場合があります(例: "Department" → "Cost Center"、"Employee" → "Stakeholder Name"、"Vest %" → "Vested %")。
マッチングルール(順番に適用):
- 大文字・小文字を区別しない完全一致 → そのまま使用(通知不要)
- 実際のカラム名がユーザーの用語を含む、またはユーザーの用語が実際のカラム名を含む(例: "vest percentage" ↔ "Vested %")→ そのまま使用(通知不要)
- 確信を持って一致するものがない → チェックポイントの質問でフラグを立てる
用語が一致しない場合、チェックポイントで候補を提示してください:
⚠ "Department" はこのレポートで見つかりませんでした。最も近いテキストカラム: Cost Center、Equity Plan、Grant Type。どれのことでしたか、またはこのフィルターをスキップしますか?
候補は最大3件、編集距離・単語の重複度順に表示してください。 一致しなかった用語がフィルター対象だった場合、ユーザーが解決するまで設定に追加しないでください。
この確認を適用する対象: 明示的なカラム選択、フィルターのカラム名、並び順のカラム名、計算式のソースカラム
広いレポート(カラム数 > 10)でのカラム選択
主要な識別子カラム(Stakeholder Name、Grant ID、または相当するもの)と、プロンプトで明示的に指定されたカラムを常に事前選択します。 チェックポイントで事前選択内容を提示してください:
事前選択済みカラム: 1 — Stakeholder Name、2 — Grant ID、6 — Exercise Price 全28カラムを取得するには all、番号で追加するには +8, 12, 13 のように入力、キーワードで絞り込むには例えば vesting と入力、または現在の選択で進めるには yes と返信してください。
ユーザーがキーワードで返信した場合、一致するカラムのみを表示してもう一度 AskUserQuestion を呼び出し、確認または番号による追加を求めてください。
第2のチェックポイント質問が許可されるのはこのケースのみです。
フィルタリングルール
すべてのフィルタリングは report_processor.py が処理します。Claude のメモリ上でフィルターを適用しないでください。
ユーザーのリクエストをフィルターオブジェクトに変換してください:
| ユーザーのリクエスト | フィルターオブジェクト |
|---|---|
| "vested % > 50" | {"column": "Vested %", "op": ">", "value": 0.5} |
| "grant date after 2024-01-01" | {"column": "Grant Date", "op": ">", "value": "2024-01-01"} |
| "name contains Smith" | {"column": "Stakeholder Name", "op": "contains", "value": "Smith"} |
| "ownership above 5%" | {"column": "Fully Diluted %", "op": ">", "value": 0.05} |
サポートされる演算子: > < >= <= = != contains
カラム型が percentage の場合、パーセンテージの値は小数で渡してください(例: 50% → 0.5)。
フィルターによってシートからすべての行が除外された場合、スクリプトは0行を返します。そのシートはスキップし、サマリーに記載してください。
カラム選択
すべてのカラム選択は report_processor.py が処理します。
表示したい順序でカラム名を渡してください。スクリプトはその順序を保持します。
ユーザーが明示的に指定しなかった場合でも、主要な識別子カラム(Stakeholder Name、Grant ID、または相当するもの)を常に含めてください。
並び順
ユーザーのリクエストをソートオブジェクトに変換してください:
| ユーザーのリクエスト | ソートオブジェクト |
|---|---|
| "newest first" | {"column": "Grant Date", "direction": "desc"} |
| "largest first" | {"column": "Shares Issued", "direction": "desc"} |
| "alphabetical" | {"column": "Stakeholder Name", "direction": "asc"} |
複数キーの場合: 優先度順に複数のオブジェクトを渡します(先頭 = 第1ソートキー)。
計算式カラム
計算式の処理は report_processor.py が行います。
計算式はカラム選択の後に適用されるため、参照できるのは出力に含まれるカラムのみです。
適用範囲の境界
計算式は、レポートデータにすでに存在する値に対する機械的な変換のみを対象とします。 エクイティのルールを知らなくてもスプレッドシートで実行できる算術演算です。 サポートされる4つの演算:
| 演算 | 説明 | 必須フィールド |
|---|---|---|
pct_of_total |
各行をカラムの総合計に対する % で表す | column |
running_sum |
カラムの累計(現在の並び順) | column |
ratio |
分子 ÷ 分母 | numerator, denominator |
delta |
行間の差分(現在の並び順) | column |
キャップ構造・エクイティの権利・持分計算の理解が必要な値をユーザーが求めた場合は、該当する Carta レポートを案内してください:
「その計算はエクイティのルールが必要なため、生データから安全に計算することができません。Carta の [レポート名] レポートにすでに含まれています。そちらを取得しましょうか?」
例:
[
{"name": "% of Total Shares", "op": "pct_of_total", "column": "Shares Issued"},
{"name": "Cumulative Shares", "op": "running_sum", "column": "Shares Issued"}
]
集計
集計は report_processor.py が処理します。
サマリー行 — 末尾に合計行を1行追加します。第1カラムには "Total" と表示されます:
{"type": "summary", "columns": {"Shares Issued": "sum", "Vested %": "avg"}}
グループ集計 — キーカラムで行をまとめ、ユニーク値ごとに1行にします:
{"type": "group_by", "group_by": "Stakeholder Name",
"columns": {"Shares Issued": "sum", "Grant Count": "count"}}
サポートされる演算子: sum avg min max count
スクリプト: report_processor.py
完全な API(全フィールド、マルチシート、マージ、出力フォーマット)については、carta-reporting の Script Reference を参照してください。
Phantom equity ラベル: このセッション(carta-reporting ステップ 1a)で _phantom_label_<corporation_id> が解決されていた場合、この法人に対するすべての report_processor.py 呼び出し(スキーマプレビュー呼び出し、出力プレビュー/フルレポート呼び出しの両方)に "label_overrides": {"CBU": "<label>"} を含めてください。
複数法人のフローを正しく処理するために、法人キー付きの変数(例: _phantom_label_12345)を使用してください。
実行後は必ず stats を確認してください:
missing_columnsが空でない →data[sheet].columnsから利用可能なカラム名を一覧表示し、どれのことか確認したうえで、修正した名前で再実行するskipped_formulasが空でない → どの計算式が実行できなかったかをユーザーに伝える(通常、ソースカラムが選択に含まれていないことが原因)filtered_row_count= 0 → 一致する行がなし。フィルターを緩めるかas_of_dateを変更するよう提案するdisplayed_row_count<filtered_row_count→ プレビューが有効な状態。previewなしで再実行してフル結果を取得する
出力プレビュー
カスタマイズチェックポイントの後、/tmp/carta_report_<user_report_pk>.json が存在するか確認してください。
準備ができていれば local_file として使用します。準備できていない場合は5秒ごとに最大5回ポーリングしてください。
"preview": 5 を指定してスクリプトを実行します:
UV_PYTHON_DOWNLOADS=never uv run "$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)" <<'EOF'
{
"local_file": "<パス>",
"columns": [...],
"filters": [...],
"sort": [...],
"preview": 5
}
EOF
処理済みの各シートの先頭5行を Markdown テーブルとして表示してください。
各テーブルの上に N of M rows matched · K columns と記載してください。
次のように確認を求めてください:
この内容で問
原文(English)を表示
Transform Configuration
Called from carta-reporting step 4d (Claude Code / MARKDOWN path). Use values resolved earlier in this session: data file path, corporation_id, user_report_pk.
Schema Preview
Run report_processor.py on the data file with no transforms to extract column names and types:
UV_PYTHON_DOWNLOADS=never uv run "$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)" <<'EOF'
{
"local_file": "<preview or full report file path>"
}
EOF
Lead with a brief result summary (e.g. "Here's your Securities Ledger report — loading full data in the background."), then present the column inventory.
Column inventory format — numbered list, grouped by category. Example for a 28-column report:
**All 28 columns:**
Identity
1 — Stakeholder Name (text) 2 — Grant ID (text) 3 — Equity Plan (text)
Grant details
4 — Grant Date (date) 5 — Grant Type (text) 6 — Exercise Price (money)
7 — Expiration Date (date)
Share counts
8 — Shares Issued (integer) 9 — Shares Vested (integer)
10 — Shares Unvested (integer) 11 — Shares Cancelled (integer)
...
Grouping heuristics (apply in order; unmatched → "Other"):
- Identity: names contain Stakeholder, Name, ID, Email, Type, Plan, Grant
- Dates: type =
date - Share counts: type =
integer, name contains Share, Quantity, Count, Units - Money: type =
money - Percentages: type =
percentage
Customization Checkpoint
One AskUserQuestion covering columns, filters, sort, and format. Content adapts based on what the original prompt already specified.
When the prompt specified details:
Here's what I'll apply based on your request:
- Columns: Stakeholder Name, Grant Date, Shares Issued, Vested %
- Filter: Vested % > 50%
- Sort: Grant Date descending
Reply Continue with these settings to proceed, or adjust anything. You can also add: formula columns (% of total, running sum, ratio, delta), or aggregations (totals row, group-by).
When the prompt was vague:
What would you like to customize? Reply all columns, no filters to get the full dataset as-is, or specify any of:
- Columns — which to include
- Filters — e.g. "Vested % > 50", "Grant Date after 2024-01-01", "Name contains Smith"
- Sort — e.g. "Grant Date newest first", "Shares Issued descending"
- Formulas — % of total, running sum, ratio (A ÷ B), delta (row-over-row change)
- Aggregations — totals row or group-by rollup
Column name validation
Before building the config, check every column name and filter target the user mentioned against the actual column names from the schema preview. The user's terminology often differs from the report's column names (e.g. "Department" → "Cost Center", "Employee" → "Stakeholder Name", "Vest %" → "Vested %").
Matching rules (apply in order):
- Case-insensitive exact match → use it silently.
- One actual column name contains the user's term, or the user's term contains an actual column name (e.g. "vest percentage" ↔ "Vested %") → use it silently.
- No confident match → flag it in the checkpoint question.
When a term can't be matched, surface it in the checkpoint with candidates:
⚠ "Department" wasn't found in this report. Closest text columns: Cost Center, Equity Plan, Grant Type. Which did you mean, or should I skip this filter?
Show at most 3 candidates, ranked by edit distance / word overlap. If the unmatched term was a filter target, do not add it to the config until the user resolves it.
Apply this check to: explicit column selections, filter column names, sort column names, and formula source columns.
Column selection for wide reports (> 10 columns)
Always pre-select key identifier columns (Stakeholder Name, Grant ID, or equivalent) plus any columns explicitly named in the prompt. State what's pre-selected in the checkpoint:
Columns pre-selected: 1 — Stakeholder Name, 2 — Grant ID, 6 — Exercise Price Reply all for all 28 columns, add by number (e.g. +8, 12, 13), enter a keyword to filter (e.g. vesting), or confirm the pre-selection with yes.
If the user replies with a keyword, call AskUserQuestion once more showing only matching columns and ask them to confirm or add more by number. This is the only case where a second checkpoint question is allowed.
Filtering Rules
All filtering is handled by report_processor.py — do not apply filters in Claude's memory.
Translate user requests to filter objects:
| User request | Filter object |
|---|---|
| "vested % > 50" | {"column": "Vested %", "op": ">", "value": 0.5} |
| "grant date after 2024-01-01" | {"column": "Grant Date", "op": ">", "value": "2024-01-01"} |
| "name contains Smith" | {"column": "Stakeholder Name", "op": "contains", "value": "Smith"} |
| "ownership above 5%" | {"column": "Fully Diluted %", "op": ">", "value": 0.05} |
Supported ops: > < >= <= = != contains
Pass percentage values as decimals when the column type is percentage (e.g. 50% → 0.5).
When a filter removes all rows from a sheet, the script returns 0 rows — skip that sheet and note it in the summary.
Column Selection
All column selection is handled by report_processor.py. Pass column names in the desired display order; the script preserves that order.
Always include key identifier columns (Stakeholder Name, Grant ID, or equivalent) even if the user didn't explicitly request them.
Sorting
Translate user requests to sort objects:
| User request | Sort object |
|---|---|
| "newest first" | {"column": "Grant Date", "direction": "desc"} |
| "largest first" | {"column": "Shares Issued", "direction": "desc"} |
| "alphabetical" | {"column": "Stakeholder Name", "direction": "asc"} |
Multi-key: pass multiple objects in priority order (first = primary sort key).
Formula Columns
Formula computation is handled by report_processor.py. Formulas are applied after column selection — they can only reference columns that are included in the output.
Scope boundary
Formulas are for mechanical transforms on values already present in the report data — arithmetic that any spreadsheet could do without knowing anything about equity rules. The four supported ops:
| Op | Description | Required fields |
|---|---|---|
pct_of_total |
Each row as % of the column's grand total | column |
running_sum |
Cumulative total down the column (current sort order) | column |
ratio |
numerator ÷ denominator | numerator, denominator |
delta |
Row-over-row difference (current sort order) | column |
If a user asks for a value that requires understanding cap structure, equity rights, or ownership math, direct them to the Carta report that already contains it:
"That calculation involves equity rules that I can't safely compute from the raw data. Carta's [Report Name] report already has it — want me to pull that one instead?"
Example:
[
{"name": "% of Total Shares", "op": "pct_of_total", "column": "Shares Issued"},
{"name": "Cumulative Shares", "op": "running_sum", "column": "Shares Issued"}
]
Aggregations
Aggregation is handled by report_processor.py.
Summary row — appends one totals row at the bottom; first column reads "Total":
{"type": "summary", "columns": {"Shares Issued": "sum", "Vested %": "avg"}}
Group-by — collapses rows by a key column, one row per unique value:
{"type": "group_by", "group_by": "Stakeholder Name",
"columns": {"Shares Issued": "sum", "Grant Count": "count"}}
Supported ops: sum avg min max count
Script: report_processor.py
See Script Reference in carta-reporting for the full API (all fields, multi-sheet, merge, output format).
Phantom equity label: If _phantom_label_<corporation_id> was resolved in this session (Step 1a of carta-reporting), include "label_overrides": {"CBU": "<label>"} in every report_processor.py invocation for this corporation — both the schema preview call and the output preview/full-report call. Use the corporation-keyed variable (e.g. _phantom_label_12345) to correctly handle multi-corporation flows.
Always check stats after running:
missing_columnsnon-empty → list available column names fromdata[sheet].columnsand ask the user which they meant, then re-run with the corrected nameskipped_formulasnon-empty → tell the user which formulas couldn't run (usually the source column wasn't included in the selection)filtered_row_count= 0 → no rows matched; offer to relax the filter or changeas_of_datedisplayed_row_count<filtered_row_count→ preview is active; re-run withoutpreviewfor full results
Output Preview
After the Customization Checkpoint, check if /tmp/carta_report_<user_report_pk>.json exists. If ready, use it as local_file. If not, poll every 5 s up to 5 more attempts.
Run the script with "preview": 5:
UV_PYTHON_DOWNLOADS=never uv run "$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)" <<'EOF'
{
"local_file": "<path>",
"columns": [...],
"filters": [...],
"sort": [...],
"preview": 5
}
EOF
Show first 5 rows of each processed sheet as a markdown table. Above each table write: N of M rows matched · K columns.
Ask:
Does this look right?
- Generate full report — all rows as a markdown table
- Excel — download as .xlsx
- Describe any change to filters, columns, or sorting — I'll update just that field and re-run the preview without restarting the whole checkpoint.
If the user requests a change, update only the affected config field and re-run the preview — do not restart the customization checkpoint.
If the user chooses Excel, invoke Skill(carta-cap-table:carta-reporting-excel).
Presentation
- One table per sheet — label with the sheet name as a heading.
- Summary line above each table — e.g. "89 of 212 grants matched (Vested % > 50%)."
- Money columns — format as
$1,234.56. - Percentage columns — format as
12.34%(script stores as decimal; multiply × 100 for display). - Date columns — format as
MMM D, YYYY(e.g.May 3, 2026) — the Carta brand standard. - If multiple sheets are returned and only one has data after filtering, hide the empty sheets.
原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。