event-prospecting
browserbase/skills
カンファレンスやイベントの登壇者のURLを受け取り、登壇者を抽出し、ユーザーのICPに基づいて所属企業をフィルタリングし、ICPに合致する企業の登壇者のみを詳細に調査します。その結果、人物を主軸としたHTMLレポートを出力し、各登壇者ごとに「なぜアプローチすべきか」という根拠を記載します。
...すべて拡張しますイベントでの見込み客開拓
カンファレンスのURLを入力すると、AEが接触すべき人物のランク付けされたリストと、人物ごとの「連絡すべき理由」が表示されます。
必要条件:環境変数BROWSERBASE_API_KEYおよびbrowseCLI のインストール(npm install -g browse)。API 呼び出しにはbrowse cloud ... を、JavaScript を多用した講演者ページにはbrowse open/browse get markdownを使用します。
パスに関するルール:すべてのBashコマンドでは、常に完全なリテラルパスを使用すること。~や$HOMEは使用しない(どちらも「シェル展開構文」の承認プロンプトを引き起こす)。 ホームディレクトリは一度だけ解決し、その後はどこでもそれを使用してください。サブエージェントのプロンプトを作成する際は、{SKILL_DIR}を完全なリテラルパス(通常は/Users/jay/skills/skills/event-prospecting )に置き換えてください。
出力ディレクトリ:イベント見込み客探索のすべての出力は、~/Desktop/{event_slug}_prospects_{YYYY-MM-DD-HHMM}/ に保存されます。 最終成果物はindex.html(企業ごとにグループ化され、企業の ICP 順にランク付けされたリスト)であり、代替ビューとしてcompanies.htmlおよびpeople.html(フィルタリング可能)に加え、コールドアウトバウンド用インポート用のresults.csvが含まれます。
重要 — ツールの制限事項(メインエージェントおよびすべてのサブエージェントに適用されます):
- すべてのウェブ検索:
Browse Cloud Searchを使用してください。WebSearchは絶対に使用しないでください。 - すべてのページコンテンツ抽出:
node {SKILL_DIR}/scripts/extract_page.mjs "を使用すること。 このスクリプトは、" browse cloud fetch --output経由でデータを取得し、タイトル、メタタグ、表示されている本文テキストを解析します。また、取得に失敗した場合や、JSでレンダリングされた薄いコンテンツが返された場合には、自動的にbrowse get markdownにフォールバックします。browse cloud fetch | sedパイプラインを手動で作成してはなりません。WebFetch を使用してはなりません。 - すべての調査結果の出力:サブエージェントは、bashのheredocを使用して、企業ごとまたは人物ごとに1つのMarkdownファイルを
{OUTPUT_DIR}/companies/{slug}.mdまたは{OUTPUT_DIR}/people/{slug}.mdに書き出します。Writeツールやpython3 -cは絶対に使用しないでください。 両方のファイル形式については、references/example-research.md を参照してください。 - レポートのコンパイル:
node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --openを使用してください。 - サブエージェントはBashツールのみを使用してください。他のツールの使用は許可されません。
- ツール呼び出しの厳格な上限:ICP トリアージ = 1 社あたり 1 回の電話、詳細調査 = 1 社あたり 5 回の電話、人物情報の充実 = 1 人あたり 4 回の電話。実施の詳細については、
references/workflow.md を参照してください。
重要 — 誤認識防止ルール(メインエージェントおよびすべてのサブエージェントに適用):
- サイトのフォント、フレームワーク、デザインシステム、またはタイポグラフィから、
product_description、業界、または人物のrole_reasonを推測してはなりません。これらは外観上の要素に過ぎず、企業が何を販売しているか、あるいはその人物が何をしているかについては何も示していません。 - ユーザー自身のICPを、ターゲットの説明に決して反映させてはなりません。ターゲットが何をしているか分からない場合は、「
Unknown」と記述し、ICPにパターンマッチさせないでください。 product_descriptionには、extract_page.mjsの出力から特定のフレーズを引用または言い換える必要があります。TITLE/META/OG/HEADINGS/BODYのいずれからも認識可能な製品説明が得られない場合は、「Unknown — ホームページのコンテンツにアクセス不可」と記述し、icp_fit_scoreの上限を3に設定してください。- 人物の
フックは、ブラウズクラウドの検索結果(ポッドキャストのタイトル、ブログのヘッドライン、GitHubリポジトリ、講演要旨)から特定の情報を引用または言い換える必要があります。過去6ヶ月間に公開されたシグナルが存在しない場合は、イベントコンテキスト(そのイベントでの講演タイトル)にフォールバックしてください。
重要 — 権限確認のプロンプトを最小限に抑える:
- サブエージェントは、連鎖したheredocsを使用して、すべてのファイル書き込みを単一のBash呼び出しにバッチ処理しなければならない。1回のBash呼び出し = 1回の権限プロンプト。
- すべての検索およびすべての取得を、
&&連結を使用して単一の Bash 呼び出しにまとめてください。
パイプラインの概要
以下の10のステップを順に実行してください。ステップをスキップしたり、順序を変更したりしないでください。
- セットアップ— 出力ディレクトリ + クリーンな状態
- プロファイルの読み込み—
profiles/{user_slug}.jsonを読み込む - 再認識— イベントプラットフォームの検出
- 人物の抽出—
people.jsonl - 企業ごとのグループ分け—
seed_companies.txt - ICP トリアージ— 企業レベルの高速スコアリング(1 社あたり 1 回の呼び出し)
- フィルタ—
icp_fit_scoreが--icp-threshold 以上の企業 - 詳細調査— ICP適合性に関する「計画→調査→統合」の全プロセス
- 登壇者の情報充実— ユーザーに確認:ICP適合者のみ(デフォルト)か、すべての登壇者か
- レポートの作成— HTML + CSV、ブラウザで開く
ユーザーは/event-prospecting や のようなURLでスキルを呼び出します。その呼び出しメッセージからEVENT_URL を解析します。デフォルト設定:DEPTH=deep、ICP_THRESHOLD=6。USER_SLUG(ICPプロファイル)は、ステップ1においてローカルに存在するプロファイルファイルから自動的に解決されます。組み込みのデフォルトプロファイルはありません。ユーザーにURLの確認を求めないでください。ユーザーはすでにURLを提供しています。
ステップ 0: 出力ディレクトリの設定
ユーザーが指定したURLから出力ディレクトリを導出します。イベント名をハードコードしないでください。
# EVENT_URL は呼び出しメッセージ(ユーザーが `/event-prospecting` の後に入力した内容)から取得されます
EVENT_SLUG=$(node -e 'const h = new URL(process.argv[1]).hostname.replace(/^www\./,""); console.log(h.split(".")[0])' "$EVENT_URL")
TIMESTAMP=$(date +%Y-%m-%d-%H%M)
OUTPUT_DIR=/Users/jay/Desktop/${EVENT_SLUG}_prospects_${TIMESTAMP}
mkdir -p "$OUTPUT_DIR/companies" "$OUTPUT_DIR/people"
完全なリテラル形式のホームパスを使用してください。~や$HOME は絶対に使用しないでください。すべてのサブエージェントのプロンプトには、{OUTPUT_DIR}を完全なリテラルパスとして渡してください。
ステップ 1: ユーザープロファイルの読み込み
このプロファイルは、ICPトリアージおよび詳細調査のスコアリングの基準となるICPを定義します。{SKILL_DIR}/profiles/{user_slug}.jsonから読み込みます(すべてのGTMスキル間で互換性あり — company-researchと同じ形式)。example.jsonはテンプレートであり、実際のプロファイルではありません。絶対に使用しないでください。
{SKILL_DIR}/profiles/以外の場所からプロファイルを検索しないでください。他のスキルのディレクトリにアクセスしてはいけません。他の場所でプロファイルが必要な場合は、ユーザーが明示的にコピーしてください。
解決順序:
- ユーザーが
--user-companyオプション付きで呼び出した場合は、そのスラグを使用します。を - それ以外の場合は、
example.jsonを除いてprofiles/*.jsonを一覧表示します。プロファイルが1つだけ存在する場合は、それを使用します(そして、どのプロファイルかユーザーに伝えます)。複数存在する場合は、ユーザーに(プレーンチャットで)どれを使用するか尋ねます。 - プロファイルが0つの場合は、明確にエラーを通知し、ユーザーにプロファイルを作成するよう指示する(
profiles/example.jsonをprofiles/コピーして内容を記入するか、自動的にプロファイルを生成するcompany-researchスキルを実行する)。.jsonに
PROFILES=$(ls {SKILL_DIR}/profiles/*.json 2>/dev/null | xargs -n1 basename | sed 's/\.json$//' | grep -v '^example$')
COUNT=$(echo "$PROFILES" | grep -c .)
if [ -z "$USER_SLUG" ]; then
if [ "$COUNT" -eq 0 ]; then
echo "{SKILL_DIR}/profiles/ にプロファイルが見つかりませんでした。profiles/example.json を profiles/.json にコピーして内容を記入するか、company-research スキルを実行して作成してください。"
exit 1
elif [ "$COUNT" -eq 1 ]; then
USER_SLUG=$PROFILES
echo "利用可能な唯一のプロファイルを使用します: ${USER_SLUG}"
else
echo "複数のプロファイルが見つかりました:"
echo "$PROFILES" | sed 's/^/ - /'
echo "--user-company を指定して再実行し、1つを選択してください。"
exit 1
fi
fi
test -f {SKILL_DIR}/profiles/${USER_SLUG}.json || {
echo "プロファイルが見つかりません: profiles/${USER_SLUG}.json"
exit 1
}
cat {SKILL_DIR}/profiles/${USER_SLUG}.json
このプロファイルからは、company、product、icp_description、existing_customers が得られます。これらは、下流のすべてのサブエージェントのプロンプトにそのまま埋め込まれます。
ステップ 2: 状況把握
イベントプラットフォームと抽出戦略を検出します。1つのコマンド:
node {SKILL_DIR}/scripts/recon.mjs {EVENT_URL} {OUTPUT_DIR}
{OUTPUT_DIR}/recon.jsonに、プラットフォーム、戦略、および(Next.js の場合)nextDataPaths が書き込まれます。プラットフォームのカタログと検出優先順位については、references/event-platforms.md を参照してください。
期待される結果:
- Stripe Sessions クラス(Next.js):
platform: "next-data", 1~3 つのパス - Sessionize:
platform: "sessionize" - Lu.ma / Eventbrite:
platform: "luma" | "eventbrite" - その他すべて:
platform: "custom",strategy: "markdown"(ベストエフォート方式のフォールバック)
ステップ3:参加者の抽出
node {SKILL_DIR}/scripts/extract_event.mjs {OUTPUT_DIR} --user-company {USER_SLUG}
recon.jsonを読み込み、プラットフォーム固有の抽出ツールに処理を委ね、people.jsonl(1行につき1人のスピーカー)とseed_companies.txt(重複排除済みの企業リスト)を書き込みます。
--user-companyフラグを指定すると、ホスト組織自身の従業員(Stripeがホストするイベントの場合、Stripeの従業員)およびユーザー自身の従業員がスピーカーリストから除外されます。これらは見込み客ではないためです。
出力の妥当性を確認します:
wc -l {OUTPUT_DIR}/people.jsonl {OUTPUT_DIR}/seed_companies.txt
head -3 {OUTPUT_DIR}/people.jsonl
people.jsonlが空、または 10 行未満の場合は、recon が誤ったプラットフォームを選択しています。references/event-platforms.md を参照し、戦略を調整して再実行してください。
ステップ4:企業ごとにグループ分け
extract_event.mjsはすでにseed_companies.txtを出力しています(1行に1社、重複排除済み、ソート済み)。このステップは確認用です。ファンアウト処理を行う前に、件数が妥当かどうかを確認してください:
wc -l {OUTPUT_DIR}/seed_companies.txt
期待値:スピーカー数の約0.4~0.6倍(ほとんどのイベントでは、1社あたり平均約2名のスピーカーが登壇しており、5名以上を派遣する企業もあれば、1名のみの企業も多い)。
ステップ5:ICPの選別
迅速なスクリーニング — 企業ごとに1回のツール実行のみ、詳細な調査は行わない。 seed_companies.txt内の全企業について、ユーザーのICPに対するスコアを算出し、companies/{slug}.mdに簡潔なトリアージのスタブを記述する。icp_fit_scoreが--icp-threshold(デフォルトは 6)以上である企業は、ステップ 7 の詳細調査に進みます。それ以外は選別スタブとして残します。
ディスパッチパターン:seed_companies.txtを約10社ずつバッチに分割し、単一のAgentバッチ内でN個のサブエージェントをファンアウトさせる(1つのメッセージ内で複数のAgentツール呼び出しを行う)。各サブエージェントは、references/workflow.md→ 「ICPトリアージ」セクションのプロンプトを実行する。 上限:1社につき1回のツール呼び出し(ホームページのextract_page.mjsのみ)。これは、# browse 呼び出しの N/1コメントパターンによって強制される。
# バッチファイルの構築:各バッチ行は「名前|推測されたホームページ|スラグ」の形式です。
# extract_event.mjsは企業名のみを出力するため(URLは含まれません)、スラグ化を行い、
# 正規のホームページとして https://{スペースなしのスラグ}.com を推測します。 トリアージサブエージェントは
# 推測されたURLが404エラーを返した場合、product_descriptionに「Unknown — homepage content not accessible」と記述し、
# キャップスコアを3に設定することが許可されています。これは
# workflow.md(ICPトリアージプロンプトのルール3)に記載されているフォールバック処理です。 URLを特定するために実際のブラウズクラウド検索を実行すると、
# 1社あたり1回の呼び出しというハードキャップに確実に抵触してしまいます。
node -e '
const fs = require("fs");
const slugify = (s) => (s || "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
const seed = fs.readFileSync("{OUTPUT_DIR}/seed_companies.txt", "utf-8").split("\n").filter(Boolean);
const lines = seed.map(c => {
const slug = slugify(c);
const guessedHost = c.toLowerCase().replace(/[^a-z0-9]/g, "");
return `${c}|https://${guessedHost}.com|${slug}`;
});
fs.writeFileSync("{OUTPUT_DIR}/_seed_with_urls.txt", lines.join("\n") + "\n");
'
# 約10社ずつバッチに分割
split -l 10 {OUTPUT_DIR}/_seed_with_urls.txt {OUTPUT_DIR}/_batch_triage_
# バッチ数をカウント → 派遣するサブエージェントの数(1メッセージあたり最大6体まで;残りは第2波として処理)
ls {OUTPUT_DIR}/_batch_triage_* | wc -l
その後、1つのメッセージ内で、バッチごとに1つのエージェント呼び出しを割り当てます(最大6つまで並行処理;最初の処理が戻った後に次のバッチを処理)。各エージェントは、references/workflow.md→ "ICP Triage" からプロンプトを取得し、送信前に以下の置換を行います:
{SKILL_DIR}→ スキルへの完全なリテラルパス(例:/Users/jay/skills/skills/event-prospecting){OUTPUT_DIR}→ 完全なリテラル出力パス{USER_COMPANY}、{USER_PRODUCT}、{ICP_DESCRIPTION}→ 読み込まれたプロファイルから取得{EVENT_NAME}→recon.jsonの.title{COMPANY_LIST}→ バッチファイルの内容(例:cat {OUTPUT_DIR}/_batch_triage_aa){TOTAL}→ このバッチの行数(# browse 呼び出しの N/{TOTAL}に代入)
エージェントのディスパッチ(骨格。1つのメッセージ内でバッチごとに繰り返す):
Agent(
description: "ICP トリアージ バッチ aa",
prompt:,
subagent_type: "general-purpose"
)
Agent(
description: "ICP トリアージ バッチ ab",
prompt:,
subagent_type: "general-purpose"
)
... 1 メッセージにつき最大 6 つまで
すべてのサブエージェントが処理を完了したら、seed_companies.txtに記載されているすべての企業に対応するcompanies/{slug}.md ファイルが存在することを確認します:
ls {OUTPUT_DIR}/companies/*.md | wc -l
# `wc -l {OUTPUT_DIR}/seed_companies.txt` と一致するはずです
バッチファイルを削除します:rm {OUTPUT_DIR}/_batch_triage_*.
ステップ 6: ICP 閾値によるフィルタリング
各companies/*.md のフロントマターを読み込み、icp_fit_score が 6 以上(または--icp-thresholdで指定された値以上)のものを保持します。残った企業のスラグを{OUTPUT_DIR}/icp_fits.txt に書き出します:
THRESHOLD=6 # --icp-threshold フラグから
for f in {OUTPUT_DIR}/companies/*.md; do
score=$(awk '/^icp_fit_score:/{print $2; exit}' "$f")
if [ -n "$score" ] && [ "$score" -ge "$THRESHOLD" ]; then
basename "$f" .md
fi
done > {OUTPUT_DIR}/icp_fits.txt
wc -l {OUTPUT_DIR}/icp_fits.txt
予想値:seed_companies.txt の 20~40%。生存率が 10% 未満の場合は、閾値が高すぎるか、ICP の記述が狭すぎる可能性があります。ユーザーに警告を表示してください。
ステップ7:詳細調査
ICPに適合する企業のみを対象に、[全体計画→調査→統合] を実行する。上限:1社あたり5回のツール呼び出し(ホームページの抽出 + 2~3回のサブクエリ検索 + 1~2回の補足情報取得)。 サブエージェントは、既存のcompanies/{slug}.mdトリアージ用スタブを、より詳細な詳細調査版で上書きする(フロントマターのtriage_only: false)。
ディスパッチパターン:icp_fits.txtを約5件ずつ(ディープモードのデフォルト)のバッチに分割し、1つのメッセージ内でバッチごとに1つのエージェントをファンアウトさせる(1メッセージあたり最大6つのエージェント)。各エージェントは、references/workflow.md→ 「Deep Research」のプロンプトを受け取り、以下の置換を行う:
{SKILL_DIR},{OUTPUT_DIR},{USER_COMPANY},{USER_PRODUCT},{ICP_DESCRIPTION}{EVENT_NAME}(recon.jsonの.titleから取得)、{EVENT_CONTEXT}(トラック/トピック、イベントのホームページから手動で推論){COMPANY_LIST}→ バッチファイルの内容(各行がslug|website の形式)
# 各トリアージ・スタブからフロントマターを読み取り、{company-slug|website} のペアを構築
while read slug; do
website=$(awk '/^website:/{print $2; exit}' {OUTPUT_DIR}/companies/${slug}.md)
echo "${slug}|${website}"
done < {OUTPUT_DIR}/icp_fits.txt > {OUTPUT_DIR}/_deep_targets.txt
# 約5社ずつバッチに分割 (ディープモード)
split -l 5 {OUTPUT_DIR}/_deep_targets.txt {OUTPUT_DIR}/_batch_deep_
ls {OUTPUT_DIR}/_batch_deep_* | wc -l
エージェントの割り当て(骨格、1つのメッセージ内でバッチごとに繰り返す):
Agent(
description: "Deep research batch aa",
prompt:,
subagent_type: "general-purpose"
)
Agent(
description: "Deep research batch ab",
prompt:,
subagent_type: "general-purpose"
)
... 1つのメッセージにつき最大6つまで;最初のグループが応答した後、2番目のグループをディスパッチ
すべてのサブエージェントが返答した後、deep-research ファイルが存在し、triage_only: false となっていることを確認します:
grep -l "triage_only: false" {OUTPUT_DIR}/companies/*.md | wc -l
# 結果は wc -l icp_fits.txt と等しくなるはず
ステップ8: スピーカー情報の充実
1人につき:LinkedInのURL、最近の活動(ポッドキャスト/ブログ/講演/GitHub/X)を収集し、people/{slug}.mdを作成する。上限:1人あたり4回のツール呼び出し、3つの処理経路:
クラウド検索「{name} {company} linkedin」を閲覧(常に)browse cloud search "{name} podcast OR talk OR blog 2026"(詳細+)ブラウズクラウド検索「{name} github」(より詳細)ブラウズクラウド検索「{name} site:x.com OR site:twitter.com」(さらに詳細、ベストエフォート)
クイックモード:ステップ8を完全にスキップ。ディープモード:レーン1~2。ディーパーモード:レーン1~4。
ステップ8a — ユーザーへの確認:情報充実の範囲
ディスパッチする前に、2つの候補の件数を算出し、ユーザーに選択を求めます。デフォルトはICPフィットのみです(高速、低コスト、大多数のユーザーが求める設定)。すべての発話者のエンリッチメントはオプトイン方式です。これは、エンリッチメントの対象となる人数に応じてコストが直線的に増加するためです。
TOTAL=$(wc -l < {OUTPUT_DIR}/people.jsonl)
ICP_FITS=$(node -e '
const fs = require("fs");
const fits = new Set(fs.readFileSync("{OUTPUT_DIR}/icp_fits.txt", "utf-8").split("\n").filter(Boolean));
const slug2name = {};
for (const slug of fits) {
const md = fs.readFileSync(`{OUTPUT_DIR}/companies/${slug}.md`, "utf-8");
const m = md.match(/^company_name:\s*(.+)$/m);
if (m) slug2name[slug] = m[1].trim();
}
const want = new Set(Object.values(slug2name).map(s => s.toLowerCase()));
const ppl = fs.readFileSync("{OUTPUT_DIR}/people.jsonl", "utf-8").split("\n").filter(Boolean).map(JSON.parse);
console.log(ppl.filter(p => p.company && want.has(p.company.toLowerCase())).length);
')
# 1人あたりのレーン数: 2 (浅い) または 4 (より深い) — {DEPTH} に一致
LANES=2 # より深くするには 4
echo "ICP に適合する: ${ICP_FITS} スピーカー × ${LANES} = $((ICP_FITS * LANES)) コール"
echo "合計: ${TOTAL} スピーカー × ${LANES} = $((TOTAL * LANES)) 件の呼び出し"
その後、AskUserQuestionを使用して、各選択肢のコストを明示した明確な 2 択の選択肢を提示します:
AskUserQuestion(questions: [
{
question: "どのスピーカーをエンリッチしますか?",
header: "エンリッチメントの範囲",
multiSelect: false,
options: [
{ label: "ICP FITSのみ", description: "${ICP_FITS} スピーカー、約 $((ICP_FITS * LANES)) コール (推奨)" },
{ label: "ICP FITSのみ", description: "${ICP_FITS}人のスピーカー、約$((ICP_FITS * LANES))件のコール" }
]
}
])
選択した範囲をENRICH_SCOPE=icp_fitsまたはENRICH_SCOPE=all として保存します。ユーザーが「すべてのスピーカー」を選択し、TOTAL × LANES > 600 の場合、警告を表示して再度確認を求めます。これは、数百回のツール呼び出しを伴う 10 分以上の実行となるためです。
ステップ 8b — フィルタリングとバッチ処理
# ENRICH_SCOPE に基づいて _people_to_enrich.jsonl を作成
if [ "$ENRICH_SCOPE" = "all" ]; then
cp {OUTPUT_DIR}/people.jsonl {OUTPUT_DIR}/_people_to_enrich.jsonl
else
node -e '
const fs = require("fs");
const fits = new Set(fs.readFileSync("{OUTPUT_DIR}/icp_fits.txt", "utf-8").split("\n").filter(Boolean));
const slug2name = {};
for (const slug of fits) {
const md = fs.readFileSync(`{OUTPUT_DIR}/companies/${slug}.md`, "utf-8");
const m = md.match(/^company_name:\s*(.+)$/m);
if (m) slug2name[slug] = m[1].trim();
}
const wantNames = new Set(Object.values(slug2name).map(s => s.toLowerCase()));
const lines = fs.readFileSync("{OUTPUT_DIR}/people.jsonl", "utf-8").split("\n").filter(Boolean);
const keep = lines.filter(l => {
const p = JSON.parse(l);
return p.company && wantNames.has(p.company.toLowerCase());
});
fs.writeFileSync("{OUTPUT_DIR}/_people_to_enrich.jsonl", keep.join("\n") + "\n");
console.error(`${lines.length} 人のスピーカーのうち ${keep.length} 人の情報を充実させています`);
'
fi
# 約5人ずつバッチに分割
split -l 5 {OUTPUT_DIR}/_people_to_enrich.jsonl {OUTPUT_DIR}/_batch_people_
その後、1つのメッセージ内で、references/workflow.md→ "Person Enrichment" のプロンプトを使用して、バッチごとに1つのエージェント呼び出し(1メッセージあたり最大6つ)をディスパッチします。各サブエージェントのプロンプトには以下を含める必要があります:
{SKILL_DIR},{OUTPUT_DIR},{DEPTH}(deep|deeper){USER_COMPANY},{USER_PRODUCT},{ICP_DESCRIPTION}{EVENT_NAME}(recon.jsonの.titleから取得){LANES}→ ディープモードの場合は2、ディーパーモードの場合は4(# browse呼び出しのN/{LANES}に代入){PEOPLE_BATCH}→_batch_people_aaの内容(各行はpeople.jsonlからの JSON レコード)
エージェントのディスパッチ(骨格。1つのメッセージ内でバッチごとに繰り返し):
Agent(
description: "Person enrichment batch aa",
prompt:,
subagent_type: "general-purpose"
)
Agent(
description: "Person enrichment batch ab",
prompt:,
subagent_type: "general-purpose"
)
... 1メッセージにつき最大6つまで
すべてのサブエージェントが処理を完了したら、人物ファイルが存在することを確認します:
ls {OUTPUT_DIR}/people/*.md | wc -l
# 結果は wc -l _people_to_enrich.jsonl と等しくなるはずです
ステップ 9: レポートの生成
1つのコマンドで、会社ごとにグループ化されたHTMLインデックス、代替ビュー、およびCSVを生成します:
node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --open
これにより以下が生成されます:
{OUTPUT_DIR}/index.html— 企業ごとにグループ化され、企業のICPスコア順にランク付けされた人員一覧(ブラウザで開きます){OUTPUT_DIR}/people.html— フィルタリング可能な登壇者リスト(代替ビュー){OUTPUT_DIR}/companies.html— 参加者を含む、ICPスコア順にランク付けされた企業一覧{OUTPUT_DIR}/results.csv— コールドアウトバウンドにすぐに使えるスプレッドシート
その後、チャットで概要を提示します:
## イベント見込み客開拓完了 — {イベント名}
- **抽出されたスピーカー総数**: {count}
- **ユニークな企業数**: {count}
- **ICP適合数(スコア ≥ {threshold})**: {count}
- **情報補完済みの登壇者**: {count}
- **スコア分布**(企業):
- 適合度が高い(8~10):{count}
- 部分的に適合(5~7):{count}
- 適合度が低い (1-4): {count}
- **ブラウザでレポートを開く**: {OUTPUT_DIR}/index.html
上位5件の「People Card」を、企業のICPスコア順に並べ替えたマークダウン形式の表として表示し、次に以下の提案を行う:
--icp-threshold を調整して、手順 6~9 を再実行する- CSVをCRMにエクスポートする
---
name: event-prospecting
description: Takes a conference or event speakers URL, extracts the people, filters their companies against the user's ICP, and deep-researches only the speakers at ICP-fit companies. Outputs a person-first HTML report with a 'why reach out' rationale per person.
license: MIT
---
# Event Prospecting
Take a conference URL → get a ranked list of people the AE should talk to, with a "why reach out" rationale per person.
**Required**: `BROWSERBASE_API_KEY` env var and the `browse` CLI installed (`npm install -g browse`). Use `browse cloud ...` for API calls and `browse open` / `browse get markdown` for JS-heavy speaker pages.
**Path rules**: Always use the full literal path in all Bash commands — NOT `~` or `$HOME` (both trigger "shell expansion syntax" approval prompts). Resolve the home directory once and use it everywhere. When constructing subagent prompts, replace `{SKILL_DIR}` with the full literal path (typically `/Users/jay/skills/skills/event-prospecting`).
**Output directory**: All event prospecting output goes to `~/Desktop/{event_slug}_prospects_{YYYY-MM-DD-HHMM}/`. Final deliverable is `index.html` (people grouped by company, ranked by company ICP), with `companies.html` and `people.html` (filterable) as alternate views, plus `results.csv` for cold-outbound import.
**CRITICAL — Tool restrictions (applies to main agent AND all subagents)**:
- All web searches: use `browse cloud search`. NEVER use WebSearch.
- All page content extraction: use `node {SKILL_DIR}/scripts/extract_page.mjs "<url>"`. This script fetches via `browse cloud fetch --output`, parses title + meta tags + visible body text, and automatically falls back to `browse get markdown` when fetch fails or returns thin JS-rendered content. NEVER hand-roll a `browse cloud fetch | sed` pipeline. NEVER use WebFetch.
- All research output: subagents write **one markdown file per company OR per person** to `{OUTPUT_DIR}/companies/{slug}.md` or `{OUTPUT_DIR}/people/{slug}.md` using bash heredoc. NEVER use the Write tool or `python3 -c`. See `references/example-research.md` for both file formats.
- Report compilation: use `node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --open`.
- **Subagents must use ONLY the Bash tool. No other tools allowed.**
- **HARD TOOL-CALL CAPS**: ICP triage = 1 call/company; deep research = 5 calls/company; person enrichment = 4 calls/person. See `references/workflow.md` for enforcement detail.
**CRITICAL — Anti-hallucination rules (applies to main agent AND all subagents)**:
- NEVER infer `product_description`, `industry`, or a person's `role_reason` from a site's fonts, framework, design system, or typography. These are cosmetic and say nothing about what the company sells or what the person does.
- NEVER let the user's own ICP leak into a target's description. If you don't know what the target does, write `Unknown` — do not pattern-match them onto the ICP.
- `product_description` MUST quote or paraphrase a specific phrase from `extract_page.mjs` output. If none of TITLE/META/OG/HEADINGS/BODY yield a recognizable product statement, write `Unknown — homepage content not accessible` and cap `icp_fit_score` at 3.
- A person's `hook` MUST quote or paraphrase a specific finding from a `browse cloud search` result (podcast title, blog headline, GitHub repo, talk abstract). If no public signal exists in the last 6 months, fall back to event-context (their talk title at this event).
**CRITICAL — Minimize permission prompts**:
- Subagents MUST batch ALL file writes into a SINGLE Bash call using chained heredocs. One Bash call = one permission prompt.
- Batch ALL searches and ALL fetches into single Bash calls using `&&` chaining.
## Pipeline Overview
Follow these 10 steps in order. Do not skip steps or reorder.
0. **Setup** — output dir + clean slate
1. **Load profile** — read `profiles/{user_slug}.json`
2. **Recon** — detect event platform
3. **Extract people** — `people.jsonl`
4. **Group by company** — `seed_companies.txt`
5. **ICP triage** — fast company-level scoring (1 call/company)
6. **Filter** — companies with `icp_fit_score >= --icp-threshold`
7. **Deep research** — full Plan→Research→Synthesize on ICP fits
8. **Enrich speakers** — ask user: ICP-fit only (default) or all speakers
9. **Compile report** — HTML + CSV, open in browser
The user invokes the skill with a URL like `/event-prospecting <URL>`. Parse `EVENT_URL` from that invocation message. Defaults: `DEPTH=deep`, `ICP_THRESHOLD=6`. The `USER_SLUG` (ICP profile) is auto-resolved in Step 1 from whatever profile files exist locally — there is no built-in default profile. Do NOT ask the user to confirm the URL — they already gave you it.
---
## Step 0: Setup Output Directory
Derive the output directory from the URL the user gave you. Do NOT hardcode any event name.
```bash
# EVENT_URL came from the invocation message (whatever the user typed after `/event-prospecting`)
EVENT_SLUG=$(node -e 'const h = new URL(process.argv[1]).hostname.replace(/^www\./,""); console.log(h.split(".")[0])' "$EVENT_URL")
TIMESTAMP=$(date +%Y-%m-%d-%H%M)
OUTPUT_DIR=/Users/jay/Desktop/${EVENT_SLUG}_prospects_${TIMESTAMP}
mkdir -p "$OUTPUT_DIR/companies" "$OUTPUT_DIR/people"
```
Use the full literal home path — never `~` or `$HOME`. Pass `{OUTPUT_DIR}` as the full literal path to all subagent prompts.
## Step 1: Load User Profile
The profile defines the ICP that ICP triage and deep research score against. Load from `{SKILL_DIR}/profiles/{user_slug}.json` (interchangeable across all GTM skills — same shape as company-research). `example.json` is a template, not a real profile — never use it.
**DO NOT look outside `{SKILL_DIR}/profiles/`** for profiles — never reach into other skills' directories. If a profile is needed elsewhere, the user copies it explicitly.
**Resolution order**:
1. If the user invoked with `--user-company <slug>`, use that slug.
2. Else, list `profiles/*.json` excluding `example.json`. If exactly one profile exists, use it (and tell the user which one). If multiple exist, ask the user (plain chat) which one.
3. If zero profiles exist, **fail loudly** and instruct the user to create one (copy `profiles/example.json` to `profiles/<your_slug>.json` and fill it in, or run the company-research skill which builds one automatically).
```bash
PROFILES=$(ls {SKILL_DIR}/profiles/*.json 2>/dev/null | xargs -n1 basename | sed 's/\.json$//' | grep -v '^example$')
COUNT=$(echo "$PROFILES" | grep -c .)
if [ -z "$USER_SLUG" ]; then
if [ "$COUNT" -eq 0 ]; then
echo "No profiles found in {SKILL_DIR}/profiles/. Copy profiles/example.json to profiles/<your_slug>.json and fill it in, or run the company-research skill to build one."
exit 1
elif [ "$COUNT" -eq 1 ]; then
USER_SLUG=$PROFILES
echo "Using the only profile available: ${USER_SLUG}"
else
echo "Multiple profiles found:"
echo "$PROFILES" | sed 's/^/ - /'
echo "Re-invoke with --user-company <slug> to pick one."
exit 1
fi
fi
test -f {SKILL_DIR}/profiles/${USER_SLUG}.json || {
echo "Profile not found: profiles/${USER_SLUG}.json"
exit 1
}
cat {SKILL_DIR}/profiles/${USER_SLUG}.json
```
The profile yields: `company`, `product`, `icp_description`, `existing_customers`. These get embedded verbatim in every subagent prompt downstream.
## Step 2: Recon
Detect the event platform and extraction strategy. One command:
```bash
node {SKILL_DIR}/scripts/recon.mjs {EVENT_URL} {OUTPUT_DIR}
```
Writes `{OUTPUT_DIR}/recon.json` with `platform`, `strategy`, and (for Next.js) `nextDataPaths`. See `references/event-platforms.md` for the platform catalog and detection priority.
Expected outcomes:
- Stripe Sessions class (Next.js): `platform: "next-data"`, 1-3 paths
- Sessionize: `platform: "sessionize"`
- Lu.ma / Eventbrite: `platform: "luma" | "eventbrite"`
- Anything else: `platform: "custom"`, `strategy: "markdown"` (best-effort fallback)
## Step 3: Extract People
```bash
node {SKILL_DIR}/scripts/extract_event.mjs {OUTPUT_DIR} --user-company {USER_SLUG}
```
Reads `recon.json`, dispatches to the platform-specific extractor, writes `people.jsonl` (one speaker per line) and `seed_companies.txt` (deduped companies).
The `--user-company` flag also drops the host-org's own employees (a Stripe-hosted event drops Stripe employees) and the user's own employees from the speaker list — those aren't prospects.
Sanity-check the output:
```bash
wc -l {OUTPUT_DIR}/people.jsonl {OUTPUT_DIR}/seed_companies.txt
head -3 {OUTPUT_DIR}/people.jsonl
```
If `people.jsonl` is empty or under ~10 lines, recon picked the wrong platform — see `references/event-platforms.md` and re-run with adjusted strategy.
## Step 4: Group by Company
`extract_event.mjs` emits `seed_companies.txt` already (one company per line, deduped, sorted). This step is informational — verify the count looks reasonable before fanning out:
```bash
wc -l {OUTPUT_DIR}/seed_companies.txt
```
Expected: roughly 0.4-0.6× the speaker count (most events have ~2 speakers per company on average, some companies send 5+, many send 1).
## Step 5: ICP Triage
**Fast pass — one tool call per company, no deep research.** Score every company in `seed_companies.txt` against the user's ICP and write a thin triage stub to `companies/{slug}.md`. Companies with `icp_fit_score >= --icp-threshold` (default 6) advance to Step 7's deep research; the rest stay as triage stubs.
**Dispatch pattern**: split `seed_companies.txt` into batches of ~10 and fan out N subagents in a SINGLE Agent batch (multiple Agent tool calls in one message). Each subagent runs the prompt from `references/workflow.md` → "ICP Triage" section. Hard cap: **1 tool call per company** (just `extract_page.mjs` on the homepage), enforced via the `# browse call N/1` comment pattern.
```bash
# Build batch files: each batch line is "name|guessed_homepage|slug".
# extract_event.mjs only emits company NAMES (no URLs), so we slugify and guess
# https://{slug-without-spaces}.com as the canonical homepage. The triage subagent
# is allowed to write product_description: "Unknown — homepage content not accessible"
# and cap score at 3 if the guessed URL 404s — that's the documented fallback in
# workflow.md (rule 3 of the ICP Triage prompt). Burning a real browse cloud search to
# discover the URL would bust the 1-call-per-company HARD CAP.
node -e '
const fs = require("fs");
const slugify = (s) => (s || "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
const seed = fs.readFileSync("{OUTPUT_DIR}/seed_companies.txt", "utf-8").split("\n").filter(Boolean);
const lines = seed.map(c => {
const slug = slugify(c);
const guessedHost = c.toLowerCase().replace(/[^a-z0-9]/g, "");
return `${c}|https://${guessedHost}.com|${slug}`;
});
fs.writeFileSync("{OUTPUT_DIR}/_seed_with_urls.txt", lines.join("\n") + "\n");
'
# Split into ~10-company batches
split -l 10 {OUTPUT_DIR}/_seed_with_urls.txt {OUTPUT_DIR}/_batch_triage_
# Count batches → number of subagents to dispatch (cap at 6 per message; second wave for the rest)
ls {OUTPUT_DIR}/_batch_triage_* | wc -l
```
Then in a single message, dispatch one Agent call per batch (up to 6 in parallel; subsequent waves after the first returns). Each Agent gets the prompt from `references/workflow.md` → "ICP Triage" with these substitutions before sending:
- `{SKILL_DIR}` → full literal skill path (e.g. `/Users/jay/skills/skills/event-prospecting`)
- `{OUTPUT_DIR}` → full literal output path
- `{USER_COMPANY}`, `{USER_PRODUCT}`, `{ICP_DESCRIPTION}` → from the loaded profile
- `{EVENT_NAME}` → `recon.json` `.title`
- `{COMPANY_LIST}` → contents of the batch file (e.g. `cat {OUTPUT_DIR}/_batch_triage_aa`)
- `{TOTAL}` → number of lines in this batch (substitute into `# browse call N/{TOTAL}`)
**Agent dispatch (skeleton, repeat per batch in one message)**:
```
Agent(
description: "ICP triage batch aa",
prompt: <ICP Triage prompt from workflow.md with all placeholders substituted>,
subagent_type: "general-purpose"
)
Agent(
description: "ICP triage batch ab",
prompt: <same prompt template, COMPANY_LIST swapped to batch ab>,
subagent_type: "general-purpose"
)
... up to 6 per message
```
After all subagents return, verify every company in `seed_companies.txt` has a corresponding `companies/{slug}.md`:
```bash
ls {OUTPUT_DIR}/companies/*.md | wc -l
# Should equal `wc -l {OUTPUT_DIR}/seed_companies.txt`
```
Clean up the batch files: `rm {OUTPUT_DIR}/_batch_triage_*`.
## Step 6: Filter by ICP Threshold
Read each `companies/*.md` frontmatter, keep those with `icp_fit_score >= 6` (or whatever `--icp-threshold` is). Write the surviving company slugs to `{OUTPUT_DIR}/icp_fits.txt`:
```bash
THRESHOLD=6 # from --icp-threshold flag
for f in {OUTPUT_DIR}/companies/*.md; do
score=$(awk '/^icp_fit_score:/{print $2; exit}' "$f")
if [ -n "$score" ] && [ "$score" -ge "$THRESHOLD" ]; then
basename "$f" .md
fi
done > {OUTPUT_DIR}/icp_fits.txt
wc -l {OUTPUT_DIR}/icp_fits.txt
```
Expected: 20-40% of `seed_companies.txt`. If the survival rate is < 10%, the threshold may be too high or the ICP description too narrow — surface a warning to the user.
## Step 7: Deep Research
Full Plan→Research→Synthesize on ICP-fit companies only. Hard cap: **5 tool calls per company** (homepage extract + 2-3 sub-question searches + 1-2 supplementary fetches). Subagents OVERWRITE the existing `companies/{slug}.md` triage stub with the richer deep-research version (frontmatter `triage_only: false`).
**Dispatch pattern**: split `icp_fits.txt` into batches of ~5 (deep mode default) and fan out one Agent per batch in a SINGLE message (up to 6 Agents per message). Each Agent gets the prompt from `references/workflow.md` → "Deep Research" with these substitutions:
- `{SKILL_DIR}`, `{OUTPUT_DIR}`, `{USER_COMPANY}`, `{USER_PRODUCT}`, `{ICP_DESCRIPTION}`
- `{EVENT_NAME}` (from `recon.json` `.title`), `{EVENT_CONTEXT}` (track / topic, manually inferred from the event homepage)
- `{COMPANY_LIST}` → contents of the batch file (each line `slug|website`)
```bash
# Build {company-slug|website} pairs by reading frontmatter from each triage stub
while read slug; do
website=$(awk '/^website:/{print $2; exit}' {OUTPUT_DIR}/companies/${slug}.md)
echo "${slug}|${website}"
done < {OUTPUT_DIR}/icp_fits.txt > {OUTPUT_DIR}/_deep_targets.txt
# Split into ~5-company batches (deep mode)
split -l 5 {OUTPUT_DIR}/_deep_targets.txt {OUTPUT_DIR}/_batch_deep_
ls {OUTPUT_DIR}/_batch_deep_* | wc -l
```
**Agent dispatch (skeleton, repeat per batch in one message)**:
```
Agent(
description: "Deep research batch aa",
prompt: <Deep Research prompt from workflow.md with all placeholders substituted; COMPANY_LIST = cat _batch_deep_aa>,
subagent_type: "general-purpose"
)
Agent(
description: "Deep research batch ab",
prompt: <same template, COMPANY_LIST = cat _batch_deep_ab>,
subagent_type: "general-purpose"
)
... up to 6 per message; second wave after the first returns
```
After all subagents return, verify the deep-research files exist and have `triage_only: false`:
```bash
grep -l "triage_only: false" {OUTPUT_DIR}/companies/*.md | wc -l
# Should equal wc -l icp_fits.txt
```
## Step 8: Enrich Speakers
Per person: harvest LinkedIn URL, recent activity (podcast / blog / talk / GitHub / X), and write `people/{slug}.md`. Hard cap: **4 tool calls per person**, three lanes:
1. `browse cloud search "{name} {company} linkedin"` (always)
2. `browse cloud search "{name} podcast OR talk OR blog 2026"` (deep+)
3. `browse cloud search "{name} github"` (deeper)
4. `browse cloud search "{name} site:x.com OR site:twitter.com"` (deeper, best-effort)
Quick mode: skip Step 8 entirely. Deep mode: lanes 1-2. Deeper mode: lanes 1-4.
### Step 8a — Ask the user: scope of enrichment
Before dispatching, compute the two candidate counts and ask the user to choose. The default is **ICP-fit only** (faster, cheaper, what most users want); enriching every speaker is opt-in because cost scales linearly with people enriched.
```bash
TOTAL=$(wc -l < {OUTPUT_DIR}/people.jsonl)
ICP_FITS=$(node -e '
const fs = require("fs");
const fits = new Set(fs.readFileSync("{OUTPUT_DIR}/icp_fits.txt", "utf-8").split("\n").filter(Boolean));
const slug2name = {};
for (const slug of fits) {
const md = fs.readFileSync(`{OUTPUT_DIR}/companies/${slug}.md`, "utf-8");
const m = md.match(/^company_name:\s*(.+)$/m);
if (m) slug2name[slug] = m[1].trim();
}
const want = new Set(Object.values(slug2name).map(s => s.toLowerCase()));
const ppl = fs.readFileSync("{OUTPUT_DIR}/people.jsonl","utf-8").split("\n").filter(Boolean).map(JSON.parse);
console.log(ppl.filter(p => p.company && want.has(p.company.toLowerCase())).length);
')
# Lanes per person: 2 (deep) or 4 (deeper) — match {DEPTH}
LANES=2 # or 4 for deeper
echo "ICP fits: ${ICP_FITS} speakers × ${LANES} = $((ICP_FITS * LANES)) calls"
echo "All: ${TOTAL} speakers × ${LANES} = $((TOTAL * LANES)) calls"
```
Then ask via `AskUserQuestion` — clean two-option choice with the quantified cost on each:
```
AskUserQuestion(questions: [
{
question: "Enrich which speakers?",
header: "Enrichment scope",
multiSelect: false,
options: [
{ label: "ICP fits only", description: "${ICP_FITS} speakers, ~$((ICP_FITS * LANES)) calls (recommended)" },
{ label: "All speakers", description: "${TOTAL} speakers, ~$((TOTAL * LANES)) calls" }
]
}
])
```
Save the chosen scope as `ENRICH_SCOPE=icp_fits` or `ENRICH_SCOPE=all`. If the user picks "All speakers" and `TOTAL × LANES > 600`, print a warning and ask once more — that's a 10+ minute run with hundreds of tool calls.
### Step 8b — Filter and batch
```bash
# Build _people_to_enrich.jsonl based on ENRICH_SCOPE
if [ "$ENRICH_SCOPE" = "all" ]; then
cp {OUTPUT_DIR}/people.jsonl {OUTPUT_DIR}/_people_to_enrich.jsonl
else
node -e '
const fs = require("fs");
const fits = new Set(fs.readFileSync("{OUTPUT_DIR}/icp_fits.txt", "utf-8").split("\n").filter(Boolean));
const slug2name = {};
for (const slug of fits) {
const md = fs.readFileSync(`{OUTPUT_DIR}/companies/${slug}.md`, "utf-8");
const m = md.match(/^company_name:\s*(.+)$/m);
if (m) slug2name[slug] = m[1].trim();
}
const wantNames = new Set(Object.values(slug2name).map(s => s.toLowerCase()));
const lines = fs.readFileSync("{OUTPUT_DIR}/people.jsonl", "utf-8").split("\n").filter(Boolean);
const keep = lines.filter(l => {
const p = JSON.parse(l);
return p.company && wantNames.has(p.company.toLowerCase());
});
fs.writeFileSync("{OUTPUT_DIR}/_people_to_enrich.jsonl", keep.join("\n") + "\n");
console.error(`Enriching ${keep.length} of ${lines.length} speakers`);
'
fi
# Split into ~5-person batches
split -l 5 {OUTPUT_DIR}/_people_to_enrich.jsonl {OUTPUT_DIR}/_batch_people_
```
Then in a single message, dispatch one Agent call per batch (up to 6 per message) with the prompt from `references/workflow.md` → "Person Enrichment". Each subagent's prompt should include:
- `{SKILL_DIR}`, `{OUTPUT_DIR}`, `{DEPTH}` (`deep` | `deeper`)
- `{USER_COMPANY}`, `{USER_PRODUCT}`, `{ICP_DESCRIPTION}`
- `{EVENT_NAME}` (from `recon.json` `.title`)
- `{LANES}` → `2` for deep mode, `4` for deeper mode (substituted into `# browse call N/{LANES}`)
- `{PEOPLE_BATCH}` → contents of `_batch_people_aa` (each line a JSON record from `people.jsonl`)
**Agent dispatch (skeleton, repeat per batch in one message)**:
```
Agent(
description: "Person enrichment batch aa",
prompt: <Person Enrichment prompt from workflow.md with all placeholders substituted; PEOPLE_BATCH = cat _batch_people_aa>,
subagent_type: "general-purpose"
)
Agent(
description: "Person enrichment batch ab",
prompt: <same template, PEOPLE_BATCH = cat _batch_people_ab>,
subagent_type: "general-purpose"
)
... up to 6 per message
```
After all subagents return, verify the people files exist:
```bash
ls {OUTPUT_DIR}/people/*.md | wc -l
# Should equal wc -l _people_to_enrich.jsonl
```
## Step 9: Compile Report
Generate the company-grouped HTML index, alternate views, and CSV in one command:
```bash
node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --open
```
This generates:
- `{OUTPUT_DIR}/index.html` — people grouped by company, ranked by company ICP score (opens in browser)
- `{OUTPUT_DIR}/people.html` — filterable speaker list (alternate view)
- `{OUTPUT_DIR}/companies.html` — ICP-ranked company table with attendees
- `{OUTPUT_DIR}/results.csv` — cold-outbound-ready spreadsheet
Then present a summary in chat:
```
## Event Prospecting Complete — {Event Name}
- **Total speakers extracted**: {count}
- **Unique companies**: {count}
- **ICP fits (score ≥ {threshold})**: {count}
- **Speakers enriched**: {count}
- **Score distribution** (companies):
- Strong fit (8-10): {count}
- Partial fit (5-7): {count}
- Weak fit (1-4): {count}
- **Report opened in browser**: {OUTPUT_DIR}/index.html
```
Show the **top 5 people cards** as a markdown table sorted by company ICP score, then offer to:
- Adjust `--icp-threshold` and re-run Steps 6-9
- Export the CSV to a CRM
event-prospectingをインストール
スキルファイルをダウンロードし、.claude/skills/ ディレクトリに解凍してください。
ZIPをダウンロードリポジトリをクローンし、スキルファイルをプロジェクトにコピーしてください。
git clone https://github.com/browserbase/skills/tree/main/skills/event-prospecting # Copy SKILL.md to your .claude/skills/ directory
コピー





家
