leads-cli 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- company_discovery/__init__.py +4 -0
- company_discovery/adapters/__init__.py +5 -0
- company_discovery/adapters/apollo.py +189 -0
- company_discovery/adapters/exa.py +112 -0
- company_discovery/adapters/llm.py +118 -0
- company_discovery/adapters/protocols.py +58 -0
- company_discovery/adapters/website.py +154 -0
- company_discovery/bundled_skills/__init__.py +1 -0
- company_discovery/bundled_skills/company-discovery-operator/SKILL.md +72 -0
- company_discovery/bundled_skills/company-discovery-operator/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/company-enrichment-operator/SKILL.md +94 -0
- company_discovery/bundled_skills/company-enrichment-operator/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/company-search-spec-writer/SKILL.md +109 -0
- company_discovery/bundled_skills/company-search-spec-writer/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/contact-discovery-operator/SKILL.md +80 -0
- company_discovery/bundled_skills/contact-discovery-operator/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/contact-enrichment-operator/SKILL.md +86 -0
- company_discovery/bundled_skills/contact-enrichment-operator/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/contact-search-spec-writer/SKILL.md +86 -0
- company_discovery/bundled_skills/contact-search-spec-writer/agents/openai.yaml +4 -0
- company_discovery/bundled_skills/leads-update-operator/SKILL.md +60 -0
- company_discovery/bundled_skills/leads-update-operator/agents/openai.yaml +4 -0
- company_discovery/cli.py +1789 -0
- company_discovery/db/__init__.py +5 -0
- company_discovery/db/contact_enrichment_repository.py +268 -0
- company_discovery/db/contact_repository.py +366 -0
- company_discovery/db/enrichment_repository.py +207 -0
- company_discovery/db/models.py +324 -0
- company_discovery/db/repository.py +363 -0
- company_discovery/db/session.py +48 -0
- company_discovery/domain/__init__.py +24 -0
- company_discovery/domain/contact_models.py +178 -0
- company_discovery/domain/contact_spec.py +86 -0
- company_discovery/domain/models.py +287 -0
- company_discovery/domain/spec.py +263 -0
- company_discovery/migrations.py +190 -0
- company_discovery/prompts/__init__.py +8 -0
- company_discovery/prompts/candidate_evaluation/system.md +13 -0
- company_discovery/prompts/company_enrichment/system.md +42 -0
- company_discovery/prompts/contact_evaluation/system.md +18 -0
- company_discovery/prompts/query_generation/system.md +10 -0
- company_discovery/release_manifest.json +7 -0
- company_discovery/reports/__init__.py +4 -0
- company_discovery/reports/contact_enrichment_exporter.py +108 -0
- company_discovery/reports/contact_exporter.py +132 -0
- company_discovery/reports/enrichment_exporter.py +125 -0
- company_discovery/reports/exporter.py +135 -0
- company_discovery/runtime.py +336 -0
- company_discovery/services/__init__.py +4 -0
- company_discovery/services/contact_enrichment_pipeline.py +344 -0
- company_discovery/services/contact_enrichment_progress.py +37 -0
- company_discovery/services/contact_evaluator.py +110 -0
- company_discovery/services/contact_pipeline.py +295 -0
- company_discovery/services/contact_progress.py +38 -0
- company_discovery/services/enrichment_extractor.py +61 -0
- company_discovery/services/enrichment_pipeline.py +526 -0
- company_discovery/services/enrichment_progress.py +20 -0
- company_discovery/services/enrichment_resolver.py +148 -0
- company_discovery/services/evaluator.py +40 -0
- company_discovery/services/hygiene.py +51 -0
- company_discovery/services/memory.py +150 -0
- company_discovery/services/normalization.py +98 -0
- company_discovery/services/pipeline.py +628 -0
- company_discovery/services/progress.py +48 -0
- company_discovery/services/query_planner.py +47 -0
- company_discovery/settings.py +152 -0
- company_discovery/skill_installer.py +197 -0
- company_discovery/update_plan.py +79 -0
- leads_cli-0.1.0.dist-info/METADATA +277 -0
- leads_cli-0.1.0.dist-info/RECORD +72 -0
- leads_cli-0.1.0.dist-info/WHEEL +4 -0
- leads_cli-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: company-discovery-operator
|
|
3
|
+
description: Validate, execute, inspect, rerun, and explain Company Discovery CLI runs from an existing company_search_spec.json. Use when a user asks an agent to run company discovery, find companies from a prepared spec, inspect a discovered domain, export a run, or summarize selected, reserve, and rejected company results. Do not rewrite the ICP or work on contacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operate Company Discovery
|
|
7
|
+
|
|
8
|
+
Run company discovery from an existing spec without silently changing it.
|
|
9
|
+
|
|
10
|
+
## Workspace And CLI
|
|
11
|
+
|
|
12
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
13
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
14
|
+
|
|
15
|
+
- Company specs normally live in `specs/companies/`; validate the exact spec path before running.
|
|
16
|
+
- Company discovery artifacts are saved under `runs/<company-discover-id>/` with `selected.csv`,
|
|
17
|
+
`reserve.csv`, `rejected.csv`, `summary.md`, and `run.json`.
|
|
18
|
+
- Config lives in `config/config.toml`; secrets live in `config/secrets.toml`; never expose secret
|
|
19
|
+
values.
|
|
20
|
+
- The memory database is `data/company_memory.db`; treat CLI output and saved artifacts as the
|
|
21
|
+
normal interface.
|
|
22
|
+
- Backups are under `backups/`; CLI diagnostics are in `logs/leads.log`; installed skill metadata
|
|
23
|
+
is under `skills/`.
|
|
24
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
25
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
26
|
+
|
|
27
|
+
## New discovery
|
|
28
|
+
|
|
29
|
+
1. Locate the requested `company_search_spec.json`.
|
|
30
|
+
2. Run `leads companies validate-spec --spec <path>`.
|
|
31
|
+
3. Report material open modes shown by validation: national geography, no size filter, or no custom exclusions.
|
|
32
|
+
4. State the novelty policy before running: `unused_memory` searches unused memory first,
|
|
33
|
+
`only_new` bypasses memory candidates and suppresses known domains, and `full_memory` permits
|
|
34
|
+
reuse of previously selected companies. If omitted, the policy is `unused_memory`.
|
|
35
|
+
5. For multi-vertical specs, report the balance mode and treat each vertical as an independent memory and external-search lane.
|
|
36
|
+
6. Report the external search budget before running. If omitted, use the normalized defaults:
|
|
37
|
+
`external_search.exa_searches = 8` and `external_search.results_per_search = 5`.
|
|
38
|
+
7. Run `leads companies discover --spec <path>`. Add `--verbose` only when detailed queries and candidate decisions help diagnose the run. Before launching the command, set a large tool-window timeout, around 10 minutes, so live discovery can finish without being cut off.
|
|
39
|
+
8. Let the command finish. Do not launch a duplicate while the original process is active.
|
|
40
|
+
9. Read the final counts and Markdown summary path.
|
|
41
|
+
10. Summarize memory reuse, known-domain suppression for `only_new`, external-search volume,
|
|
42
|
+
selected/reserve/rejected counts, per-vertical outcomes, and any shortfall.
|
|
43
|
+
11. Present the results with:
|
|
44
|
+
- one compact count line for all buckets;
|
|
45
|
+
- one table for `selected`;
|
|
46
|
+
- one table for `reserve`.
|
|
47
|
+
Do not show `rejected` rows by default unless the user asks, or unless there are no useful
|
|
48
|
+
results and the failure reasons are the main thing that matters.
|
|
49
|
+
12. Keep the default tables compact and systematic. Use these columns when they are available:
|
|
50
|
+
`Company | Domain | Vertical | State | Size | Fit | Source | Notes`
|
|
51
|
+
13. Show at most about 15 rows per table by default. If there are more, say that additional rows
|
|
52
|
+
are available in the exported artifacts.
|
|
53
|
+
|
|
54
|
+
Discovery stops after saving and reporting its run ID. Never start enrichment through a discovery
|
|
55
|
+
flag. When the user also requests enrichment, finish discovery first and pass its saved run ID to
|
|
56
|
+
the separate enrichment workflow.
|
|
57
|
+
|
|
58
|
+
## Follow-up operations
|
|
59
|
+
|
|
60
|
+
- Inspect a run with `leads companies show-run <run-id>`.
|
|
61
|
+
- Inspect one domain with `leads companies inspect <run-id> --domain <domain>`.
|
|
62
|
+
- Regenerate artifacts with `leads companies export <run-id>`.
|
|
63
|
+
- Repeat the exact prior spec and its novelty policy using `leads companies rerun <run-id>`.
|
|
64
|
+
|
|
65
|
+
## Guardrails
|
|
66
|
+
|
|
67
|
+
- Do not edit or replace the spec unless the user asks to change the ICP.
|
|
68
|
+
- Do not hide a missing constraint or selected-count shortfall.
|
|
69
|
+
- Do not describe reserve companies as confirmed selections.
|
|
70
|
+
- Explain deterministic hygiene rejections separately from LLM ICP judgments when relevant.
|
|
71
|
+
- Treat the saved run and artifacts as authoritative; do not infer companies from terminal snippets alone.
|
|
72
|
+
- Never expose API keys or raw environment values.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: company-enrichment-operator
|
|
3
|
+
description: Enrich company profiles from a completed Company Discovery run. Use when a user asks to enrich selected or reserve companies, continue from discovery to enrichment, retrieve company phone/address/independence, inspect enrichment evidence, refresh stale enrichment facts, or export ready/review/blocked company results. This skill operates on companies only, never contacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operate Company Enrichment
|
|
7
|
+
|
|
8
|
+
Consume a completed discovery run. Do not ask the user to restate its ICP or reconstruct input from
|
|
9
|
+
`selected.csv`; the database record is authoritative.
|
|
10
|
+
|
|
11
|
+
## Workspace And CLI
|
|
12
|
+
|
|
13
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
14
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
15
|
+
|
|
16
|
+
- Company discovery runs live at `runs/<company-discover-id>/`.
|
|
17
|
+
- Company enrichment artifacts live at
|
|
18
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/` with `enriched.csv`, `review.csv`,
|
|
19
|
+
`blocked.csv`, `summary.md`, and `run.json`.
|
|
20
|
+
- The database is `data/company_memory.db`; use `leads companies show-run`,
|
|
21
|
+
`show-enrichment`, and inspect commands before direct DB inspection.
|
|
22
|
+
- Config is in `config/config.toml`; secrets are in `config/secrets.toml`; never expose secret
|
|
23
|
+
values.
|
|
24
|
+
- Backups are under `backups/`; CLI diagnostics are in `logs/leads.log`; installed skill metadata
|
|
25
|
+
is under `skills/`; specs live under `specs/companies/` and `specs/contacts/`.
|
|
26
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
27
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
28
|
+
|
|
29
|
+
## Standard workflow
|
|
30
|
+
|
|
31
|
+
1. Identify the discovery run ID. Default to its `selected` bucket.
|
|
32
|
+
2. Run `leads companies show-run <discovery-run-id>` when its status or result count is unclear.
|
|
33
|
+
3. Explain that name, domain, vertical, geography, employee estimate, and ownership type are retained
|
|
34
|
+
from discovery. Enrichment targets LinkedIn company profile, phone, complete address, and
|
|
35
|
+
independence.
|
|
36
|
+
4. Run `leads companies enrich <discovery-run-id>`.
|
|
37
|
+
5. Read the final counts and artifact path. Report inherited facts, memory reuse, website retrieval,
|
|
38
|
+
fallback searches, and ready/review/blocked totals.
|
|
39
|
+
The returned enrichment run ID is random and prefixed, like `company-enrich-a1b2c3d4e5f6`.
|
|
40
|
+
6. Treat `enriched.csv` as the clean deliverable, `review.csv` as unresolved work, `blocked.csv` as
|
|
41
|
+
conflicts, and `run.json` as the provenance and decision trace.
|
|
42
|
+
7. Present the results with:
|
|
43
|
+
- one compact count line for all outcomes;
|
|
44
|
+
- one table for `ready`;
|
|
45
|
+
- one table for `review`.
|
|
46
|
+
Do not show `blocked` rows by default unless the user asks, or unless there are no useful
|
|
47
|
+
results and the blocking reasons are what the user needs next.
|
|
48
|
+
8. Keep the default tables compact and systematic. Use these columns when they are available:
|
|
49
|
+
`Company | Domain | Vertical | Phone | City | State | LinkedIn | Independence | Outcome | Notes`
|
|
50
|
+
9. Show at most about 15 rows per table by default. If there are more, say that additional rows
|
|
51
|
+
are available in the exported artifacts.
|
|
52
|
+
|
|
53
|
+
For a new search followed by enrichment, always use two separate commands:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
leads companies discover --spec <spec-path>
|
|
57
|
+
leads companies enrich <discovery-run-id>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Wait for discovery to finish and use the exact run ID it returns. Never represent enrichment as a
|
|
61
|
+
discovery option.
|
|
62
|
+
|
|
63
|
+
## Options
|
|
64
|
+
|
|
65
|
+
- Use `--bucket reserve` only when the user asks to enrich reserve companies.
|
|
66
|
+
- Use `--limit N` for an explicitly bounded run.
|
|
67
|
+
- Use `--refresh contact` to refetch LinkedIn, phone, and location.
|
|
68
|
+
- Use `--refresh independence` to rerun only the parent/franchise check.
|
|
69
|
+
- Use `--refresh all` to ignore all fresh enrichment memory.
|
|
70
|
+
- Use `--allow-unknown-independence` only when the user accepts complete contact profiles whose
|
|
71
|
+
independence could not be proven. Without it, those companies go to review.
|
|
72
|
+
|
|
73
|
+
## Follow-up operations
|
|
74
|
+
|
|
75
|
+
- Show a run with `leads companies show-enrichment <company-enrich-id>`.
|
|
76
|
+
- Inspect provenance and trace with
|
|
77
|
+
`leads companies inspect-enrichment <company-enrich-id> --domain <domain>`.
|
|
78
|
+
- Regenerate artifacts with `leads companies export-enrichment <company-enrich-id>`.
|
|
79
|
+
|
|
80
|
+
## Guardrails
|
|
81
|
+
|
|
82
|
+
- Never treat `private`, `privately held`, LLC, partnership, or corporation as proof of independence.
|
|
83
|
+
- Explicit franchise, parent, subsidiary, division, or acquisition evidence blocks the company.
|
|
84
|
+
- If the discovery spec lists `family_owned` under `exclude.structured.ownership_signals`, explicit
|
|
85
|
+
family-owned evidence blocks the company as a fit conflict. Without that requested exclusion,
|
|
86
|
+
family-owned remains valid positive evidence of independence.
|
|
87
|
+
- Absence of franchise language is not proof; unresolved independence remains `unknown`.
|
|
88
|
+
- Never merge address pieces from separate offices. The selected address must be one complete block
|
|
89
|
+
and, for state-scoped discovery, must be in the inherited state.
|
|
90
|
+
- Save only LinkedIn company profiles under `/company/`. Never save personal profiles, jobs, posts,
|
|
91
|
+
or search pages. Prefer links found directly on the official company website.
|
|
92
|
+
- Do not silently replace discovery facts. Report identity, geography, and fit conflicts.
|
|
93
|
+
- Do not refresh employee data during the default pass; discovery already supplied it.
|
|
94
|
+
- Never expose API keys or raw environment values.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Company Enrichment Operator"
|
|
3
|
+
short_description: "Enrich selected companies from a discovery run"
|
|
4
|
+
default_prompt: "Use $company-enrichment-operator to enrich selected companies from this discovery run and summarize ready, review, and blocked results."
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: company-search-spec-writer
|
|
3
|
+
description: Turn natural-language company targeting or ICP requests into strict company_search_spec.json files for the Company Discovery CLI. Use when a user asks to find target companies, define a company ICP, prepare a company search, or translate company criteria such as vertical, geography, employee size, exclusions, and novelty into a runnable spec. Do not use for contact or person searches.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Write a Company Search Spec
|
|
7
|
+
|
|
8
|
+
Create one `company_search_spec.json` under the Leads workspace unless the user gives another path.
|
|
9
|
+
|
|
10
|
+
## Workspace And CLI
|
|
11
|
+
|
|
12
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
13
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
14
|
+
|
|
15
|
+
- Write company specs to `specs/companies/`, for example
|
|
16
|
+
`specs/companies/company_search_spec.json`.
|
|
17
|
+
- Contact specs belong in `specs/contacts/`; do not write contact specs here.
|
|
18
|
+
- Runtime config is in `config/config.toml`; secrets are in `config/secrets.toml`; never expose
|
|
19
|
+
secret values.
|
|
20
|
+
- The SQLite memory DB is `data/company_memory.db`; use CLI commands rather than editing it.
|
|
21
|
+
- Run artifacts are saved under `runs/`; backups are saved under `backups/`; CLI diagnostics are in
|
|
22
|
+
`logs/leads.log`; installed skill metadata lives under `skills/`.
|
|
23
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
24
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. Extract only company-level criteria the user actually supplied.
|
|
29
|
+
2. Set `version` to `1` and require a positive `count`.
|
|
30
|
+
3. Use `verticals` for every new spec. Add one entry per requested vertical; multiple entries mean
|
|
31
|
+
OR (separate company groups), never companies that must match every vertical.
|
|
32
|
+
4. Each vertical should always use one simple shape: `key`, `label`, and optional query hints.
|
|
33
|
+
Use a lowercase stable key.
|
|
34
|
+
5. Add `search_terms` only when the vertical is niche, ambiguous, or user wording needs stronger
|
|
35
|
+
search hints. Add `exclude_terms` only when a few obvious search-time negatives help reduce
|
|
36
|
+
noise. Do not invent ICP constraints.
|
|
37
|
+
6. Encode broad US geography as `{"country": "US", "states": []}`. Use two-letter uppercase state codes when states are requested.
|
|
38
|
+
7. Use an empty `company_size` object when no employee range was given. Never invent employee limits.
|
|
39
|
+
8. Use empty arrays for omitted include/exclude criteria. When the user explicitly excludes family
|
|
40
|
+
businesses, set `exclude.structured.ownership_signals` to `["family_owned"]`. This tells enrichment
|
|
41
|
+
to block a company when official-site or corroborating evidence identifies it as family-owned.
|
|
42
|
+
Never invent this exclusion.
|
|
43
|
+
9. Default `novelty_mode` to `unused_memory`. This searches memory first but excludes every company
|
|
44
|
+
that has ever been selected. Use `only_new` when the user wants external discovery only; it skips
|
|
45
|
+
memory candidates and excludes known domains returned by search. Use `full_memory` only when the
|
|
46
|
+
user explicitly permits reusing companies selected in prior runs.
|
|
47
|
+
10. Default `reserve_ratio` to `0.5`; this controls output capacity, not ICP fit.
|
|
48
|
+
11. Default `balance_mode` to `soft` for multiple verticals. Use `strict` only when equal caps matter more than reaching the requested count, and `none` only when distribution does not matter.
|
|
49
|
+
12. Add `external_search` to every new spec. Default to `{"exa_searches": 8, "results_per_search": 5}` unless the user asks for a broader or cheaper search. `exa_searches` is the number of Exa searches per active vertical/lane; `results_per_search` is the number of Exa results requested by each search.
|
|
50
|
+
13. Write JSON, then run `leads companies validate-spec --spec <spec-path>`.
|
|
51
|
+
14. Fix validation errors before returning. Do not run discovery unless the user asked for it.
|
|
52
|
+
|
|
53
|
+
## Contract
|
|
54
|
+
|
|
55
|
+
Use this shape and omit no top-level fields except those with documented defaults:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"version": 1,
|
|
60
|
+
"count": 50,
|
|
61
|
+
"verticals": [
|
|
62
|
+
{"key": "construction", "label": "Construction"},
|
|
63
|
+
{"key": "healthcare", "label": "Healthcare"}
|
|
64
|
+
],
|
|
65
|
+
"geography": {"country": "US", "states": ["TX"]},
|
|
66
|
+
"company_size": {"employee_min": 20, "employee_max": 100},
|
|
67
|
+
"include": {"keywords": [], "subtypes": []},
|
|
68
|
+
"exclude": {
|
|
69
|
+
"keywords": [],
|
|
70
|
+
"ownership_types": [],
|
|
71
|
+
"company_patterns": [],
|
|
72
|
+
"structured": {"ownership_signals": []}
|
|
73
|
+
},
|
|
74
|
+
"novelty_mode": "unused_memory",
|
|
75
|
+
"reserve_ratio": 0.5,
|
|
76
|
+
"balance_mode": "soft",
|
|
77
|
+
"external_search": {
|
|
78
|
+
"exa_searches": 8,
|
|
79
|
+
"results_per_search": 5
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Allowed novelty values are `unused_memory`, `only_new`, and `full_memory`.
|
|
85
|
+
|
|
86
|
+
- `unused_memory` (default): search memory first, but never select a company that was selected before.
|
|
87
|
+
- `only_new`: do not source candidates from memory and discard external results whose domains are already known.
|
|
88
|
+
- `full_memory`: search all matching memory, including companies selected in prior runs.
|
|
89
|
+
Allowed balance values are `soft`, `strict`, and `none`.
|
|
90
|
+
`external_search.exa_searches` may be 1-20. `external_search.results_per_search` may be
|
|
91
|
+
1-100. Keep the default `8` and `5` unless the user asks to make discovery broader, narrower,
|
|
92
|
+
cheaper, or more exhaustive.
|
|
93
|
+
|
|
94
|
+
For a niche or ambiguous vertical, add query hints like:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"key": "marine-surveying",
|
|
99
|
+
"label": "Marine Surveying",
|
|
100
|
+
"search_terms": ["marine surveying", "vessel inspection", "cargo survey"],
|
|
101
|
+
"exclude_terms": ["software", "directory", "marketplace"]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Allowed structured ownership signals are `family_owned`, `franchise`, `parent`, `subsidiary`,
|
|
106
|
+
`division`, and `acquired`. When a size bound is one-sided, include only the known bound. When
|
|
107
|
+
exclusions are omitted, keep all exclusion arrays empty. Preserve the user's ambiguity instead of
|
|
108
|
+
silently tightening the ICP. Old specs that still use `mode`, `seed_terms`, or `anti_terms` remain
|
|
109
|
+
valid, but new specs should not emit them.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contact-discovery-operator
|
|
3
|
+
description: Validate, execute, inspect, export, and explain live contact discovery from an existing contact_search_spec.json. Use when a user asks an agent to find current role-matched people at companies from a completed enrichment run or review a prior contact discovery run. Use the separate contact-enrichment-operator skill for Apollo email or phone enrichment.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operate Contact Discovery
|
|
7
|
+
|
|
8
|
+
Find current people at already-enriched companies without changing the saved company scope.
|
|
9
|
+
|
|
10
|
+
## Workspace And CLI
|
|
11
|
+
|
|
12
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
13
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
14
|
+
|
|
15
|
+
- Contact specs normally live in `specs/contacts/`; validate the exact spec path before running.
|
|
16
|
+
- Contact discovery artifacts live at
|
|
17
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/contacts/<contact-discover-id>/`
|
|
18
|
+
with `accepted.csv`, `review.csv`, `rejected.csv`, `summary.md`, and `run.json`.
|
|
19
|
+
- The source company enrichment run lives under
|
|
20
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/`.
|
|
21
|
+
- Config is in `config/config.toml`; secrets are in `config/secrets.toml`; never expose secret
|
|
22
|
+
values.
|
|
23
|
+
- The memory database is `data/company_memory.db`; use `leads contacts show-run` and inspect
|
|
24
|
+
commands before direct DB inspection.
|
|
25
|
+
- Backups are under `backups/`; CLI diagnostics are in `logs/leads.log`; installed skill metadata
|
|
26
|
+
is under `skills/`.
|
|
27
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
28
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
29
|
+
|
|
30
|
+
## New Discovery
|
|
31
|
+
|
|
32
|
+
1. Locate the requested `contact_search_spec.json`.
|
|
33
|
+
2. Run `leads contacts validate-spec --spec <path>`.
|
|
34
|
+
3. Confirm the source company enrichment run, bucket, optional domain subset, roles, and caps.
|
|
35
|
+
4. Run `leads contacts discover --spec <path>`.
|
|
36
|
+
5. Let the command finish; do not launch a duplicate while it is active.
|
|
37
|
+
6. Report the contact run ID, companies loaded, memory reuse, live-web queries, and
|
|
38
|
+
accepted/review/rejected counts.
|
|
39
|
+
7. Read the saved summary or `run.json` when explaining why people were accepted or held for
|
|
40
|
+
review. Terminal progress is not the authoritative record.
|
|
41
|
+
8. Present the results with:
|
|
42
|
+
- one compact count line for all verdicts;
|
|
43
|
+
- one table for `accepted`;
|
|
44
|
+
- one table for `review`.
|
|
45
|
+
Do not show `rejected` rows by default unless the user asks, or unless there are no useful
|
|
46
|
+
results and the rejection reasons are the important output.
|
|
47
|
+
9. Keep the default tables compact and systematic. Use these columns when they are available:
|
|
48
|
+
`Company | Contact | Title | Role Key | LinkedIn | Status | Source | Notes`
|
|
49
|
+
10. Show at most about 15 rows per table by default. If there are more, say that additional rows
|
|
50
|
+
are available in the exported artifacts.
|
|
51
|
+
|
|
52
|
+
The command checks fresh contact memory independently for every company and role. It searches Exa
|
|
53
|
+
only for remaining per-role gaps, then verifies identity, current-company evidence, and title fit.
|
|
54
|
+
|
|
55
|
+
## Follow-up Operations
|
|
56
|
+
|
|
57
|
+
- Show a run with `leads contacts show-run <contact-run-id>`.
|
|
58
|
+
- Inspect one person with `leads contacts inspect <contact-run-id> --person "Jane Smith"`.
|
|
59
|
+
- Regenerate artifacts with `leads contacts export <contact-run-id>`.
|
|
60
|
+
|
|
61
|
+
## Interpret Results
|
|
62
|
+
|
|
63
|
+
- `accepted.csv`: clear identity, explicit current-company tie, and explicit requested-role match.
|
|
64
|
+
- `review.csv`: plausible evidence that is not strong enough for automatic acceptance, including
|
|
65
|
+
valid matches beyond a per-company role cap.
|
|
66
|
+
- `rejected.csv`: wrong company, former employee, wrong role, or ambiguous identity.
|
|
67
|
+
- `run.json`: complete role decisions, evidence, source URLs, query results, and memory/live source.
|
|
68
|
+
|
|
69
|
+
The CSV schema intentionally includes blank `email` and `phone` columns so later enrichment can
|
|
70
|
+
fill the same client-facing shape. Never describe those blank fields as failed enrichment.
|
|
71
|
+
|
|
72
|
+
## Guardrails
|
|
73
|
+
|
|
74
|
+
- Do not edit the spec during execution.
|
|
75
|
+
- Do not search arbitrary companies outside the source enrichment run.
|
|
76
|
+
- Do not describe a review contact as confirmed.
|
|
77
|
+
- Do not infer current employment from Apollo or old databases.
|
|
78
|
+
- Do not silently continue into contact enrichment; invoke the separate operator workflow when the
|
|
79
|
+
user asks for email or phone data.
|
|
80
|
+
- Never expose API keys or raw environment values.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contact-enrichment-operator
|
|
3
|
+
description: Enrich accepted live-web contact discoveries with Apollo email and phone data, inspect provider mismatches, and export outreach-ready results. Use when a user asks to find contact details, emails, or phone numbers for people in a completed contact discovery run, rerun Apollo enrichment, or review a prior contact enrichment run.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operate Contact Enrichment
|
|
7
|
+
|
|
8
|
+
Use Apollo only after contact discovery has established the person's identity, current company,
|
|
9
|
+
and requested-role fit.
|
|
10
|
+
|
|
11
|
+
## Workspace And CLI
|
|
12
|
+
|
|
13
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
14
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
15
|
+
|
|
16
|
+
- Contact discovery artifacts live under
|
|
17
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/contacts/<contact-discover-id>/`.
|
|
18
|
+
- Contact enrichment artifacts live under
|
|
19
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/contacts/<contact-discover-id>/enrich/<contact-enrich-id>/`
|
|
20
|
+
with `ready.csv`, `review.csv`, `blocked.csv`, `summary.md`, and `run.json`.
|
|
21
|
+
- Config is in `config/config.toml`; secrets are in `config/secrets.toml`; never expose API keys or
|
|
22
|
+
webhook values.
|
|
23
|
+
- The memory database is `data/company_memory.db`; use `leads contacts show-run`,
|
|
24
|
+
`show-enrichment`, and inspect commands before direct DB inspection.
|
|
25
|
+
- Backups are under `backups/`; CLI diagnostics are in `logs/leads.log`; installed skill metadata
|
|
26
|
+
is under `skills/`; specs live under `specs/companies/` and `specs/contacts/`.
|
|
27
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
28
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
29
|
+
|
|
30
|
+
## Configure Apollo
|
|
31
|
+
|
|
32
|
+
Require `APOLLO_API_KEY`.
|
|
33
|
+
|
|
34
|
+
For the default email-and-phone flow, also require a public HTTPS `APOLLO_WEBHOOK_URL`; Apollo's
|
|
35
|
+
phone and waterfall enrichment are asynchronous. Never print either environment value.
|
|
36
|
+
|
|
37
|
+
If no webhook endpoint is available, run email-only enrichment with `--no-phone`.
|
|
38
|
+
|
|
39
|
+
## Run Enrichment
|
|
40
|
+
|
|
41
|
+
1. Identify the completed `contact-discover-<id>` requested by the user.
|
|
42
|
+
2. Run `leads contacts show-run <contact-run-id>` to confirm scope and accepted count.
|
|
43
|
+
3. Run `leads contacts enrich <contact-run-id>` for email and phone.
|
|
44
|
+
4. Use `--no-phone` only when the user wants email-only enrichment or no webhook is configured.
|
|
45
|
+
5. Use `--refresh` only when the user explicitly wants to ignore fresh 14-day Apollo memory.
|
|
46
|
+
6. Report the contact enrichment run ID and ready/review/blocked counts.
|
|
47
|
+
7. Read `summary.md` or `run.json` before explaining mismatches.
|
|
48
|
+
8. Present the results with:
|
|
49
|
+
- one compact count line for all outcomes;
|
|
50
|
+
- one table for `ready`;
|
|
51
|
+
- one table for `review`.
|
|
52
|
+
Do not show `blocked` rows by default unless the user asks, or unless there are no useful
|
|
53
|
+
results and the blocking reasons are what the user needs next.
|
|
54
|
+
9. Keep the default tables compact and systematic. Use these columns when they are available:
|
|
55
|
+
`Company | Contact | Title | Email | Phone | Status | Apollo Match | Notes`
|
|
56
|
+
10. Show at most about 15 rows per table by default. If there are more, say that additional rows
|
|
57
|
+
are available in the exported artifacts.
|
|
58
|
+
|
|
59
|
+
The command enriches accepted contacts only. It batches up to 10 people per Apollo request, polls
|
|
60
|
+
asynchronous request IDs, and saves `contact-enrich-<id>` below the source contact run.
|
|
61
|
+
|
|
62
|
+
## Follow-Up Operations
|
|
63
|
+
|
|
64
|
+
- Show a run: `leads contacts show-enrichment <contact-enrich-id>`
|
|
65
|
+
- Inspect a person: `leads contacts inspect-enrichment <run-id> --person "Jane Smith"`
|
|
66
|
+
- Regenerate artifacts: `leads contacts export-enrichment <run-id>`
|
|
67
|
+
|
|
68
|
+
## Interpret Results
|
|
69
|
+
|
|
70
|
+
- `ready.csv`: identity matches and a work channel is supported by the target company domain.
|
|
71
|
+
- `review.csv`: identity is credible, but Apollo company data, email domain, or channel context is
|
|
72
|
+
stale or ambiguous.
|
|
73
|
+
- `blocked.csv`: no credible Apollo identity match or no usable email/phone was returned.
|
|
74
|
+
- `run.json`: discovery snapshot, Apollo metadata, raw provider record, deterministic checks,
|
|
75
|
+
flags, and outcome.
|
|
76
|
+
|
|
77
|
+
Apollo never overrides the live-web company, title, LinkedIn URL, or role. A stale Apollo employer
|
|
78
|
+
is a review signal, not proof that discovery was wrong.
|
|
79
|
+
|
|
80
|
+
## Guardrails
|
|
81
|
+
|
|
82
|
+
- Do not enrich review or rejected discovery contacts automatically.
|
|
83
|
+
- Do not describe review rows as outreach-ready.
|
|
84
|
+
- Do not use personal email addresses without explicit human review.
|
|
85
|
+
- Do not expose API keys, webhook secrets, or raw environment values.
|
|
86
|
+
- Do not retry failed paid requests blindly; inspect the stored run and provider error first.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: contact-search-spec-writer
|
|
3
|
+
description: Convert natural-language requests for people at previously enriched companies into a validated contact_search_spec.json for the Leads CLI. Use when a user asks to find managers, owners, estimators, project managers, or other current employees across all or selected companies from a company enrichment run. Do not run discovery or add Apollo enrichment settings.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Write Contact Search Specs
|
|
7
|
+
|
|
8
|
+
Create one strict JSON input for `leads contacts discover`.
|
|
9
|
+
|
|
10
|
+
## Workspace And CLI
|
|
11
|
+
|
|
12
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
13
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
14
|
+
|
|
15
|
+
- Write contact specs to `specs/contacts/`, for example
|
|
16
|
+
`specs/contacts/contact_search_spec.json`.
|
|
17
|
+
- Company specs belong in `specs/companies/`; do not write company ICP specs here.
|
|
18
|
+
- Contact specs reference completed company enrichment runs stored under
|
|
19
|
+
`runs/<company-discover-id>/enrich/<company-enrich-id>/`.
|
|
20
|
+
- Config is in `config/config.toml`; secrets are in `config/secrets.toml`; never expose secret
|
|
21
|
+
values.
|
|
22
|
+
- The memory database is `data/company_memory.db`; use CLI commands rather than editing it.
|
|
23
|
+
- Backups are under `backups/`; CLI diagnostics are in `logs/leads.log`; installed skill metadata
|
|
24
|
+
is under `skills/`.
|
|
25
|
+
- Useful setup/maintenance commands: `leads init`, `leads version`, `leads doctor`,
|
|
26
|
+
`leads update --check`, `leads migrate --check`, and `leads skills status`.
|
|
27
|
+
|
|
28
|
+
## Workflow
|
|
29
|
+
|
|
30
|
+
1. Identify the completed company enrichment run that supplies the companies.
|
|
31
|
+
2. Default to its `ready` companies. Use `review` or `all` only when the user explicitly wants
|
|
32
|
+
companies that were not fully ready.
|
|
33
|
+
3. Resolve company scope:
|
|
34
|
+
- omit `domains` or use `[]` for every company in the chosen bucket;
|
|
35
|
+
- use root domains for a requested subset;
|
|
36
|
+
- never invent domains that are absent from the enrichment run.
|
|
37
|
+
4. Convert every requested role into a stable snake_case key and a focused list of title labels.
|
|
38
|
+
5. Default `max_per_company` to `1`. Increase it only when the user requests multiple people per
|
|
39
|
+
company or the role naturally needs broader coverage.
|
|
40
|
+
6. Keep `current_only` and `require_role_match` true unless the user explicitly requests looser
|
|
41
|
+
research.
|
|
42
|
+
7. Write JSON, then run `leads contacts validate-spec --spec <spec-path>`.
|
|
43
|
+
8. Correct validation errors before handing the spec to the discovery operator.
|
|
44
|
+
|
|
45
|
+
## Contract
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"version": 1,
|
|
50
|
+
"company_source": {
|
|
51
|
+
"enrichment_run_id": "company-enrich-a1b2c3d4e5f6",
|
|
52
|
+
"bucket": "ready",
|
|
53
|
+
"domains": []
|
|
54
|
+
},
|
|
55
|
+
"roles": [
|
|
56
|
+
{
|
|
57
|
+
"key": "project_manager",
|
|
58
|
+
"labels": ["project manager", "senior project manager"],
|
|
59
|
+
"max_per_company": 1
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"company_limit": null,
|
|
63
|
+
"contact_limit": null,
|
|
64
|
+
"current_only": true,
|
|
65
|
+
"require_role_match": true,
|
|
66
|
+
"memory_freshness_days": 30
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Role Rules
|
|
71
|
+
|
|
72
|
+
- Keep synonyms semantically close. Do not put `owner`, `estimator`, and `project manager` under
|
|
73
|
+
one broad `manager` role.
|
|
74
|
+
- Preserve distinct user requests as distinct role objects.
|
|
75
|
+
- Use observed business titles, not department keywords alone.
|
|
76
|
+
- If “manager” is genuinely ambiguous and context does not resolve it, ask which management role
|
|
77
|
+
they mean before creating the file.
|
|
78
|
+
|
|
79
|
+
## Guardrails
|
|
80
|
+
|
|
81
|
+
- JSON is the canonical format; do not produce YAML.
|
|
82
|
+
- Do not include company-discovery ICP fields such as state, vertical, size, or exclusions. The
|
|
83
|
+
company enrichment run already defines company scope.
|
|
84
|
+
- Do not add email, phone, Apollo, or contact-enrichment settings.
|
|
85
|
+
- Do not silently include company enrichment review rows.
|
|
86
|
+
- Never expose API keys or environment values.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: leads-update-operator
|
|
3
|
+
description: Safely guide updates for the Leads CLI, bundled agent skills, local database schema, and workspace backups.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operate Leads Updates
|
|
7
|
+
|
|
8
|
+
Use this skill when a user asks to update, upgrade, repair, or check the installed Leads tool.
|
|
9
|
+
|
|
10
|
+
## Workspace And CLI
|
|
11
|
+
|
|
12
|
+
Use `leads doctor` or `leads version` to confirm the workspace root. The root contains
|
|
13
|
+
`backups/`, `config/`, `data/`, `logs/`, `runs/`, `skills/`, and `specs/`.
|
|
14
|
+
|
|
15
|
+
- `config/config.toml` stores non-secret settings; `config/secrets.toml` stores API keys and
|
|
16
|
+
webhook secrets; `config/runtime.json` stores schema, skill, and install metadata.
|
|
17
|
+
- `data/company_memory.db` is the SQLite memory DB.
|
|
18
|
+
- `runs/` stores discovery, enrichment, contact discovery, and contact enrichment artifacts.
|
|
19
|
+
- `specs/companies/` and `specs/contacts/` store agent-created spec files.
|
|
20
|
+
- `backups/` stores migration and reset backups.
|
|
21
|
+
- `logs/leads.log` stores CLI diagnostics; it is not run evidence and should not be summarized as
|
|
22
|
+
a lead result.
|
|
23
|
+
- `skills/` stores bundled skill copies and install metadata. Use `leads skills ...` commands
|
|
24
|
+
instead of manually editing installed skill files.
|
|
25
|
+
|
|
26
|
+
Core commands to know: `leads init`, `leads version`, `leads doctor`, `leads config show`,
|
|
27
|
+
`leads skills status`, `leads skills install`, `leads skills reinstall`, `leads update --check`,
|
|
28
|
+
`leads migrate --check`, and `leads migrate --apply`.
|
|
29
|
+
|
|
30
|
+
## Safe Update Flow
|
|
31
|
+
|
|
32
|
+
1. Run `leads update --check` first.
|
|
33
|
+
2. Prefer `leads update --check --json` when you need exact fields for an explanation.
|
|
34
|
+
3. Report CLI, skill bundle, and database schema changes separately.
|
|
35
|
+
4. Explain whether a backup or migration is required.
|
|
36
|
+
5. If migration is required, run `leads migrate --check` or `leads migrate --check --json` and
|
|
37
|
+
explain the migration action, backup path behavior, and risk summary.
|
|
38
|
+
6. Ask the user before applying structural database changes.
|
|
39
|
+
7. Only run `leads migrate --apply` after explicit user approval. Use a large tool-window timeout,
|
|
40
|
+
around 10 minutes, so backup and migration work can finish.
|
|
41
|
+
8. Do not assume a migration is harmless just because the command exists.
|
|
42
|
+
|
|
43
|
+
## Interpretation
|
|
44
|
+
|
|
45
|
+
- `cli_update_required` means the installed package version differs from the release manifest.
|
|
46
|
+
- `skills_update_required` means bundled agent skills should be reinstalled or synced.
|
|
47
|
+
- `migration_required` means the local schema and release manifest disagree, or the release
|
|
48
|
+
explicitly requires migration.
|
|
49
|
+
- `backup_required` means the update plan expects a database backup before structural work.
|
|
50
|
+
- `confirmation_required` means the agent should pause and get explicit user approval.
|
|
51
|
+
- `leads migrate --check` is read-only and reports the local DB migration action.
|
|
52
|
+
- `leads migrate --apply` creates a timestamped backup before supported structural changes and
|
|
53
|
+
refuses unknown migration paths.
|
|
54
|
+
|
|
55
|
+
## Guardrails
|
|
56
|
+
|
|
57
|
+
- Do not run destructive database operations from a plain update request.
|
|
58
|
+
- Do not hide skill updates inside a generic success message.
|
|
59
|
+
- Do not delete runs, specs, logs, backups, or the database unless the user explicitly confirms.
|
|
60
|
+
- Never expose API keys or raw secret values from the workspace config.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Leads Update Operator"
|
|
3
|
+
short_description: "Check and explain safe Leads updates"
|
|
4
|
+
default_prompt: "Use $leads-update-operator to run leads update --check, explain CLI, skill, and database changes separately, and ask before applying structural changes."
|