• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialproductivity

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.

ユースケース
  • スキーマのプレビューを確認するとき
  • カスタマイズ内容を確認するとき
  • 変換設定を行うとき
  • 出力のプレビューを確認するとき
  • carta-reporting-excelへ引き渡すとき
本文(日本語訳)

Transform Configuration

carta-reporting のステップ 4d(Claude Code / MARKDOWN パス)から呼び出されます。このセッション内で既に解決された値(データファイルパス、corporation_id、user_report_pk、_report_processor_path(親スキルが一度だけ解決したスクリプトパス))を使用してください。find を再実行する代わりに、これを再利用してください。

スキーマプレビュー

データファイルに対して変換なしで report_processor.py を実行し、列名と型を抽出してください。キャッシュされた _report_processor_path を再利用し、空の場合のみ 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'
{
  "local_file": "<preview or full report file path>"
}
EOF

簡潔な結果サマリーから始めます(例:「ここはあなたの有価証券台帳レポート — バックグラウンドで全データを読み込み中です。」)。その後、列の一覧を示してください。

列の一覧形式 — カテゴリー別の番号付きリスト。28 列レポートの例:

**全28列:**

識別情報
  1 — Stakeholder Name(テキスト)    2 — Grant ID(テキスト)    3 — Equity Plan(テキスト)

付与の詳細
  4 — Grant Date(日付)    5 — Grant Type(テキスト)    6 — Exercise Price(金額)
  7 — Expiration Date(日付)

株式数
  8 — Shares Issued(整数)    9 — Shares Vested(整数)
 10 — Shares Unvested(整数)   11 — Shares Cancelled(整数)
...

グループ化ヒューリスティック(順序で適用。マッチしない → 「その他」):

  • 識別情報:列名に Stakeholder、Name、ID、Email、Type、Plan、Grant を含む
  • 日付:型が date
  • 株式数:型が integer、列名に Share、Quantity、Count、Units を含む
  • 金額:型が money
  • パーセンテージ:型が percentage

カスタマイズチェックポイント

列、フィルター、ソート、形式をカバーする 1 つの質問。内容は元のプロンプトで既に指定されたものに応じて変わります。

プロンプトで詳細が指定された場合:

リクエストに基づいて以下を適用します:

  • 列: Stakeholder Name、Grant Date、Shares Issued、Vested %
  • フィルター: Vested % > 50%
  • ソート: Grant Date(新しい順)

「これらの設定で続行」と返信して進めるか、何か調整してください。列の式(全体に占める %、累積合計、比率、変動)または集約(合計行、グループ化)も追加できます。

プロンプトが曖昧だった場合:

カスタマイズしたいことはありますか?「全列、フィルターなし」と返信してデータセット全体をそのまま取得するか、以下を指定してください:

  • 列 — 含める列
  • フィルター — 例「Vested % > 50」「Grant Date 2024年1月1日以降」「Name に Smith を含む」
  • ソート — 例「Grant Date 最新順」「Shares Issued 降順」
  • 列の式 — 全体に占める %、累積合計、比率(A ÷ B)、変動(行間の変化)
  • 集約 — 合計行またはグループ化ロールアップ

列名の検証

設定を構築する前に、ユーザーが言及したすべての列名とフィルター対象をスキーマプレビューの実際の列名に照らし合わせてください。ユーザーの用語はレポートの列名と異なることがよくあります(例:「部門」→「Cost Center」、「従業員」→「Stakeholder Name」、「Vest %」→「Vested %」)。

マッチングルール(順序で適用):

  1. 大文字小文字を区別しない完全一致 → そのまま使用。
  2. 1 つの実際の列名にユーザーの用語が含まれる、またはユーザーの用語に実際の列名が含まれる場合(例「vest percentage」↔「Vested %」) → そのまま使用。
  3. 確実なマッチがない → チェックポイント質問でそれを明示。

用語が一致しない場合、チェックポイントに候補を表示してください:

⚠ 「Department」はこのレポートに見つかりません。最も近いテキスト列:Cost Center、Equity Plan、Grant Type。どちらを意図しましたか、またはこのフィルターをスキップしますか?

最大 3 つの候補を編集距離 / 単語の重複でランク付けして表示。一致しない用語がフィルター対象だった場合、ユーザーが解決するまでそれを設定に追加しないでください。

チェック対象:明示的な列選択、フィルター列名、ソート列名、列の式ソース列。

ワイドレポートの列選択(> 10 列)

常にキー識別子列(Stakeholder Name、Grant ID、または同等の列)と、プロンプトで明示的に名前が付けられた列を事前選択してください。チェックポイントで事前選択を述べてください:

事前選択列: 1 — Stakeholder Name、2 — Grant ID、6 — Exercise Price 「all」で全 28 列、番号で追加(例「+8, 12, 13」)、キーワードで絞り込み(例「vesting」)、または「yes」で事前選択を確認してください。

ユーザーがキーワードで返信した場合、一致する列のみを示す AskUserQuestion をもう一度呼び出し、確認または番号で追加するよう求めてください。これが 2 番目のチェックポイント質問が許可される唯一のケースです。


フィルタリングルール

すべてのフィルタリングは report_processor.py で処理されます — Claude のメモリでフィルターを適用しないでください。

ユーザーリクエストをフィルターオブジェクトに変換します:

