event-prospecting

Skill de prospection événementielle. Prend l'URL d'une page de speakers d'une conférence / d'un événement, extrait les personnes, filtre leurs entreprises par rapport à l'ICP de l'utilisateur, puis effectue une recherche approfondie uniquement sur les speakers dont les entreprises correspondent à l'ICP. Produit un rapport HTML centré sur les personnes, où chaque carte répond à la question « pourquoi l'AE devrait-il parler à cette personne ? » avec tous les liens publics et un bouton d'envoi de DM en un clic. À utiliser lorsque l'utilisateur souhaite : (1) trouver des leads lors d'une conférence spécifique, (2) se préparer pour un événement, (3) rechercher des speakers d'un événement, (4) construire une liste de cibles à partir d'une page de sponsors/exposants, (5) scraper les speakers d'une conférence et les classer par adéquation avec l'ICP. Déclencheurs : « find leads at {event} », « research speakers at », « prospect this conference », « stripe sessions leads », « ai engineer summit prospects », « event prospecting », « scrape conference speakers », « who should I meet at ».

npx skills add https://github.com/browserbase/skills --skill event-prospecting

Prospection d'événements

Prenez l'URL d'une conférence → récupérez une liste classée de personnes avec lesquelles l'AE devrait discuter, avec une justification « pourquoi contacter » par personne.

Requis : variable d'environnement BROWSERBASE_API_KEY, CLI bb installé (@browserbasehq/cli), et CLI browse installé (@browserbasehq/browse-cli) pour les pages de conférenciers chargées en JS (la plupart des sites d'événements modernes).

Règles de chemin : utilisez toujours le chemin littéral complet dans toutes les commandes Bash — JAMAIS ~ ou $HOME (les deux déclenchent des invites d'approbation « syntaxe d'expansion shell »). Résolvez le répertoire home une fois et utilisez-le partout. Lors de la construction de prompts de sous-agents, remplacez {SKILL_DIR} par le chemin littéral complet (généralement /Users/jay/skills/skills/event-prospecting).

Répertoire de sortie : toutes les sorties de prospection d'événement vont à ~/Desktop/{event_slug}_prospects_{YYYY-MM-DD-HHMM}/. Le livrable final est index.html (personnes groupées par entreprise, classées par ICP d'entreprise), avec companies.html et people.html (filtrables) comme vues alternatives, plus results.csv pour l'import en cold-outbound.

CRITIQUE — Restrictions d'outils (s'appliquent au agent principal ET à tous les sous-agents) :

  • Toutes les recherches web : utilisez bb search. N'utilisez JAMAIS WebSearch.
  • Toute extraction de contenu de page : utilisez node {SKILL_DIR}/scripts/extract_page.mjs "<url>". Ce script récupère via bb fetch, analyse le titre + méta-balises + texte visible du corps, et bascule automatiquement vers bb browse quand la page est rendue en JS ou dépasse 1 Mo. N'improvisez JAMAIS un pipeline bb fetch | sed. N'utilisez JAMAIS WebFetch.
  • Toute sortie de recherche : les sous-agents écrivent un fichier markdown par entreprise OU par personne vers {OUTPUT_DIR}/companies/{slug}.md ou {OUTPUT_DIR}/people/{slug}.md en utilisant heredoc bash. N'utilisez JAMAIS l'outil Write ou python3 -c. Consultez references/example-research.md pour les deux formats de fichier.
  • Compilation de rapport : utilisez node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --open.
  • Les sous-agents ne doivent utiliser QUE l'outil Bash. Aucun autre outil autorisé.
  • LIMITES DURES D'APPELS D'OUTILS : tri ICP = 1 appel/entreprise ; recherche approfondie = 5 appels/entreprise ; enrichissement de personne = 4 appels/personne. Consultez references/workflow.md pour les détails d'application.

