salesprompter-cli 0.1.0
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.
- package/.codex/environments/environment.toml +19 -0
- package/README.md +54 -0
- package/data/deel-icp.json +17 -0
- package/data/deel-leads.json +77 -0
- package/data/enriched.json +106 -0
- package/data/icp.json +24 -0
- package/data/leads.json +62 -0
- package/data/scored.json +142 -0
- package/dist/cli.js +114 -0
- package/dist/domain.js +36 -0
- package/dist/engine.js +147 -0
- package/dist/io.js +17 -0
- package/dist/providers.js +1 -0
- package/dist/sample-data.js +34 -0
- package/dist-tests/src/cli.js +114 -0
- package/dist-tests/src/domain.js +36 -0
- package/dist-tests/src/engine.js +147 -0
- package/dist-tests/src/io.js +17 -0
- package/dist-tests/src/providers.js +1 -0
- package/dist-tests/src/sample-data.js +34 -0
- package/dist-tests/tests/cli.test.js +149 -0
- package/package.json +31 -0
- package/src/cli.ts +136 -0
- package/src/domain.ts +50 -0
- package/src/engine.ts +170 -0
- package/src/io.ts +21 -0
- package/src/providers.ts +22 -0
- package/src/sample-data.ts +37 -0
- package/tests/cli.test.ts +184 -0
- package/tsconfig.json +16 -0
- package/tsconfig.test.json +8 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# THIS IS AUTOGENERATED. DO NOT EDIT MANUALLY
|
|
2
|
+
version = 1
|
|
3
|
+
name = "salesprompter-cli"
|
|
4
|
+
|
|
5
|
+
[setup]
|
|
6
|
+
script = ""
|
|
7
|
+
|
|
8
|
+
[[actions]]
|
|
9
|
+
name = "Run"
|
|
10
|
+
icon = "run"
|
|
11
|
+
command = '''
|
|
12
|
+
npm login
|
|
13
|
+
npm publish --access public
|
|
14
|
+
'''
|
|
15
|
+
|
|
16
|
+
[[actions]]
|
|
17
|
+
name = "npm publish --access public"
|
|
18
|
+
icon = "tool"
|
|
19
|
+
command = "npm publish --access public"
|
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# salesprompter-cli
|
|
2
|
+
|
|
3
|
+
`salesprompter-cli` is a JSON-first command line interface for running a practical sales workflow:
|
|
4
|
+
|
|
5
|
+
- Define an ideal customer profile
|
|
6
|
+
- Generate seed leads
|
|
7
|
+
- Enrich leads
|
|
8
|
+
- Score leads
|
|
9
|
+
- Sync leads into CRM and outreach systems
|
|
10
|
+
|
|
11
|
+
The first version is intentionally local-first. It uses deterministic heuristics and dry-run sync providers so the command surface and data contracts are stable before real APIs are attached.
|
|
12
|
+
|
|
13
|
+
When you pass `--company-domain`, the CLI generates modeled contacts for that target account. These are synthetic leads for workflow testing, not verified real contacts.
|
|
14
|
+
|
|
15
|
+
## Why this shape works for humans and LLMs
|
|
16
|
+
|
|
17
|
+
- Every command reads and writes plain JSON.
|
|
18
|
+
- Output is machine-readable and composable.
|
|
19
|
+
- Domain contracts are explicit and validated with `zod`.
|
|
20
|
+
- External integrations are behind narrow provider interfaces.
|
|
21
|
+
|
|
22
|
+
## Commands
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
salesprompter icp:define --name "EU SaaS RevOps" \
|
|
26
|
+
--industries "Software,Financial Services" \
|
|
27
|
+
--company-sizes "50-199,200-499" \
|
|
28
|
+
--regions "Europe" \
|
|
29
|
+
--titles "Head of Revenue Operations,VP Sales" \
|
|
30
|
+
--required-signals "recent funding,growing outbound team" \
|
|
31
|
+
--out ./data/icp.json
|
|
32
|
+
|
|
33
|
+
salesprompter leads:generate --icp ./data/icp.json --count 5 --out ./data/leads.json
|
|
34
|
+
salesprompter leads:generate --icp ./data/icp.json --count 5 --company-domain deel.com --company-name Deel --out ./data/deel-leads.json
|
|
35
|
+
salesprompter leads:enrich --in ./data/leads.json --out ./data/enriched.json
|
|
36
|
+
salesprompter leads:score --icp ./data/icp.json --in ./data/enriched.json --out ./data/scored.json
|
|
37
|
+
salesprompter sync:crm --target hubspot --in ./data/scored.json
|
|
38
|
+
salesprompter sync:outreach --target instantly --in ./data/scored.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Development
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm install
|
|
45
|
+
npm run build
|
|
46
|
+
node ./dist/cli.js --help
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Next integrations
|
|
50
|
+
|
|
51
|
+
- Replace `HeuristicLeadProvider` with Apollo, Clay, LinkedIn, or custom data providers.
|
|
52
|
+
- Replace `HeuristicEnrichmentProvider` with enrichment APIs such as Clearbit, FullEnrich, or custom LLM workflows.
|
|
53
|
+
- Replace `DryRunSyncProvider` with real HubSpot, Salesforce, Pipedrive, Instantly, Apollo, or Outreach clients.
|
|
54
|
+
- Add prompt-oriented commands so an LLM can ask for ICP refinement or lead prioritization directly through the CLI.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Global HR Tech",
|
|
3
|
+
"industries": [
|
|
4
|
+
"Software"
|
|
5
|
+
],
|
|
6
|
+
"companySizes": [],
|
|
7
|
+
"regions": [
|
|
8
|
+
"Global"
|
|
9
|
+
],
|
|
10
|
+
"titles": [
|
|
11
|
+
"VP Sales",
|
|
12
|
+
"Head of Revenue Operations"
|
|
13
|
+
],
|
|
14
|
+
"pains": [],
|
|
15
|
+
"requiredSignals": [],
|
|
16
|
+
"excludedSignals": []
|
|
17
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"companyName": "Deel",
|
|
4
|
+
"domain": "deel.com",
|
|
5
|
+
"industry": "Software",
|
|
6
|
+
"region": "Global",
|
|
7
|
+
"employeeCount": 180,
|
|
8
|
+
"contactName": "Jordan Patel",
|
|
9
|
+
"title": "VP Sales",
|
|
10
|
+
"email": "jordan.patel@deel.com",
|
|
11
|
+
"source": "heuristic-target-account",
|
|
12
|
+
"signals": [
|
|
13
|
+
"hiring sales reps",
|
|
14
|
+
"expanding into new regions"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"companyName": "Deel",
|
|
19
|
+
"domain": "deel.com",
|
|
20
|
+
"industry": "Software",
|
|
21
|
+
"region": "Global",
|
|
22
|
+
"employeeCount": 320,
|
|
23
|
+
"contactName": "Taylor Morgan",
|
|
24
|
+
"title": "Head of Revenue Operations",
|
|
25
|
+
"email": "taylor.morgan@deel.com",
|
|
26
|
+
"source": "heuristic-target-account",
|
|
27
|
+
"signals": [
|
|
28
|
+
"recent funding",
|
|
29
|
+
"using fragmented sales tooling"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"companyName": "Deel",
|
|
34
|
+
"domain": "deel.com",
|
|
35
|
+
"industry": "Software",
|
|
36
|
+
"region": "Global",
|
|
37
|
+
"employeeCount": 85,
|
|
38
|
+
"contactName": "Morgan Diaz",
|
|
39
|
+
"title": "VP Sales",
|
|
40
|
+
"email": "morgan.diaz@deel.com",
|
|
41
|
+
"source": "heuristic-target-account",
|
|
42
|
+
"signals": [
|
|
43
|
+
"expanding into new regions",
|
|
44
|
+
"growing outbound team"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"companyName": "Deel",
|
|
49
|
+
"domain": "deel.com",
|
|
50
|
+
"industry": "Software",
|
|
51
|
+
"region": "Global",
|
|
52
|
+
"employeeCount": 540,
|
|
53
|
+
"contactName": "Cameron Lee",
|
|
54
|
+
"title": "Head of Revenue Operations",
|
|
55
|
+
"email": "cameron.lee@deel.com",
|
|
56
|
+
"source": "heuristic-target-account",
|
|
57
|
+
"signals": [
|
|
58
|
+
"using fragmented sales tooling",
|
|
59
|
+
"launching new product line"
|
|
60
|
+
]
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"companyName": "Deel",
|
|
64
|
+
"domain": "deel.com",
|
|
65
|
+
"industry": "Software",
|
|
66
|
+
"region": "Global",
|
|
67
|
+
"employeeCount": 260,
|
|
68
|
+
"contactName": "Riley Brooks",
|
|
69
|
+
"title": "VP Sales",
|
|
70
|
+
"email": "riley.brooks@deel.com",
|
|
71
|
+
"source": "heuristic-target-account",
|
|
72
|
+
"signals": [
|
|
73
|
+
"growing outbound team",
|
|
74
|
+
"hiring sales reps"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
]
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"companyName": "Northstar Freight",
|
|
4
|
+
"domain": "northstarfreight.com",
|
|
5
|
+
"industry": "Software",
|
|
6
|
+
"region": "Europe",
|
|
7
|
+
"employeeCount": 180,
|
|
8
|
+
"contactName": "Jordan Patel",
|
|
9
|
+
"title": "Head of Revenue Operations",
|
|
10
|
+
"email": "jordan.patel@northstarfreight.com",
|
|
11
|
+
"source": "heuristic-seed",
|
|
12
|
+
"signals": [
|
|
13
|
+
"hiring sales reps",
|
|
14
|
+
"expanding into new regions"
|
|
15
|
+
],
|
|
16
|
+
"techStack": [
|
|
17
|
+
"HubSpot",
|
|
18
|
+
"Instantly"
|
|
19
|
+
],
|
|
20
|
+
"crmFit": "medium",
|
|
21
|
+
"outreachFit": "medium",
|
|
22
|
+
"buyingStage": "solution-aware",
|
|
23
|
+
"notes": [
|
|
24
|
+
"Northstar Freight matches the Software segment.",
|
|
25
|
+
"Jordan Patel is likely close to revenue tooling decisions."
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"companyName": "Brightpath Health",
|
|
30
|
+
"domain": "brightpathhealth.io",
|
|
31
|
+
"industry": "Financial Services",
|
|
32
|
+
"region": "Europe",
|
|
33
|
+
"employeeCount": 320,
|
|
34
|
+
"contactName": "Taylor Morgan",
|
|
35
|
+
"title": "VP Sales",
|
|
36
|
+
"email": "taylor.morgan@brightpathhealth.io",
|
|
37
|
+
"source": "heuristic-seed",
|
|
38
|
+
"signals": [
|
|
39
|
+
"recent funding",
|
|
40
|
+
"using fragmented sales tooling"
|
|
41
|
+
],
|
|
42
|
+
"techStack": [
|
|
43
|
+
"Salesforce",
|
|
44
|
+
"Outreach"
|
|
45
|
+
],
|
|
46
|
+
"crmFit": "high",
|
|
47
|
+
"outreachFit": "medium",
|
|
48
|
+
"buyingStage": "active-evaluation",
|
|
49
|
+
"notes": [
|
|
50
|
+
"Brightpath Health matches the Financial Services segment.",
|
|
51
|
+
"Taylor Morgan is likely close to revenue tooling decisions."
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"companyName": "ForgeOps Cloud",
|
|
56
|
+
"domain": "forgeopscloud.dev",
|
|
57
|
+
"industry": "Software",
|
|
58
|
+
"region": "Europe",
|
|
59
|
+
"employeeCount": 85,
|
|
60
|
+
"contactName": "Morgan Diaz",
|
|
61
|
+
"title": "Head of Revenue Operations",
|
|
62
|
+
"email": "morgan.diaz@forgeopscloud.dev",
|
|
63
|
+
"source": "heuristic-seed",
|
|
64
|
+
"signals": [
|
|
65
|
+
"expanding into new regions",
|
|
66
|
+
"growing outbound team"
|
|
67
|
+
],
|
|
68
|
+
"techStack": [
|
|
69
|
+
"Apollo",
|
|
70
|
+
"Clay"
|
|
71
|
+
],
|
|
72
|
+
"crmFit": "low",
|
|
73
|
+
"outreachFit": "high",
|
|
74
|
+
"buyingStage": "solution-aware",
|
|
75
|
+
"notes": [
|
|
76
|
+
"ForgeOps Cloud matches the Software segment.",
|
|
77
|
+
"Morgan Diaz is likely close to revenue tooling decisions."
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"companyName": "Summit Retail Group",
|
|
82
|
+
"domain": "summitretailgroup.com",
|
|
83
|
+
"industry": "Financial Services",
|
|
84
|
+
"region": "Europe",
|
|
85
|
+
"employeeCount": 540,
|
|
86
|
+
"contactName": "Cameron Lee",
|
|
87
|
+
"title": "VP Sales",
|
|
88
|
+
"email": "cameron.lee@summitretailgroup.com",
|
|
89
|
+
"source": "heuristic-seed",
|
|
90
|
+
"signals": [
|
|
91
|
+
"using fragmented sales tooling",
|
|
92
|
+
"launching new product line"
|
|
93
|
+
],
|
|
94
|
+
"techStack": [
|
|
95
|
+
"Instantly",
|
|
96
|
+
"Segment"
|
|
97
|
+
],
|
|
98
|
+
"crmFit": "high",
|
|
99
|
+
"outreachFit": "medium",
|
|
100
|
+
"buyingStage": "solution-aware",
|
|
101
|
+
"notes": [
|
|
102
|
+
"Summit Retail Group matches the Financial Services segment.",
|
|
103
|
+
"Cameron Lee is likely close to revenue tooling decisions."
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
]
|
package/data/icp.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "EU SaaS RevOps",
|
|
3
|
+
"industries": [
|
|
4
|
+
"Software",
|
|
5
|
+
"Financial Services"
|
|
6
|
+
],
|
|
7
|
+
"companySizes": [
|
|
8
|
+
"50-199",
|
|
9
|
+
"200-499"
|
|
10
|
+
],
|
|
11
|
+
"regions": [
|
|
12
|
+
"Europe"
|
|
13
|
+
],
|
|
14
|
+
"titles": [
|
|
15
|
+
"Head of Revenue Operations",
|
|
16
|
+
"VP Sales"
|
|
17
|
+
],
|
|
18
|
+
"pains": [],
|
|
19
|
+
"requiredSignals": [
|
|
20
|
+
"recent funding",
|
|
21
|
+
"growing outbound team"
|
|
22
|
+
],
|
|
23
|
+
"excludedSignals": []
|
|
24
|
+
}
|
package/data/leads.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"companyName": "Northstar Freight",
|
|
4
|
+
"domain": "northstarfreight.com",
|
|
5
|
+
"industry": "Software",
|
|
6
|
+
"region": "Europe",
|
|
7
|
+
"employeeCount": 180,
|
|
8
|
+
"contactName": "Jordan Patel",
|
|
9
|
+
"title": "Head of Revenue Operations",
|
|
10
|
+
"email": "jordan.patel@northstarfreight.com",
|
|
11
|
+
"source": "heuristic-seed",
|
|
12
|
+
"signals": [
|
|
13
|
+
"hiring sales reps",
|
|
14
|
+
"expanding into new regions"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"companyName": "Brightpath Health",
|
|
19
|
+
"domain": "brightpathhealth.io",
|
|
20
|
+
"industry": "Financial Services",
|
|
21
|
+
"region": "Europe",
|
|
22
|
+
"employeeCount": 320,
|
|
23
|
+
"contactName": "Taylor Morgan",
|
|
24
|
+
"title": "VP Sales",
|
|
25
|
+
"email": "taylor.morgan@brightpathhealth.io",
|
|
26
|
+
"source": "heuristic-seed",
|
|
27
|
+
"signals": [
|
|
28
|
+
"recent funding",
|
|
29
|
+
"using fragmented sales tooling"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"companyName": "ForgeOps Cloud",
|
|
34
|
+
"domain": "forgeopscloud.dev",
|
|
35
|
+
"industry": "Software",
|
|
36
|
+
"region": "Europe",
|
|
37
|
+
"employeeCount": 85,
|
|
38
|
+
"contactName": "Morgan Diaz",
|
|
39
|
+
"title": "Head of Revenue Operations",
|
|
40
|
+
"email": "morgan.diaz@forgeopscloud.dev",
|
|
41
|
+
"source": "heuristic-seed",
|
|
42
|
+
"signals": [
|
|
43
|
+
"expanding into new regions",
|
|
44
|
+
"growing outbound team"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"companyName": "Summit Retail Group",
|
|
49
|
+
"domain": "summitretailgroup.com",
|
|
50
|
+
"industry": "Financial Services",
|
|
51
|
+
"region": "Europe",
|
|
52
|
+
"employeeCount": 540,
|
|
53
|
+
"contactName": "Cameron Lee",
|
|
54
|
+
"title": "VP Sales",
|
|
55
|
+
"email": "cameron.lee@summitretailgroup.com",
|
|
56
|
+
"source": "heuristic-seed",
|
|
57
|
+
"signals": [
|
|
58
|
+
"using fragmented sales tooling",
|
|
59
|
+
"launching new product line"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
]
|
package/data/scored.json
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"companyName": "Northstar Freight",
|
|
4
|
+
"domain": "northstarfreight.com",
|
|
5
|
+
"industry": "Software",
|
|
6
|
+
"region": "Europe",
|
|
7
|
+
"employeeCount": 180,
|
|
8
|
+
"contactName": "Jordan Patel",
|
|
9
|
+
"title": "Head of Revenue Operations",
|
|
10
|
+
"email": "jordan.patel@northstarfreight.com",
|
|
11
|
+
"source": "heuristic-seed",
|
|
12
|
+
"signals": [
|
|
13
|
+
"hiring sales reps",
|
|
14
|
+
"expanding into new regions"
|
|
15
|
+
],
|
|
16
|
+
"techStack": [
|
|
17
|
+
"HubSpot",
|
|
18
|
+
"Instantly"
|
|
19
|
+
],
|
|
20
|
+
"crmFit": "medium",
|
|
21
|
+
"outreachFit": "medium",
|
|
22
|
+
"buyingStage": "solution-aware",
|
|
23
|
+
"notes": [
|
|
24
|
+
"Northstar Freight matches the Software segment.",
|
|
25
|
+
"Jordan Patel is likely close to revenue tooling decisions."
|
|
26
|
+
],
|
|
27
|
+
"score": 90,
|
|
28
|
+
"grade": "A",
|
|
29
|
+
"rationale": [
|
|
30
|
+
"Industry matches ICP.",
|
|
31
|
+
"Region matches ICP.",
|
|
32
|
+
"Company size matches ICP.",
|
|
33
|
+
"Contact title matches ICP."
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"companyName": "Brightpath Health",
|
|
38
|
+
"domain": "brightpathhealth.io",
|
|
39
|
+
"industry": "Financial Services",
|
|
40
|
+
"region": "Europe",
|
|
41
|
+
"employeeCount": 320,
|
|
42
|
+
"contactName": "Taylor Morgan",
|
|
43
|
+
"title": "VP Sales",
|
|
44
|
+
"email": "taylor.morgan@brightpathhealth.io",
|
|
45
|
+
"source": "heuristic-seed",
|
|
46
|
+
"signals": [
|
|
47
|
+
"recent funding",
|
|
48
|
+
"using fragmented sales tooling"
|
|
49
|
+
],
|
|
50
|
+
"techStack": [
|
|
51
|
+
"Salesforce",
|
|
52
|
+
"Outreach"
|
|
53
|
+
],
|
|
54
|
+
"crmFit": "high",
|
|
55
|
+
"outreachFit": "medium",
|
|
56
|
+
"buyingStage": "active-evaluation",
|
|
57
|
+
"notes": [
|
|
58
|
+
"Brightpath Health matches the Financial Services segment.",
|
|
59
|
+
"Taylor Morgan is likely close to revenue tooling decisions."
|
|
60
|
+
],
|
|
61
|
+
"score": 100,
|
|
62
|
+
"grade": "A",
|
|
63
|
+
"rationale": [
|
|
64
|
+
"Industry matches ICP.",
|
|
65
|
+
"Region matches ICP.",
|
|
66
|
+
"Company size matches ICP.",
|
|
67
|
+
"Contact title matches ICP.",
|
|
68
|
+
"Matched 1 required buying signals.",
|
|
69
|
+
"Strong CRM fit."
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"companyName": "ForgeOps Cloud",
|
|
74
|
+
"domain": "forgeopscloud.dev",
|
|
75
|
+
"industry": "Software",
|
|
76
|
+
"region": "Europe",
|
|
77
|
+
"employeeCount": 85,
|
|
78
|
+
"contactName": "Morgan Diaz",
|
|
79
|
+
"title": "Head of Revenue Operations",
|
|
80
|
+
"email": "morgan.diaz@forgeopscloud.dev",
|
|
81
|
+
"source": "heuristic-seed",
|
|
82
|
+
"signals": [
|
|
83
|
+
"expanding into new regions",
|
|
84
|
+
"growing outbound team"
|
|
85
|
+
],
|
|
86
|
+
"techStack": [
|
|
87
|
+
"Apollo",
|
|
88
|
+
"Clay"
|
|
89
|
+
],
|
|
90
|
+
"crmFit": "low",
|
|
91
|
+
"outreachFit": "high",
|
|
92
|
+
"buyingStage": "solution-aware",
|
|
93
|
+
"notes": [
|
|
94
|
+
"ForgeOps Cloud matches the Software segment.",
|
|
95
|
+
"Morgan Diaz is likely close to revenue tooling decisions."
|
|
96
|
+
],
|
|
97
|
+
"score": 100,
|
|
98
|
+
"grade": "A",
|
|
99
|
+
"rationale": [
|
|
100
|
+
"Industry matches ICP.",
|
|
101
|
+
"Region matches ICP.",
|
|
102
|
+
"Company size matches ICP.",
|
|
103
|
+
"Contact title matches ICP.",
|
|
104
|
+
"Matched 1 required buying signals.",
|
|
105
|
+
"Strong outreach fit."
|
|
106
|
+
]
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"companyName": "Summit Retail Group",
|
|
110
|
+
"domain": "summitretailgroup.com",
|
|
111
|
+
"industry": "Financial Services",
|
|
112
|
+
"region": "Europe",
|
|
113
|
+
"employeeCount": 540,
|
|
114
|
+
"contactName": "Cameron Lee",
|
|
115
|
+
"title": "VP Sales",
|
|
116
|
+
"email": "cameron.lee@summitretailgroup.com",
|
|
117
|
+
"source": "heuristic-seed",
|
|
118
|
+
"signals": [
|
|
119
|
+
"using fragmented sales tooling",
|
|
120
|
+
"launching new product line"
|
|
121
|
+
],
|
|
122
|
+
"techStack": [
|
|
123
|
+
"Instantly",
|
|
124
|
+
"Segment"
|
|
125
|
+
],
|
|
126
|
+
"crmFit": "high",
|
|
127
|
+
"outreachFit": "medium",
|
|
128
|
+
"buyingStage": "solution-aware",
|
|
129
|
+
"notes": [
|
|
130
|
+
"Summit Retail Group matches the Financial Services segment.",
|
|
131
|
+
"Cameron Lee is likely close to revenue tooling decisions."
|
|
132
|
+
],
|
|
133
|
+
"score": 85,
|
|
134
|
+
"grade": "A",
|
|
135
|
+
"rationale": [
|
|
136
|
+
"Industry matches ICP.",
|
|
137
|
+
"Region matches ICP.",
|
|
138
|
+
"Contact title matches ICP.",
|
|
139
|
+
"Strong CRM fit."
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
]
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { EnrichedLeadSchema, IcpSchema, LeadSchema, ScoredLeadSchema, SyncTargetSchema } from "./domain.js";
|
|
5
|
+
import { DryRunSyncProvider, HeuristicEnrichmentProvider, HeuristicLeadProvider, HeuristicScoringProvider } from "./engine.js";
|
|
6
|
+
import { readJsonFile, splitCsv, writeJsonFile } from "./io.js";
|
|
7
|
+
const program = new Command();
|
|
8
|
+
const leadProvider = new HeuristicLeadProvider();
|
|
9
|
+
const enrichmentProvider = new HeuristicEnrichmentProvider();
|
|
10
|
+
const scoringProvider = new HeuristicScoringProvider();
|
|
11
|
+
const syncProvider = new DryRunSyncProvider();
|
|
12
|
+
function printOutput(value) {
|
|
13
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
14
|
+
}
|
|
15
|
+
program
|
|
16
|
+
.name("salesprompter")
|
|
17
|
+
.description("Sales workflow CLI for ICP definition, lead generation, enrichment, scoring, and sync.")
|
|
18
|
+
.version("0.1.0");
|
|
19
|
+
program
|
|
20
|
+
.command("icp:define")
|
|
21
|
+
.description("Define an ideal customer profile and write it to a JSON file.")
|
|
22
|
+
.requiredOption("--name <name>", "Human-readable ICP name")
|
|
23
|
+
.option("--industries <items>", "Comma-separated industries", "")
|
|
24
|
+
.option("--company-sizes <items>", "Comma-separated buckets like 1-49,50-199,200-499,500+", "")
|
|
25
|
+
.option("--regions <items>", "Comma-separated regions", "")
|
|
26
|
+
.option("--titles <items>", "Comma-separated titles", "")
|
|
27
|
+
.option("--pains <items>", "Comma-separated pain points", "")
|
|
28
|
+
.option("--required-signals <items>", "Comma-separated required signals", "")
|
|
29
|
+
.option("--excluded-signals <items>", "Comma-separated excluded signals", "")
|
|
30
|
+
.requiredOption("--out <path>", "Output file path")
|
|
31
|
+
.action(async (options) => {
|
|
32
|
+
const icp = IcpSchema.parse({
|
|
33
|
+
name: options.name,
|
|
34
|
+
industries: splitCsv(options.industries),
|
|
35
|
+
companySizes: splitCsv(options.companySizes),
|
|
36
|
+
regions: splitCsv(options.regions),
|
|
37
|
+
titles: splitCsv(options.titles),
|
|
38
|
+
pains: splitCsv(options.pains),
|
|
39
|
+
requiredSignals: splitCsv(options.requiredSignals),
|
|
40
|
+
excludedSignals: splitCsv(options.excludedSignals)
|
|
41
|
+
});
|
|
42
|
+
await writeJsonFile(options.out, icp);
|
|
43
|
+
printOutput({ status: "ok", icp });
|
|
44
|
+
});
|
|
45
|
+
program
|
|
46
|
+
.command("leads:generate")
|
|
47
|
+
.description("Generate seed leads against an ICP.")
|
|
48
|
+
.requiredOption("--icp <path>", "Path to ICP JSON")
|
|
49
|
+
.option("--count <number>", "Number of leads to generate", "10")
|
|
50
|
+
.option("--company-domain <domain>", "Target a specific company domain like deel.com")
|
|
51
|
+
.option("--company-name <name>", "Optional company name override for a targeted domain")
|
|
52
|
+
.requiredOption("--out <path>", "Output file path")
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
const icp = await readJsonFile(options.icp, IcpSchema);
|
|
55
|
+
const count = z.coerce.number().int().min(1).max(1000).parse(options.count);
|
|
56
|
+
const target = {
|
|
57
|
+
companyDomain: options.companyDomain,
|
|
58
|
+
companyName: options.companyName
|
|
59
|
+
};
|
|
60
|
+
const leads = await leadProvider.generateLeads(icp, count, target);
|
|
61
|
+
await writeJsonFile(options.out, leads);
|
|
62
|
+
printOutput({ status: "ok", generated: leads.length, out: options.out, target: target.companyDomain ?? null });
|
|
63
|
+
});
|
|
64
|
+
program
|
|
65
|
+
.command("leads:enrich")
|
|
66
|
+
.description("Enrich leads with fit, buying stage, and tech stack data.")
|
|
67
|
+
.requiredOption("--in <path>", "Path to lead JSON array")
|
|
68
|
+
.requiredOption("--out <path>", "Output file path")
|
|
69
|
+
.action(async (options) => {
|
|
70
|
+
const leads = await readJsonFile(options.in, z.array(LeadSchema));
|
|
71
|
+
const enriched = await enrichmentProvider.enrichLeads(leads);
|
|
72
|
+
await writeJsonFile(options.out, enriched);
|
|
73
|
+
printOutput({ status: "ok", enriched: enriched.length, out: options.out });
|
|
74
|
+
});
|
|
75
|
+
program
|
|
76
|
+
.command("leads:score")
|
|
77
|
+
.description("Score enriched leads against an ICP.")
|
|
78
|
+
.requiredOption("--icp <path>", "Path to ICP JSON")
|
|
79
|
+
.requiredOption("--in <path>", "Path to enriched lead JSON array")
|
|
80
|
+
.requiredOption("--out <path>", "Output file path")
|
|
81
|
+
.action(async (options) => {
|
|
82
|
+
const icp = await readJsonFile(options.icp, IcpSchema);
|
|
83
|
+
const leads = await readJsonFile(options.in, z.array(EnrichedLeadSchema));
|
|
84
|
+
const scored = await scoringProvider.scoreLeads(icp, leads);
|
|
85
|
+
await writeJsonFile(options.out, scored);
|
|
86
|
+
printOutput({ status: "ok", scored: scored.length, out: options.out });
|
|
87
|
+
});
|
|
88
|
+
program
|
|
89
|
+
.command("sync:crm")
|
|
90
|
+
.description("Dry-run sync scored leads into a CRM target.")
|
|
91
|
+
.requiredOption("--target <target>", "hubspot|salesforce|pipedrive")
|
|
92
|
+
.requiredOption("--in <path>", "Path to scored lead JSON array")
|
|
93
|
+
.action(async (options) => {
|
|
94
|
+
const target = SyncTargetSchema.parse(options.target);
|
|
95
|
+
const leads = await readJsonFile(options.in, z.array(ScoredLeadSchema));
|
|
96
|
+
const result = await syncProvider.sync(target, leads);
|
|
97
|
+
printOutput({ status: "ok", ...result });
|
|
98
|
+
});
|
|
99
|
+
program
|
|
100
|
+
.command("sync:outreach")
|
|
101
|
+
.description("Dry-run sync scored leads into an outreach platform.")
|
|
102
|
+
.requiredOption("--target <target>", "apollo|instantly|outreach")
|
|
103
|
+
.requiredOption("--in <path>", "Path to scored lead JSON array")
|
|
104
|
+
.action(async (options) => {
|
|
105
|
+
const target = SyncTargetSchema.parse(options.target);
|
|
106
|
+
const leads = await readJsonFile(options.in, z.array(ScoredLeadSchema));
|
|
107
|
+
const result = await syncProvider.sync(target, leads);
|
|
108
|
+
printOutput({ status: "ok", ...result });
|
|
109
|
+
});
|
|
110
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
111
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
112
|
+
process.stderr.write(`${message}\n`);
|
|
113
|
+
process.exitCode = 1;
|
|
114
|
+
});
|
package/dist/domain.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const IcpSchema = z.object({
|
|
3
|
+
name: z.string().min(1),
|
|
4
|
+
industries: z.array(z.string().min(1)).default([]),
|
|
5
|
+
companySizes: z.array(z.string().min(1)).default([]),
|
|
6
|
+
regions: z.array(z.string().min(1)).default([]),
|
|
7
|
+
titles: z.array(z.string().min(1)).default([]),
|
|
8
|
+
pains: z.array(z.string().min(1)).default([]),
|
|
9
|
+
requiredSignals: z.array(z.string().min(1)).default([]),
|
|
10
|
+
excludedSignals: z.array(z.string().min(1)).default([]),
|
|
11
|
+
});
|
|
12
|
+
export const LeadSchema = z.object({
|
|
13
|
+
companyName: z.string().min(1),
|
|
14
|
+
domain: z.string().min(1),
|
|
15
|
+
industry: z.string().min(1),
|
|
16
|
+
region: z.string().min(1),
|
|
17
|
+
employeeCount: z.number().int().nonnegative(),
|
|
18
|
+
contactName: z.string().min(1),
|
|
19
|
+
title: z.string().min(1),
|
|
20
|
+
email: z.string().email(),
|
|
21
|
+
source: z.string().min(1),
|
|
22
|
+
signals: z.array(z.string().min(1)).default([]),
|
|
23
|
+
});
|
|
24
|
+
export const EnrichedLeadSchema = LeadSchema.extend({
|
|
25
|
+
techStack: z.array(z.string().min(1)).default([]),
|
|
26
|
+
crmFit: z.enum(["high", "medium", "low"]),
|
|
27
|
+
outreachFit: z.enum(["high", "medium", "low"]),
|
|
28
|
+
buyingStage: z.enum(["problem-aware", "solution-aware", "active-evaluation"]),
|
|
29
|
+
notes: z.array(z.string().min(1)).default([]),
|
|
30
|
+
});
|
|
31
|
+
export const ScoredLeadSchema = EnrichedLeadSchema.extend({
|
|
32
|
+
score: z.number().int().min(0).max(100),
|
|
33
|
+
grade: z.enum(["A", "B", "C", "D"]),
|
|
34
|
+
rationale: z.array(z.string().min(1)).default([]),
|
|
35
|
+
});
|
|
36
|
+
export const SyncTargetSchema = z.enum(["hubspot", "salesforce", "pipedrive", "apollo", "instantly", "outreach"]);
|