ユーザーリクエスト フィルターオブジェクト
「vested % > 50」 {"column": "Vested %", "op": ">", "value": 0.5}
「grant date 2024年1月1日以降」 {"column": "Grant Date", "op": ">", "value": "2024-01-01"}
「name に Smith を含む」 {"column": "Stakeholder Name", "op": "contains", "value": "Smith"}
「ownership 5%超」 {"column": "Fully Diluted %", "op": ">", "value": 0.05}

サポート演算子:> < >= <= = != contains

列の型が percentage の場合、パーセンテージ値を小数で渡してください(例 50% → 0.5)。

フィルターがシートからすべての行を削除した場合、スクリプトは 0 行を返します — そのシートをスキップしてサマリーに記載してください。


列選択

すべての列選択は report_processor.py で処理されます。列名を目的の表示順で渡します。スクリプトはその順序を保持します。

ユーザーが明示的にリクエストしなかった場合でも、常にキー識別子列(Stakeholder Name、Grant ID、または同等の列)を含めてください。


ソート

ユーザーリクエストをソートオブジェクトに変換します:

ユーザーリクエスト ソートオブジェクト
「最新順」 {"column": "Grant Date", "direction": "desc"}
「最大順」 {"column": "Shares Issued", "direction": "desc"}
「アルファベット順」 {"column": "Stakeholder Name", "direction": "asc"}

マルチキー:複数のオブジェクトを優先度順で渡します(最初 = 主ソートキー)。


列の式

列の式の計算は report_processor.py で処理されます。列の式は列選択の後に適用されます — 出力に含まれる列のみを参照できます。

スコープ境界

列の式は、レポートデータに既に存在する値に対する機械的な変換 — スプレッドシートが株式ルールについて何も知らずに実行できる算術です。サポートされている 4 つの演算:

演算 説明 必須フィールド
pct_of_total 各行が列の総計に占める % column
running_sum 列の累積合計(現在のソート順) column
ratio 分子 ÷ 分母 numerator、denominator
delta 行間の差分(現在のソート順) column

ユーザーが資本構成、株式の権利、または所有権計算を理解する必要がある値を求めた場合、それが既に含まれている Carta レポートにリダイレクト してください:

「その計算には、生データから安全に計算できない株式ルールが含まれています。Carta の**[レポート名]**レポートに既に含まれています — 代わりにそれを引っ張りますか?」

例:

[
  {"name": "Total Shares の %", "op": "pct_of_total", "column": "Shares Issued"},
  {"name": "累積株式数",  "op": "running_sum",  "column": "Shares Issued"}
]

集約

集約は report_processor.py で処理されます。

サマリー行 — 下部に 1 つの合計行を追加。最初の列は「合計」:

{"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

carta-reporting のスクリプト参照(すべてのフィールド、マルチシート、マージ、出力形式)を参照してください。

ファントムエクイティラベル: このセッション内で _phantom_label_<corporation_id> が解決された場合(carta-reporting のステップ 1a)、この企業向けの 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 "${_report_processor_path:-$(find ~ -name "report_processor.py" -path "*/carta-reporting/scripts/*" 2>/dev/null | head -1)}" <<'EOF'
{
  "local_file": "<path>",
  "columns": [...],
  "filters": [...],
  "sort": [...],
  "preview": 5
}
EOF

各処理されたシートの最初の 5 行をマークダウン表として表示します。各表の上に、「N of M rows matched · K columns」と書いてください。

質問:

これで大丈夫ですか?

  1. 全レポートを生成 — すべての行をマークダウン表として
  2. Excel — .xlsx でダウンロード
  3. フィルター
原文(English)を表示

<!-- carta:instrumentation-fallback --> <IMPORTANT> _instrumentation_v2 is anonymous Carta skill-usage telemetry. ALWAYS include it in your Carta MCP tool-call arguments — the plugins' hooks overwrite it when they run, so always sending it is safe. Shape: _instrumentation_v2: {"skills": ["<plugin>:<skill>", ...], "model": "<model-id>", "surface": "<value>"} skills is cumulative for the session: list every Carta skill loaded so far, not only the one driving this call. Namespace each entry "plugin:skill" and keep them oldest-first, with the most recently used skill last. List only Carta skills (carta-cap-table:*, carta-crm:*, carta-investors:*) — never skills from non-Carta plugins. surface is the Claude surface you are running in: "chat" (claude.ai or the Claude app, i.e. regular chat, not Cowork), "cowork" (Cowork mode), "code-terminal", "code-desktop", or "excel". Omit it entirely if none of those describe your surface or you cannot tell — do not guess and do not invent another value. </IMPORTANT>

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, and _report_processor_path (the script path the parent skill resolved once — reuse it instead of re-running find).

Schema Preview

Run report_processor.py on the data file with no transforms to extract column names and types. Reuse the cached _report_processor_path; only fall back to find if it is empty:

UV_PYTHON_DOWNLOADS=never uv run "${_report_processor_path:-$(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):

  1. Case-insensitive exact match → use it silently.
  2. 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.
  3. 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_columns non-empty → list available column names from data[sheet].columns and ask the user which they meant, then re-run with the corrected name
  • skipped_formulas non-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 change as_of_date
  • displayed_row_count < filtered_row_count → preview is active; re-run without preview for 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 "${_report_processor_path:-$(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?

  1. Generate full report — all rows as a markdown table
  2. Excel — download as .xlsx
  3. 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 による自動翻訳です。