salesprompter-cli 0.1.15 → 0.1.16
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/dist/cli.js +148 -107
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
+
import { access } from "node:fs/promises";
|
|
3
4
|
import { createRequire } from "node:module";
|
|
4
5
|
import { emitKeypressEvents } from "node:readline";
|
|
5
6
|
import { createInterface } from "node:readline/promises";
|
|
@@ -196,6 +197,22 @@ function writeSessionSummary(session) {
|
|
|
196
197
|
writeWizardLine(`Workspace: ${orgLabel}`);
|
|
197
198
|
}
|
|
198
199
|
}
|
|
200
|
+
async function fileExists(filePath) {
|
|
201
|
+
try {
|
|
202
|
+
await access(filePath);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function buildLeadOutputPaths(baseSlug) {
|
|
210
|
+
return {
|
|
211
|
+
leadsPath: `./data/${baseSlug}-leads.json`,
|
|
212
|
+
enrichedPath: `./data/${baseSlug}-enriched.json`,
|
|
213
|
+
scoredPath: `./data/${baseSlug}-scored.json`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
199
216
|
function normalizeChoiceText(value) {
|
|
200
217
|
return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, " ").replace(/\s+/g, " ").trim();
|
|
201
218
|
}
|
|
@@ -385,6 +402,44 @@ async function promptYesNo(rl, prompt, defaultValue) {
|
|
|
385
402
|
writeWizardLine("Please answer yes or no.");
|
|
386
403
|
}
|
|
387
404
|
}
|
|
405
|
+
async function maybeSearchLeadDataNow(rl, options) {
|
|
406
|
+
const shouldSearch = await promptYesNo(rl, "Do you want to search your lead data for matches now?", false);
|
|
407
|
+
writeWizardLine();
|
|
408
|
+
if (!shouldSearch) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
await runVendorLookupWizard(rl, { icpPath: options.icpPath });
|
|
412
|
+
}
|
|
413
|
+
async function maybePrepareLeadsForOutreach(rl, options) {
|
|
414
|
+
const shouldScore = await promptYesNo(rl, "Do you want me to score these leads for outreach?", false);
|
|
415
|
+
writeWizardLine();
|
|
416
|
+
if (!shouldScore) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const { enrichedPath, scoredPath } = buildLeadOutputPaths(options.baseSlug);
|
|
420
|
+
const enriched = await enrichmentProvider.enrichLeads(options.leads);
|
|
421
|
+
const scored = await scoringProvider.scoreLeads(options.icp, enriched);
|
|
422
|
+
await writeJsonFile(enrichedPath, enriched);
|
|
423
|
+
await writeJsonFile(scoredPath, scored);
|
|
424
|
+
writeWizardLine(`Saved enriched leads to ${enrichedPath}.`);
|
|
425
|
+
writeWizardLine(`Saved scored leads to ${scoredPath}.`);
|
|
426
|
+
writeWizardLine();
|
|
427
|
+
writeWizardLine("Equivalent raw commands:");
|
|
428
|
+
writeWizardLine(` ${buildCommandLine(["salesprompter", "leads:enrich", "--in", options.leadPath, "--out", enrichedPath])}`);
|
|
429
|
+
writeWizardLine(` ${buildCommandLine(["salesprompter", "leads:score", "--icp", options.icpPath, "--in", enrichedPath, "--out", scoredPath])}`);
|
|
430
|
+
if (!process.env.INSTANTLY_API_KEY || process.env.INSTANTLY_API_KEY.trim().length === 0) {
|
|
431
|
+
writeWizardLine();
|
|
432
|
+
writeWizardLine("You can send the scored leads to Instantly later from the main menu.");
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
writeWizardLine();
|
|
436
|
+
const shouldSync = await promptYesNo(rl, "Do you want to send these leads to Instantly now?", false);
|
|
437
|
+
writeWizardLine();
|
|
438
|
+
if (!shouldSync) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
await runOutreachSyncWizard(rl, { inputPath: scoredPath });
|
|
442
|
+
}
|
|
388
443
|
async function ensureWizardSession(options) {
|
|
389
444
|
if (shouldBypassAuth()) {
|
|
390
445
|
return null;
|
|
@@ -412,11 +467,11 @@ async function ensureWizardSession(options) {
|
|
|
412
467
|
return result.session;
|
|
413
468
|
}
|
|
414
469
|
async function runVendorIcpWizard(rl) {
|
|
415
|
-
const startPoint = await promptChoice(rl, "How do you want to
|
|
470
|
+
const startPoint = await promptChoice(rl, "How do you want to build your ICP?", [
|
|
416
471
|
{
|
|
417
472
|
value: "custom",
|
|
418
|
-
label: "
|
|
419
|
-
description: "Answer a few questions about
|
|
473
|
+
label: "Start from scratch",
|
|
474
|
+
description: "Answer a few questions about the companies you want to sell to",
|
|
420
475
|
aliases: ["custom", "from scratch", "new profile"]
|
|
421
476
|
},
|
|
422
477
|
{
|
|
@@ -428,21 +483,17 @@ async function runVendorIcpWizard(rl) {
|
|
|
428
483
|
], "custom");
|
|
429
484
|
writeWizardLine();
|
|
430
485
|
if (startPoint === "custom") {
|
|
431
|
-
const productName = await promptText(rl, "What
|
|
432
|
-
const description = await promptText(rl, "
|
|
433
|
-
const industries = await promptText(rl, "
|
|
434
|
-
const companySizes = await promptText(rl, "
|
|
435
|
-
const regions = await promptText(rl, "
|
|
436
|
-
const countries = await promptText(rl, "
|
|
437
|
-
const titles = await promptText(rl, "
|
|
486
|
+
const productName = await promptText(rl, "What do you sell?", { required: true });
|
|
487
|
+
const description = await promptText(rl, "Short description (optional)");
|
|
488
|
+
const industries = await promptText(rl, "Industries to target (optional, comma-separated)");
|
|
489
|
+
const companySizes = await promptText(rl, "Company sizes to target (optional, comma-separated)");
|
|
490
|
+
const regions = await promptText(rl, "Regions to target (optional, comma-separated)");
|
|
491
|
+
const countries = await promptText(rl, "Countries to target (optional, comma-separated)");
|
|
492
|
+
const titles = await promptText(rl, "Job titles to target (optional, comma-separated)");
|
|
438
493
|
const keywords = await promptText(rl, "Keywords or buying signals (optional, comma-separated)");
|
|
439
494
|
writeWizardLine();
|
|
440
495
|
const slug = slugify(productName) || "icp";
|
|
441
|
-
const outPath =
|
|
442
|
-
defaultValue: `./data/${slug}-icp.json`,
|
|
443
|
-
required: true
|
|
444
|
-
});
|
|
445
|
-
writeWizardLine();
|
|
496
|
+
const outPath = `./data/${slug}-icp.json`;
|
|
446
497
|
const icp = IcpSchema.parse({
|
|
447
498
|
name: `${productName} ICP`,
|
|
448
499
|
description,
|
|
@@ -455,7 +506,7 @@ async function runVendorIcpWizard(rl) {
|
|
|
455
506
|
});
|
|
456
507
|
await writeJsonFile(outPath, icp);
|
|
457
508
|
writeWizardLine(`Created ${icp.name}.`);
|
|
458
|
-
writeWizardLine(`Saved
|
|
509
|
+
writeWizardLine(`Saved profile to ${outPath}.`);
|
|
459
510
|
writeWizardLine();
|
|
460
511
|
writeWizardLine("Equivalent raw command:");
|
|
461
512
|
const defineArgs = ["salesprompter", "icp:define", "--name", icp.name];
|
|
@@ -483,73 +534,42 @@ async function runVendorIcpWizard(rl) {
|
|
|
483
534
|
defineArgs.push("--out", outPath);
|
|
484
535
|
writeWizardLine(` ${buildCommandLine(defineArgs)}`);
|
|
485
536
|
writeWizardLine();
|
|
486
|
-
|
|
487
|
-
writeWizardLine(` ${buildCommandLine([
|
|
488
|
-
"salesprompter",
|
|
489
|
-
"leads:generate",
|
|
490
|
-
"--icp",
|
|
491
|
-
outPath,
|
|
492
|
-
"--count",
|
|
493
|
-
"5",
|
|
494
|
-
"--out",
|
|
495
|
-
`./data/${slug}-leads.json`
|
|
496
|
-
])}`);
|
|
537
|
+
await maybeSearchLeadDataNow(rl, { icpPath: outPath });
|
|
497
538
|
return;
|
|
498
539
|
}
|
|
499
540
|
const vendor = "deel";
|
|
500
541
|
writeWizardLine("Using the built-in Deel ICP template.");
|
|
501
542
|
writeWizardLine();
|
|
502
|
-
const market = await promptChoice(rl, "Which market do you want to
|
|
543
|
+
const market = await promptChoice(rl, "Which market do you want to focus on?", [
|
|
503
544
|
{ value: "dach", label: "DACH", description: "Germany, Austria, Switzerland" },
|
|
504
545
|
{ value: "europe", label: "Europe" },
|
|
505
546
|
{ value: "global", label: "Global" }
|
|
506
547
|
], "dach");
|
|
507
548
|
writeWizardLine();
|
|
508
|
-
const outPath =
|
|
509
|
-
defaultValue: `./data/${slugify(vendor)}-icp-${market}.json`,
|
|
510
|
-
required: true
|
|
511
|
-
});
|
|
512
|
-
writeWizardLine();
|
|
549
|
+
const outPath = `./data/${slugify(vendor)}-icp-${market}.json`;
|
|
513
550
|
const icp = buildVendorIcp(vendor, market);
|
|
514
551
|
await writeJsonFile(outPath, icp);
|
|
515
552
|
writeWizardLine(`Created ${icp.name}.`);
|
|
516
|
-
writeWizardLine(`Saved
|
|
553
|
+
writeWizardLine(`Saved profile to ${outPath}.`);
|
|
517
554
|
writeWizardLine();
|
|
518
555
|
writeWizardLine("Equivalent raw command:");
|
|
519
556
|
writeWizardLine(` ${buildCommandLine(["salesprompter", "icp:vendor", "--vendor", vendor, "--market", market, "--out", outPath])}`);
|
|
520
557
|
writeWizardLine();
|
|
521
|
-
|
|
522
|
-
writeWizardLine(` ${buildCommandLine([
|
|
523
|
-
"salesprompter",
|
|
524
|
-
"leads:lookup:bq",
|
|
525
|
-
"--icp",
|
|
526
|
-
outPath,
|
|
527
|
-
"--limit",
|
|
528
|
-
"100",
|
|
529
|
-
"--lead-out",
|
|
530
|
-
`./data/${slugify(vendor)}-leads.json`
|
|
531
|
-
])}`);
|
|
558
|
+
await maybeSearchLeadDataNow(rl, { icpPath: outPath });
|
|
532
559
|
}
|
|
533
560
|
async function runTargetAccountWizard(rl) {
|
|
534
|
-
const domain = normalizeDomainInput(await promptText(rl, "Which company
|
|
561
|
+
const domain = normalizeDomainInput(await promptText(rl, "Which company do you want leads from? Enter the domain", { required: true }));
|
|
535
562
|
writeWizardLine();
|
|
536
|
-
const companyName = await promptText(rl, "Company name
|
|
563
|
+
const companyName = await promptText(rl, "Company name (optional)");
|
|
537
564
|
const displayName = companyName || deriveCompanyNameFromDomain(domain);
|
|
538
|
-
const leadCount = z.coerce.number().int().min(1).max(1000).parse(await promptText(rl, "How many
|
|
539
|
-
const region = await promptText(rl, "
|
|
540
|
-
const industries = await promptText(rl, "
|
|
541
|
-
const titles = await promptText(rl, "
|
|
565
|
+
const leadCount = z.coerce.number().int().min(1).max(1000).parse(await promptText(rl, "How many people do you want?", { defaultValue: "5", required: true }));
|
|
566
|
+
const region = await promptText(rl, "Region", { defaultValue: "Global", required: true });
|
|
567
|
+
const industries = await promptText(rl, "Industries (optional, comma-separated)");
|
|
568
|
+
const titles = await promptText(rl, "Job titles (optional, comma-separated)");
|
|
542
569
|
writeWizardLine();
|
|
543
570
|
const slug = slugify(domain);
|
|
544
|
-
const icpPath =
|
|
545
|
-
|
|
546
|
-
required: true
|
|
547
|
-
});
|
|
548
|
-
const leadsPath = await promptText(rl, "Where should I save the generated leads JSON?", {
|
|
549
|
-
defaultValue: `./data/${slug}-leads.json`,
|
|
550
|
-
required: true
|
|
551
|
-
});
|
|
552
|
-
writeWizardLine();
|
|
571
|
+
const icpPath = `./data/${slug}-target-icp.json`;
|
|
572
|
+
const { leadsPath } = buildLeadOutputPaths(slug);
|
|
553
573
|
const icp = IcpSchema.parse({
|
|
554
574
|
name: `${displayName} target account`,
|
|
555
575
|
regions: region.length > 0 ? [region] : [],
|
|
@@ -563,7 +583,7 @@ async function runTargetAccountWizard(rl) {
|
|
|
563
583
|
});
|
|
564
584
|
await writeJsonFile(leadsPath, result.leads);
|
|
565
585
|
writeWizardLine(`Generated ${result.leads.length} leads for ${result.account.companyName} (${result.account.domain}).`);
|
|
566
|
-
writeWizardLine(`Saved
|
|
586
|
+
writeWizardLine(`Saved profile to ${icpPath}.`);
|
|
567
587
|
writeWizardLine(`Saved leads to ${leadsPath}.`);
|
|
568
588
|
if (result.warnings.length > 0) {
|
|
569
589
|
writeWizardLine();
|
|
@@ -589,6 +609,14 @@ async function runTargetAccountWizard(rl) {
|
|
|
589
609
|
}
|
|
590
610
|
leadArgs.push("--out", leadsPath);
|
|
591
611
|
writeWizardLine(` ${buildCommandLine(leadArgs)}`);
|
|
612
|
+
writeWizardLine();
|
|
613
|
+
await maybePrepareLeadsForOutreach(rl, {
|
|
614
|
+
baseSlug: slug,
|
|
615
|
+
icp,
|
|
616
|
+
icpPath,
|
|
617
|
+
leadPath: leadsPath,
|
|
618
|
+
leads: result.leads
|
|
619
|
+
});
|
|
592
620
|
}
|
|
593
621
|
async function runLeadGenerationWizard(rl) {
|
|
594
622
|
const source = await promptChoice(rl, "How do you want to generate leads?", [
|
|
@@ -600,8 +628,8 @@ async function runLeadGenerationWizard(rl) {
|
|
|
600
628
|
},
|
|
601
629
|
{
|
|
602
630
|
value: "vendor-lookup",
|
|
603
|
-
label: "From my
|
|
604
|
-
description: "
|
|
631
|
+
label: "From my own lead data",
|
|
632
|
+
description: "Search leads you already have in BigQuery",
|
|
605
633
|
aliases: ["bigquery", "warehouse", "my data", "from bigquery"]
|
|
606
634
|
}
|
|
607
635
|
], "target-account");
|
|
@@ -612,33 +640,24 @@ async function runLeadGenerationWizard(rl) {
|
|
|
612
640
|
}
|
|
613
641
|
await runVendorLookupWizard(rl);
|
|
614
642
|
}
|
|
615
|
-
async function runVendorLookupWizard(rl) {
|
|
616
|
-
const icpPath =
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
643
|
+
async function runVendorLookupWizard(rl, options) {
|
|
644
|
+
const icpPath = options?.icpPath
|
|
645
|
+
? options.icpPath
|
|
646
|
+
: await promptText(rl, "Which saved ICP should I use?", {
|
|
647
|
+
defaultValue: "./data/icp.json",
|
|
648
|
+
required: true
|
|
649
|
+
});
|
|
650
|
+
if (options?.icpPath) {
|
|
651
|
+
writeWizardLine(`Using profile from ${icpPath}.`);
|
|
652
|
+
}
|
|
653
|
+
const limit = z.coerce.number().int().min(1).max(5000).parse(await promptText(rl, "How many leads do you want?", { defaultValue: "100", required: true }));
|
|
654
|
+
const execute = await promptYesNo(rl, "Do you want me to run the BigQuery search now?", false);
|
|
622
655
|
writeWizardLine();
|
|
623
656
|
const icp = await readJsonFile(icpPath, IcpSchema);
|
|
624
657
|
const slug = slugify(icp.name) || "icp";
|
|
625
|
-
const sqlPath =
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
});
|
|
629
|
-
const rawPath = execute
|
|
630
|
-
? await promptText(rl, "Where should I save raw BigQuery rows?", {
|
|
631
|
-
defaultValue: `./data/${slug}-leads-raw.json`,
|
|
632
|
-
required: true
|
|
633
|
-
})
|
|
634
|
-
: "";
|
|
635
|
-
const leadPath = execute
|
|
636
|
-
? await promptText(rl, "Where should I save normalized leads?", {
|
|
637
|
-
defaultValue: `./data/${slug}-leads.json`,
|
|
638
|
-
required: true
|
|
639
|
-
})
|
|
640
|
-
: "";
|
|
641
|
-
writeWizardLine();
|
|
658
|
+
const sqlPath = `./data/${slug}-lookup.sql`;
|
|
659
|
+
const rawPath = `./data/${slug}-leads-raw.json`;
|
|
660
|
+
const { leadsPath: leadPath } = buildLeadOutputPaths(slug);
|
|
642
661
|
const sql = buildBigQueryLeadLookupSql(icp, {
|
|
643
662
|
table: "icpidentifier.SalesGPT.leadPool_new",
|
|
644
663
|
companyField: "companyName",
|
|
@@ -658,19 +677,19 @@ async function runVendorLookupWizard(rl) {
|
|
|
658
677
|
});
|
|
659
678
|
await writeTextFile(sqlPath, `${sql}\n`);
|
|
660
679
|
let executedRowCount = null;
|
|
680
|
+
let normalizedLeads = [];
|
|
661
681
|
if (execute) {
|
|
662
682
|
const rows = await runBigQueryQuery(sql, { maxRows: limit });
|
|
663
683
|
const parsedRows = z.array(z.record(z.string(), z.unknown())).parse(rows);
|
|
664
684
|
await writeJsonFile(rawPath, parsedRows);
|
|
665
|
-
|
|
685
|
+
normalizedLeads = normalizeBigQueryLeadRows(parsedRows);
|
|
666
686
|
await writeJsonFile(leadPath, normalizedLeads);
|
|
667
687
|
executedRowCount = parsedRows.length;
|
|
668
688
|
}
|
|
669
|
-
writeWizardLine(`
|
|
670
|
-
writeWizardLine(`Saved lookup SQL to ${sqlPath}.`);
|
|
689
|
+
writeWizardLine(`Saved search SQL to ${sqlPath}.`);
|
|
671
690
|
if (execute) {
|
|
672
691
|
writeWizardLine(`Saved ${executedRowCount ?? 0} raw rows to ${rawPath}.`);
|
|
673
|
-
writeWizardLine(`Saved
|
|
692
|
+
writeWizardLine(`Saved leads to ${leadPath}.`);
|
|
674
693
|
}
|
|
675
694
|
writeWizardLine();
|
|
676
695
|
writeWizardLine("Equivalent raw command:");
|
|
@@ -679,25 +698,47 @@ async function runVendorLookupWizard(rl) {
|
|
|
679
698
|
lookupArgs.push("--execute", "--out", rawPath, "--lead-out", leadPath);
|
|
680
699
|
}
|
|
681
700
|
writeWizardLine(` ${buildCommandLine(lookupArgs)}`);
|
|
701
|
+
if (!execute) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
writeWizardLine();
|
|
705
|
+
await maybePrepareLeadsForOutreach(rl, {
|
|
706
|
+
baseSlug: slug,
|
|
707
|
+
icp,
|
|
708
|
+
icpPath,
|
|
709
|
+
leadPath,
|
|
710
|
+
leads: normalizedLeads
|
|
711
|
+
});
|
|
682
712
|
}
|
|
683
|
-
async function runOutreachSyncWizard(rl) {
|
|
713
|
+
async function runOutreachSyncWizard(rl, options) {
|
|
684
714
|
const target = "instantly";
|
|
685
|
-
|
|
715
|
+
const targetLabel = "Instantly";
|
|
716
|
+
writeWizardLine(`Using ${targetLabel}.`);
|
|
686
717
|
writeWizardLine();
|
|
687
718
|
if (!process.env.INSTANTLY_API_KEY || process.env.INSTANTLY_API_KEY.trim().length === 0) {
|
|
688
719
|
throw new Error("INSTANTLY_API_KEY is required for the Instantly sync flow.");
|
|
689
720
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
721
|
+
let inputPath = options?.inputPath?.trim() ?? "";
|
|
722
|
+
if (inputPath.length === 0 && (await fileExists("./data/scored.json"))) {
|
|
723
|
+
inputPath = "./data/scored.json";
|
|
724
|
+
}
|
|
725
|
+
if (inputPath.length === 0) {
|
|
726
|
+
inputPath = await promptText(rl, "Where is your scored leads file?", {
|
|
727
|
+
defaultValue: "./data/scored.json",
|
|
728
|
+
required: true
|
|
729
|
+
});
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
writeWizardLine(`Using scored leads from ${inputPath}.`);
|
|
733
|
+
writeWizardLine();
|
|
734
|
+
}
|
|
694
735
|
const defaultCampaignId = process.env.INSTANTLY_CAMPAIGN_ID?.trim();
|
|
695
|
-
const campaignId = await promptText(rl, "Instantly campaign
|
|
736
|
+
const campaignId = await promptText(rl, "Which Instantly campaign should I use?", {
|
|
696
737
|
defaultValue: defaultCampaignId && defaultCampaignId.length > 0 ? defaultCampaignId : undefined,
|
|
697
738
|
required: defaultCampaignId === undefined || defaultCampaignId.length === 0
|
|
698
739
|
});
|
|
699
|
-
const apply = await promptYesNo(rl, "
|
|
700
|
-
const allowDuplicates = await promptYesNo(rl, "
|
|
740
|
+
const apply = await promptYesNo(rl, "Add these leads to Instantly now?", false);
|
|
741
|
+
const allowDuplicates = await promptYesNo(rl, "Keep leads that are already in the campaign?", false);
|
|
701
742
|
writeWizardLine();
|
|
702
743
|
const leads = await readJsonFile(inputPath, z.array(ScoredLeadSchema));
|
|
703
744
|
const result = await syncProvider.sync(target, leads, {
|
|
@@ -706,12 +747,12 @@ async function runOutreachSyncWizard(rl) {
|
|
|
706
747
|
allowDuplicates
|
|
707
748
|
});
|
|
708
749
|
const skipped = result.skipped ?? 0;
|
|
709
|
-
writeWizardLine(`${apply ? "Sent" : "Prepared"} ${result.synced} lead${result.synced === 1 ? "" : "s"} for ${
|
|
750
|
+
writeWizardLine(`${apply ? "Sent" : "Prepared"} ${result.synced} lead${result.synced === 1 ? "" : "s"} for ${targetLabel}.`);
|
|
710
751
|
if (skipped > 0) {
|
|
711
752
|
writeWizardLine(`Skipped ${skipped} duplicate lead${skipped === 1 ? "" : "s"}.`);
|
|
712
753
|
}
|
|
713
754
|
if (result.dryRun) {
|
|
714
|
-
writeWizardLine("
|
|
755
|
+
writeWizardLine("Nothing was sent yet. Re-run and confirm when you are ready.");
|
|
715
756
|
}
|
|
716
757
|
writeWizardLine();
|
|
717
758
|
writeWizardLine("Equivalent raw command:");
|
|
@@ -749,20 +790,20 @@ async function runWizard(options) {
|
|
|
749
790
|
const flow = await promptChoice(rl, "What do you want help with?", [
|
|
750
791
|
{
|
|
751
792
|
value: "vendor-icp",
|
|
752
|
-
label: "
|
|
753
|
-
description: "
|
|
793
|
+
label: "Define my ICP",
|
|
794
|
+
description: "Build the company profile you want to sell to",
|
|
754
795
|
aliases: ["icp", "ideal customer", "who to target", "targeting", "profile"]
|
|
755
796
|
},
|
|
756
797
|
{
|
|
757
798
|
value: "lead-generation",
|
|
758
799
|
label: "Generate leads",
|
|
759
|
-
description: "Find people at one company or from your
|
|
800
|
+
description: "Find people at one company or from your own lead data",
|
|
760
801
|
aliases: ["leads", "find leads", "lead generation", "find people"]
|
|
761
802
|
},
|
|
762
803
|
{
|
|
763
804
|
value: "outreach-sync",
|
|
764
|
-
label: "
|
|
765
|
-
description: "
|
|
805
|
+
label: "Send leads to Instantly",
|
|
806
|
+
description: "Use a scored leads file to fill an Instantly campaign",
|
|
766
807
|
aliases: ["instantly", "outreach", "send leads", "campaign"]
|
|
767
808
|
}
|
|
768
809
|
], "vendor-icp");
|
package/package.json
CHANGED