CRITIQUE — Règles anti-hallucination (s'appliquent au agent principal ET à tous les sous-agents) :

  • NE JAMAIS inférez product_description, industry, ou la role_reason d'une personne à partir des polices, frameworks, systèmes de design ou typographie d'un site. Ce sont des éléments cosmétiques qui ne disent rien sur ce que l'entreprise vend ou ce que la personne fait.
  • NE JAMAIS laissez l'ICP de l'utilisateur lui-même s'infiltrer dans la description d'une cible. Si vous ne savez pas ce que la cible fait, écrivez Unknown — ne les feuilletez PAS selon l'ICP.
  • product_description DOIT citer ou paraphraser une phrase spécifique de la sortie extract_page.mjs. Si aucun de TITLE/META/OG/HEADINGS/BODY ne produit une déclaration de produit reconnaissable, écrivez Unknown — homepage content not accessible et plafonnez icp_fit_score à 3.
  • Le hook d'une personne DOIT citer ou paraphraser une découverte spécifique d'un résultat bb search (titre de podcast, titre de blog, repo GitHub, résumé de présentation). Si aucun signal public n'existe dans les 6 derniers mois, revenez au contexte d'événement (son titre de présentation à cet événement).

CRITIQUE — Minimisez les invites de permission :

  • Les sous-agents DOIVENT regrouper TOUTES les écritures de fichiers en UN SEUL appel Bash en utilisant des heredocs chaînés. Un appel Bash = une invite de permission.
  • Regroupez TOUTES les recherches et TOUTES les récupérations en appels Bash uniques en utilisant le chaînage &&.

Aperçu du pipeline

Suivez ces 10 étapes dans l'ordre. Ne sautez pas les étapes ni ne les réorganisez.

  1. Configuration — répertoire de sortie + ardoise vierge
  2. Charger le profil — lire profiles/{user_slug}.json
  3. Reconnaissance — détecter la plateforme d'événement
  4. Extraire les personnespeople.jsonl
  5. Grouper par entrepriseseed_companies.txt
  6. Tri ICP — notation rapide au niveau de l'entreprise (1 appel/entreprise)
  7. Filtrer — entreprises avec icp_fit_score >= --icp-threshold
  8. Recherche approfondie — Plan→Recherche→Synthèse complet sur les correspondances ICP
  9. Enrichir les conférenciers — demander à l'utilisateur : ICP uniquement (par défaut) ou tous les conférenciers
  10. Compiler le rapport — HTML + CSV, ouvrir dans le navigateur

L'utilisateur invoque le skill avec une URL comme /event-prospecting <URL>. Analysez EVENT_URL du message d'invocation. Défauts : DEPTH=deep, ICP_THRESHOLD=6. Le USER_SLUG (profil ICP) est résolu automatiquement à l'étape 1 à partir de tous les fichiers de profil existants localement — il n'y a pas de profil par défaut intégré. NE DEMANDEZ PAS à l'utilisateur de confirmer l'URL — il vous l'a déjà donnée.


Étape 0 : Configuration du répertoire de sortie

Dérivez le répertoire de sortie de l'URL que l'utilisateur vous a donnée. NE CODEZ PAS EN DUR aucun nom d'événement.

# EVENT_URL provient du message d'invocation (tout ce que l'utilisateur a tapé après `/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"

Utilisez le chemin home littéral complet — jamais ~ ou $HOME. Passez {OUTPUT_DIR} comme chemin littéral complet à tous les prompts de sous-agents.

Étape 1 : Charger le profil utilisateur

Le profil définit l'ICP contre lequel le tri ICP et la recherche approfondie évaluent. Chargez depuis {SKILL_DIR}/profiles/{user_slug}.json (interchangeable dans tous les skills GTM — même forme que la recherche d'entreprise). example.json est un modèle, pas un vrai profil — ne l'utilisez jamais.

NE CHERCHEZ PAS en dehors de {SKILL_DIR}/profiles/ pour les profils — n'allez jamais dans les répertoires d'autres skills. Si un profil est nécessaire ailleurs, l'utilisateur le copie explicitement.

