feat: event-prospecting skill v0.1#78
Conversation
Spawns parallel Claude subagents against a target docs/SDK/SKILL.md from a one-sentence prompt, captures structured traces, and renders a graded HTML report scoring Setup Friction, Speed, Efficiency, Error Recovery, and Doc Quality. Includes narrative cross-agent review to surface convergent hallucinations and silent workarounds the JSON self-report misses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pre-event prospecting skill that wraps company-research: - Recon event URL + extract people via platform-specific shortcuts (Next.js __NEXT_DATA__, Sessionize API, Lu.ma JSON-LD) - Company-first ICP filter before person enrichment (~45% cheaper than enrich-everyone) - Person-first HTML report with 3-bullet "why reach out" + DM opener + clipboard "research deeper" trigger Validated on Stripe Sessions: 4 browse commands extracted 240 speakers / 99 companies in 6s. Reuses extract_page.mjs, compile_report.mjs, profiles, and the Plan→Research→Synthesize pattern from company-research. Sibling event-follow-up skill (post-event artifacts → CRM-ready notes) explicitly out of scope for v0.1.
5-phase TDD-style plan: scaffolding+recon → extract+group → ICP triage delegated to company-research → person enrichment + HTML report → end-to-end validation on Stripe Sessions. Each phase produces a runnable artifact. Tool-call caps + format normalization patterns inherited from competitor-analysis.
Three fixes per skill-creator principles: - New Task A5 creates references/event-platforms.md (was named in the design doc but had no creation task) - Task C2 now copies the Plan→Research→Synthesize block VERBATIM from company-research instead of cross-referencing its filesystem path at runtime — skills must be self-contained - Tasks A5 and C2 both gain explicit "add TOC" steps for files that will exceed 100 lines (skill-creator requirement)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…time
Step 5's batch builder previously read p.companyUrl / p.website from
people.jsonl, but extract_event.mjs only emits {name,title,company,
linkedin,bio,slug} — no URL field. Result: every triage subagent got
empty URLs after the | separator and would either guess wildly or burn
a second tool call to discover the homepage, busting the 1-call
HARD CAP.
Fix: slugify the company name and guess https://{name-no-spaces}.com.
Most common names map correctly; the few that 404 hit the documented
'Unknown — homepage content not accessible' fallback in workflow.md
rule 3. Also add a third field (slug) to the batch line so subagents
write to the canonical filename without re-slugifying.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 4 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2a8ed25. Configure here.
| if (depth === 'deeper') { | ||
| const r3 = bbSearch(`"${name}" github`); | ||
| const r4 = bbSearch(`"${name}" site:x.com OR site:twitter.com`); | ||
| out.links = { ...out.links, ...harvestLinks([...(r3.results || []), ...(r4.results || [])]) }; |
There was a problem hiding this comment.
Lane 3 spread overwrites previously harvested links with null
Medium Severity
In deeper mode, Lane 3 merges links via { ...out.links, ...harvestLinks([...]) }. The harvestLinks function always initializes a fresh object with linkedin: linkedinIn || null (and other fields as null). When linkedinIn is empty (the default), any LinkedIn URL discovered in Lane 1 gets overwritten with null by the spread from Lane 3's harvestLinks return, since the GitHub/X search results are unlikely to also contain a LinkedIn URL.
Reviewed by Cursor Bugbot for commit 2a8ed25. Configure here.
| for (const row of deduped) { | ||
| csvLines.push(cols.map(c => csvEscape(row[c] || '')).join(',')); | ||
| } | ||
| writeFileSync(join(dir, 'results.csv'), csvLines.join('\n') + '\n'); |
There was a problem hiding this comment.
CSV export contains only company data, missing people
Medium Severity
The results.csv iterates over deduped (the companies array) and only writes company-level fields. The SKILL.md and design doc describe this CSV as "cold-outbound-ready," but cold outbound requires person-level data — name, title, company, LinkedIn URL, hook, and DM opener. As written, the CSV is a company scorecard, not an actionable prospect list.
Reviewed by Cursor Bugbot for commit 2a8ed25. Configure here.
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Company Research — {{COMPANY_NAME}}</title> |
There was a problem hiding this comment.
Report template title and footer reference wrong skill
Low Severity
The report-template.html was copied from company-research without updating the <title> tag (still says "Company Research — {{COMPANY_NAME}}") or the footer (still credits company-research). The compile_report.mjs replaces {{COMPANY_NAME}} but can't fix the hardcoded "Company Research" prefix, so the browser tab title is wrong for every generated report.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 2a8ed25. Configure here.
| <div class="stat"><div class="label">Completed</div><div class="value ok">{{COMPLETED_COUNT}}</div></div> | ||
| <div class="stat"><div class="label">Stuck</div><div class="value warn">{{STUCK_COUNT}}</div></div> | ||
| <div class="stat"><div class="label">Errored</div><div class="value bad">{{ERRORED_COUNT}}</div></div> | ||
| </div> |
There was a problem hiding this comment.
Audit template missing critical narrative review placeholder
Medium Severity
The SKILL.md Step 9 references {{NARRATIVE_REVIEW_SECTION}} and {{AGENT_TRACES_SECTION}} as placeholders to fill in the template, but neither exists in report-template.html. The narrative review is described as "CRITICAL" (Step 6.5) and should appear "right after the scorecard," yet there is no placeholder between the scorecard and the executive summary sections where it would be inserted.
Reviewed by Cursor Bugbot for commit 2a8ed25. Configure here.


event-prospecting — design
Status: approved 2026-04-25
Sibling skills: company-research, cold-outbound, account-positioning, competitor-analysis, github-stargazers
Path:
/Users/jay/skills/skills/event-prospecting/Purpose
Take a conference / event speakers URL, extract the people, filter their companies against the user's ICP, then deep-research only the people at ICP-fit companies. Output a person-first HTML report where each card answers "why should the AE talk to this person?" with all their public links and a one-click DM opener.
Architectural shape: a thin front-end (event recon + extract) and back-end (person enrichment + HTML) wrapped around the company-research backend. Most of the cost lives in company-research; this skill is glue + a different report.
What problem this solves
GTM teams scrape conference speaker lists into spreadsheets manually or via Clay / Apify actors. The work that follows — figuring out which speakers actually matter for THIS sender, what the wedge is, and how to open the conversation — stays manual. This skill collapses that to one command per event.
Five gaps this targets (per find-skills research, 2026-04-25):
v0.1 hits #1, #3, #5. #2 and #4 are v0.2 candidates.
Pipeline (10 steps)
~/Desktop/{event_slug}_prospects_{YYYY-MM-DD-HHMM}/profiles/{slug}.json. Fail loudly if missing — point at company-research to build one.__NEXT_DATA__, Sessionize public API, Lu.ma JSON-LD, Eventbrite JSON-LD, custom). Persistrecon.json.browsecommands extract structured speaker JSON. Outputpeople.jsonl..company→ unique seed company list (e.g. 240 people → 99 companies).icp_fit_score >= --icp-threshold(default 6).companies/{slug}.mdwith frontmatter scores.references/research-patterns.mdverbatimpeople/{slug}.md.results.csvfor cold-outbound.compile_report.mjsPer-person card design
The primary deliverable. The index is a stack of these, ranked by ICP score.