moonlight-lupin/agent-skills

people-enrichment

Enrich and search People Data Labs (PDL) Person and Company data, writing results to .xlsx.

Ver código fuente
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

People Enrichment & Search (People Data Labs)

One script, scripts/enrich.py, with five subcommands over PDL's Person and Company datasets. All share the same API-key handling, the boolean-PII contact logic, status flags, .xlsx styling, and a --dry-run preflight mode.

SubcommandInputOutputBilling
person-enrichlist of named peopleprofile + work history1 credit / match
person-identifylist of people (ambiguous)several scored candidates eachper PDL identify terms
person-searchcriteria flagsa list of matching people1 credit / record returned
company-enrichlist of companiesfirmographics1 credit / match
company-searchcriteria flagsa list of matching companies1 credit / record returned

The two search commands return data per result, so cost scales with --size. Always state the rough cost before a large search and keep --size modest unless the user asks for more (max 100 per request).

Scope and routing

Use this skill when the user wants PDL person/company enrichment or search for a legitimate, proportionate purpose. Do not use it to scrape LinkedIn directly, to compile an intrusive profile, or where a host environment mandates a different data provider.

Why People Data Labs, not a LinkedIn scraper

Scraping LinkedIn is fragile and legally risky. This skill uses PDL as a licensed aggregator rather than live LinkedIn scraping. If the user insists on live scraping, explain the trade-off rather than building a scraper.

The API key

scripts/enrich.py needs a PDL key, resolved at runtime in this order: PDL_API_KEY env var → .env in the cwd → .env next to the script. The key must never be written into this skill or any script. If absent, live commands exit with instructions. --dry-run and --self-test do not require a key.

Create the .env only locally:

bash
echo 'PDL_API_KEY=their_key_here' > .env

Treat .env as a secret: don't print, commit, or upload it. --self-test runs offline (canned data, no key) and writes sample people + company sheets so the user can see the output format before spending credits.

Dry-run preflight

Before spending credits, especially on larger files or searches, run the same command with --dry-run:

bash
python scripts/enrich.py person-enrich --input people.csv --output out.xlsx --dry-run
python scripts/enrich.py person-search --company "Northwind Capital" --title director --size 25 --dry-run
python scripts/enrich.py company-search --industry "real estate" --country singapore --size 50 --dry-run

Dry-run validates the input/search, prints the planned output, and estimates maximum credits without requiring PDL_API_KEY, calling PDL, or writing .xlsx output.

Contact fields and the free plan

On the free plan, PDL returns PII fields (emails, phone_numbers) as a boolean, not the value: true = a contact exists but is paywalled, false = none on file. The people sheets surface this in Email status / Phone status columns: included (real value present, Pro plans), exists - upgrade to view (paywalled but present), none on file, or unknown.

The five commands

person-enrich — one-to-one match named people.

bash
python scripts/enrich.py person-enrich --input people.csv --output out.xlsx

Recognised input columns (case/space-insensitive): name/full name, first name, last name, company/employer, title, location, email, linkedin/profile. More context per row = higher match rate.

person-identify — when a single enrich is ambiguous, get the candidate set.

bash
python scripts/enrich.py person-identify --input people.csv --max-candidates 5

Same input as enrich. Output has multiple rows per input person, each a scored candidate (Match score column), so the user can pick the right one.

person-search — find people by criteria, no name list needed.

bash
python scripts/enrich.py person-search --company "Northwind Capital" --title director --size 25

Flags: --company --title --location --country --industry --name, plus --size (1–100), --dataset (default all), and --sql to pass a raw PDL SQL query for full control. Flags are combined with AND.

company-enrich — match a list of companies to firmographics.

bash
python scripts/enrich.py company-enrich --input companies.csv --output firms.xlsx

Recognised input columns: name/company, website/domain, ticker, linkedin/profile, location/country/region/locality. Needs at least one of name/website/ticker/profile per row.

company-search — find companies by criteria.

bash
python scripts/enrich.py company-search --industry "real estate" --country singapore --min-employees 50 --size 50

Flags: --name --industry --country --locality --tag --min-employees, plus --size and --sql.

Reviewing output with the user

People sheets have two tabs: People (one row per person, status colour-coded) and Employment history (one row per past role). Company sheets have a single Companies tab. The Status column is the first thing to check: matched (green), needs_review (amber), no_match (red), error (orange). Call out the amber/red rows explicitly so the user knows what to double-check.