Ordre de résolution :

  1. Si l'utilisateur a invoqué avec --user-company <slug>, utilisez ce slug.
  2. Sinon, listez profiles/*.json en excluant example.json. Si exactement un profil existe, utilisez-le (et dites à l'utilisateur lequel). S'il en existe plusieurs, demandez à l'utilisateur (chat ordinaire) lequel choisir.
  3. Si zéro profil existe, échouez bruyamment et instruisez l'utilisateur de créer un (copiez profiles/example.json vers profiles/<votre_slug>.json et remplissez-le, ou exécutez le skill company-research qui en crée un automatiquement).
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

Le profil produit : company, product, icp_description, existing_customers. Ceux-ci sont intégrés mot pour mot dans chaque prompt de sous-agent en aval.

Étape 2 : Reconnaissance

Détectez la plateforme d'événement et la stratégie d'extraction. Une commande :

node {SKILL_DIR}/scripts/recon.mjs {EVENT_URL} {OUTPUT_DIR}

Écrit {OUTPUT_DIR}/recon.json avec platform, strategy, et (pour Next.js) nextDataPaths. Consultez references/event-platforms.md pour le catalogue de plateformes et la priorité de détection.

Résultats attendus :

  • Stripe Sessions class (Next.js) : platform: "next-data", 1-3 chemins
  • Sessionize : platform: "sessionize"
  • Lu.ma / Eventbrite : platform: "luma" | "eventbrite"
  • Autre : platform: "custom", strategy: "markdown" (fallback au meilleur effort)

Étape 3 : Extraire les personnes

node {SKILL_DIR}/scripts/extract_event.mjs {OUTPUT_DIR} --user-company {USER_SLUG}

Lit recon.json, envoie à l'extracteur spécifique à la plateforme, écrit people.jsonl (un conférencier par ligne) et seed_companies.txt (entreprises dédupliquées).

L'option --user-company supprime également les employés de l'organisation hôte (un événement hébergé par Stripe supprime les employés Stripe) et les employés de l'utilisateur de la liste des conférenciers — ce ne sont pas des prospects.

Vérifiez la sortie :

wc -l {OUTPUT_DIR}/people.jsonl {OUTPUT_DIR}/seed_companies.txt
head -3 {OUTPUT_DIR}/people.jsonl

Si people.jsonl est vide ou contient moins de ~10 lignes, la reconnaissance a choisi la mauvaise plateforme — consultez references/event-platforms.md et relancez avec une stratégie ajustée.

Étape 4 : Grouper par entreprise

extract_event.mjs émet déjà seed_companies.txt (une entreprise par ligne, dédupliquée, triée). Cette étape est informative — vérifiez que le nombre semble raisonnable avant de se disperser :

wc -l {OUTPUT_DIR}/seed_companies.txt

Attendu : approximativement 0,4-0,6× le nombre de conférenciers (la plupart des événements ont ~2 conférenciers par entreprise en moyenne, certaines entreprises en envoient 5+, beaucoup en envoient 1).

Étape 5 : Tri ICP

Passage rapide — un appel d'outil par entreprise, sans recherche approfondie. Notez chaque entreprise dans seed_companies.txt selon l'ICP de l'utilisateur et écrivez un stub de tri fin vers companies/{slug}.md. Les entreprises avec icp_fit_score >= --icp-threshold (par défaut 6) avancent vers la recherche approfondie de l'étape 7 ; les autres restent comme des stubs de tri.

Motif de dispatch : divisez seed_companies.txt en lots d'~10 et dispersez N sous-agents en UN SEUL batch d'Agent (plusieurs appels Agent tool en un message). Chaque sous-agent exécute le prompt de references/workflow.md → section « ICP Triage ». Limite dure : 1 appel d'outil par entreprise (juste extract_page.mjs sur la page d'accueil), appliquée via le motif de commentaire # bb call N/1.

# Construire des fichiers de batch : chaque ligne du batch est "name|guessed_homepage|slug".
# extract_event.mjs n'émet que des NOMS d'entreprise (pas d'URL), donc nous slugifions et devinons
# https://{slug-without-spaces}.com comme page d'accueil canonique. Le sous-agent de tri
# est autorisé à écrire product_description: "Unknown — homepage content not accessible"
# et plafonner le score à 3 si l'URL devinée renvoie 404 — c'est le fallback documenté dans
# workflow.md (règle 3 du prompt ICP Triage). Brûler une vraie bb search pour
# découvrir l'URL casserait la LIMITE DURE de 1 appel par entreprise.
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");
'

# Diviser en lots d'~10 entreprises
split -l 10 {OUTPUT_DIR}/_seed_with_urls.txt {OUTPUT_DIR}/_batch_triage_

# Compter les lots → nombre de sous-agents à dispatcher (plafonner à 6 par message ; deuxième vague pour le reste)
ls {OUTPUT_DIR}/_batch_triage_* | wc -l

Ensuite, en un seul message, dispersez un appel Agent par lot (jusqu'à 6 en parallèle ; les vagues suivantes après le retour de la première). Chaque Agent obtient le prompt de references/workflow.md → « ICP Triage » avec ces substitutions avant d'envoyer :

  • {SKILL_DIR} → chemin littéral complet du skill (par ex. /Users/jay/skills/skills/event-prospecting)
  • {OUTPUT_DIR} → chemin littéral complet de sortie
  • {USER_COMPANY}, {USER_PRODUCT}, {ICP_DESCRIPTION} → du profil chargé
  • {EVENT_NAME}.title de recon.json
  • {COMPANY_LIST} → contenu du fichier de lot (par ex. cat {OUTPUT_DIR}/_batch_triage_aa)
  • {TOTAL} → nombre de lignes dans ce lot (remplacé dans # bb call N/{TOTAL})

Dispatch d'Agent (squelette, répéter par lot en un 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"
)
... jusqu'à 6 par message

Après le retour de tous les sous-agents, vérifiez que chaque entreprise dans seed_companies.txt a un companies/{slug}.md correspondant :

ls {OUTPUT_DIR}/companies/*.md | wc -l
# Devrait être égal à `wc -l {OUTPUT_DIR}/seed_companies.txt`

Nettoyez les fichiers de lot : rm {OUTPUT_DIR}/_batch_triage_*.

Étape 6 : Filtrer par seuil ICP

Lisez chaque frontmatter de companies/*.md, conservez ceux avec icp_fit_score >= 6 (ou quel que soit le --icp-threshold). Écrivez les slugs d'entreprise survivants vers {OUTPUT_DIR}/icp_fits.txt :

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

Attendu : 20-40% de seed_companies.txt. Si le taux de survie est < 10%, le seuil peut être trop élevé ou la description ICP trop étroite — surfacez un avertissement à l'utilisateur.

Étape 7 : Recherche approfondie

Plan→Recherche→Synthèse complet sur les entreprises correspondant à l'ICP uniquement. Limite dure : 5 appels d'outil par entreprise (extraction de page d'accueil + 2-3 recherches de sous-questions + 1-2 récupérations supplémentaires). Les sous-agents RÉÉCRIVENT le stub de tri companies/{slug}.md existant avec la version plus riche de recherche approfondie (frontmatter triage_only: false).

Motif de dispatch : divisez icp_fits.txt en lots d'~5 (mode deep par défaut) et dispersez un Agent par lot en UN SEUL message (jusqu'à 6 Agents par message). Chaque Agent obtient le prompt de references/workflow.md → « Deep Research » avec ces substitutions :

  • {SKILL_DIR}, {OUTPUT_DIR}, {USER_COMPANY}, {USER_PRODUCT}, {ICP_DESCRIPTION}
  • {EVENT_NAME} (de .title recon.json), {EVENT_CONTEXT} (piste / sujet, déduit manuellement de la page d'accueil d'événement)
  • {COMPANY_LIST} → contenu du fichier de lot (chaque ligne slug|website)
# Construire des paires {company-slug|website} en lisant le frontmatter de chaque stub de tri
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

# Diviser en lots d'~5 entreprises (mode deep)
split -l 5 {OUTPUT_DIR}/_deep_targets.txt {OUTPUT_DIR}/_batch_deep_
ls {OUTPUT_DIR}/_batch_deep_* | wc -l

Dispatch d'Agent (squelette, répéter par lot en un 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"
)
... jusqu'à 6 par message ; deuxième vague après le retour de la première

Après le retour de tous les sous-agents, vérifiez que les fichiers de recherche approfondie existent et ont triage_only: false :

grep -l "triage_only: false" {OUTPUT_DIR}/companies/*.md | wc -l
# Devrait être égal à wc -l icp_fits.txt

Étape 8 : Enrichir les conférenciers

Par personne : moissonnez l'URL LinkedIn, l'activité récente (podcast / blog / présentation / GitHub / X), et écrivez people/{slug}.md. Limite dure : 4 appels d'outil par personne, trois voies :

  1. bb search "{name} {company} linkedin" (toujours)
  2. bb search "{name} podcast OR talk OR blog 2026" (deep+)
  3. bb search "{name} github" (deeper)
  4. bb search "{name} site:x.com OR site:twitter.com" (deeper)

Mode rapide : sautez entièrement l'étape 8. Mode deep : voies 1-2. Mode deeper : voies 1-4.

Étape 8a — Demander à l'utilisateur : étendue de l'enrichissement

Avant de dispatcher, calculez les deux nombre de candidats et demandez à l'utilisateur de choisir. La valeur par défaut est ICP uniquement (plus rapide, moins cher, ce que la plupart des utilisateurs veulent) ; enrichir chaque conférencier est opt-in car le coût évolue linéairement avec le nombre de personnes enrichies.

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);
')

# Voies par personne : 2 (deep) ou 4 (deeper) — match {DEPTH}
LANES=2   # ou 4 pour deeper
echo "ICP fits: ${ICP_FITS} speakers × ${LANES} = $((ICP_FITS * LANES)) calls"
echo "All:      ${TOTAL} speakers × ${LANES} = $((TOTAL * LANES)) calls"

Ensuite, demandez via AskUserQuestion — un choix pur à deux options avec le coût quantifié sur chacun :

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" }
    ]
  }
])

Sauvegardez l'étendue choisie comme ENRICH_SCOPE=icp_fits ou ENRICH_SCOPE=all. Si l'utilisateur choisit « All speakers » et TOTAL × LANES > 600, affichez un avertissement et demandez une fois de plus — c'est une exécution 10+ minutes avec des centaines d'appels d'outils.

Étape 8b — Filtrer et grouper en lots

# Construire _people_to_enrich.jsonl basé sur 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

# Diviser en lots d'~5 personnes
split -l 5 {OUTPUT_DIR}/_people_to_enrich.jsonl {OUTPUT_DIR}/_batch_people_

Ensuite, en un seul message, dispersez un appel Agent par lot (jusqu'à 6 par message) avec le prompt de references/workflow.md → « Person Enrichment ». Le prompt de chaque sous-agent devrait inclure :

  • {SKILL_DIR}, {OUTPUT_DIR}, {DEPTH} (deep | deeper)
  • {USER_COMPANY}, {USER_PRODUCT}, {ICP_DESCRIPTION}
  • {EVENT_NAME} (de .title recon.json)
  • {LANES}2 pour le mode deep, 4 pour le mode deeper (remplacé dans # bb call N/{LANES})
  • {PEOPLE_BATCH} → contenu de _batch_people_aa (chaque ligne un enregistrement JSON de people.jsonl)

Dispatch d'Agent (squelette, répéter par lot en un 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"
)
... jusqu'à 6 par message

Après le retour de tous les sous-agents, vérifiez que les fichiers de personnes existent :

ls {OUTPUT_DIR}/people/*.md | wc -l
# Devrait être égal à wc -l _people_to_enrich.jsonl

Étape 9 : Compiler le rapport

Générez l'index HTML groupé par entreprise, les vues alternatives et le CSV en une seule commande :

node {SKILL_DIR}/scripts/compile_report.mjs {OUTPUT_DIR} --open

Ceci génère :

  • {OUTPUT_DIR}/index.html — personnes groupées par entreprise, classées par score ICP d'entreprise (s'ouvre dans le navigateur)
  • {OUTPUT_DIR}/people.html — liste de conférenciers filtrables (vue alternative)
  • {OUTPUT_DIR}/companies.html — tableau d'entreprises classées par ICP avec participants
  • {OUTPUT_DIR}/results.csv — feuille de calcul prête pour cold-outbound

Ensuite, présentez un résumé en 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

Affichez les 5 premières cartes de personnes sous forme de tableau markdown trié par score ICP d'entreprise, puis proposez de :

  • Ajuster --icp-threshold et relancer les étapes 6-9
  • Exporter le CSV vers un CRM

Skills similaires