Tuning matches

--min-likelihood N (1–10) is the confidence floor for the enrich/identify commands. Raise it (6–8) when names/companies are common and you'd rather miss than mis-match; lower it when you have rich context and want coverage. Company enrichment is most reliable with a website/domain; person enrichment with a company or email alongside the name.

Swapping providers later

The PDL-specific pieces are the *_params builders, pdl_request, and the parse_person / parse_company mappers. To support another provider, implement those against its API and keep the same record dict shape; input parsing, status logic, SQL/flag handling, dry-run summaries, and .xlsx writing stay as is.

Principles

  • Drafts, not advice — output is a research aid for a person to review, not a determination.
  • Never invent — surface only what PDL returns; mark no_match/needs_review honestly rather than guessing an identity.
  • Deterministic where it counts — input parsing, status logic, dry-run estimates and .xlsx writing are deterministic.
  • Honesty and calibration — flag low-confidence matches and show the rough credit cost up front.
  • Workspace hygiene — write outputs where the user expects; never write the API key to disk in the skill.

Data handling

PDL is a third party and enrichment sends the real name/company to it — it cannot be tokenised, because the name is the lookup. Treat the .env / PDL_API_KEY as a secret: never print, commit or upload it. For people, confirm a legitimate and proportionate purpose and collect only fields relevant to that purpose.

Pitfalls

  1. Free plan hides contact values — emails/phones come back as booleans; read the status columns.
  2. Search cost scales with `--size` — quote the rough credit cost and keep --size modest.
  3. Common names mis-match — raise --min-likelihood or add context columns (company/email).
  4. Never commit `.env` — the key is a secret; --self-test and --dry-run need no key.
  5. Dry-run is an estimate — actual billing follows PDL's endpoint terms and returned records/matches.

Verification checklist

  • [ ] Legitimate, proportionate purpose confirmed for any person enrichment/search.
  • [ ] --dry-run used for large files or searches to validate scope and estimate credits.
  • [ ] PDL_API_KEY available via env or .env for live runs (never written into the skill).
  • [ ] Rough credit cost stated before any large search.
  • [ ] Amber/red status rows flagged to the user.
  • [ ] .env not printed/committed.

Requirements

  • Python 3.8+
  • pip install openpyxl (HTTP uses the stdlib urllib — no requests needed)
  • PDL_API_KEY (env var or .env) for live API calls; get one at https://www.peopledatalabs.com
  • Network access to the PDL API. --self-test and --dry-run run fully offline.
del mismo repositorio

Más Skills

Todos los Skills
moonlight-lupin
Comunidad

claude-plugin-converter

Convert Claude Code plugins into self-contained Hermes plugins — discovery analysis then full conversion

instalaciones
1
GitHub Stars
62
Actualizado
7 sept
moonlight-lupin
Comunidad

clips-studio

Use when the user wants to "make a video/clip", "generate a video from text", "animate this image/photo", "create a marketing reel / social video / teaser", "do a 3D / parallax move", "pan/zoom/orbit a shot", or mentions fal.ai, Kling, Veo or Seedance for video. Staged fal.ai workflow — brainstorm, draft cheaply, produce the final at quality. Three modes: text-to-video, animate (still to motion), camera-move (push-in/pan/orbit). Not for still images (image-studio), slide decks, or charts. Honesty discipline: never depict real identifiable subjects via text-to-video.

instalaciones
1
GitHub Stars
62
Actualizado
7 sept
moonlight-lupin
Comunidad

decision-log

ADR-style decision journal for agents and teams. Create numbered decision records, track superseding chains, schedule periodic reviews, and search past decisions to avoid re-litigating settled questions.

instalaciones
1
GitHub Stars
62
Actualizado
7 sept
moonlight-lupin
Comunidad

deep-research

Autonomous multi-step deep research engine implementing an iterative Think → Search → Extract → Synthesize → Stop loop. The LLM drives every decision: what to search, what's relevant, what's missing, and when to stop. Produces a cited, magazine-quality report with inline citations, category- specific formatting, and research stats. Trigger when the user asks for "deep research", "research report on", "comprehensive analysis of", "look into X in depth", "write a report on X", or any question needing multi-source synthesis beyond a single search. For entity vetting/dossiers use entity-research; for news digests use news-monitoring; for source-grounded Q&A use notebooklm-mode.

instalaciones
1
GitHub Stars
62
Actualizado
7 sept