salesprompter-cli 0.1.11 → 0.1.12

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.
Files changed (2) hide show
  1. package/dist/cli.js +87 -9
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -369,6 +369,26 @@ async function runTargetAccountWizard(rl) {
369
369
  leadArgs.push("--out", leadsPath);
370
370
  writeWizardLine(` ${buildCommandLine(leadArgs)}`);
371
371
  }
372
+ async function runLeadGenerationWizard(rl) {
373
+ const source = await promptChoice(rl, "How do you want to generate leads?", [
374
+ {
375
+ value: "target-account",
376
+ label: "At a specific company",
377
+ description: "Example: find people at deel.com"
378
+ },
379
+ {
380
+ value: "vendor-lookup",
381
+ label: "From BigQuery",
382
+ description: "Use an ICP to search lead data you already have in BigQuery"
383
+ }
384
+ ], "target-account");
385
+ writeWizardLine();
386
+ if (source === "target-account") {
387
+ await runTargetAccountWizard(rl);
388
+ return;
389
+ }
390
+ await runVendorLookupWizard(rl);
391
+ }
372
392
  async function runVendorLookupWizard(rl) {
373
393
  const vendor = await promptChoice(rl, "Which product are you selling?", [{ value: "deel", label: "Deel", description: "Use Deel's built-in ICP template" }], "deel");
374
394
  writeWizardLine();
@@ -446,6 +466,64 @@ async function runVendorLookupWizard(rl) {
446
466
  }
447
467
  writeWizardLine(` ${buildCommandLine(lookupArgs)}`);
448
468
  }
469
+ async function runOutreachSyncWizard(rl) {
470
+ const target = await promptChoice(rl, "Which outreach tool do you want to use?", [
471
+ {
472
+ value: "instantly",
473
+ label: "Instantly",
474
+ description: "Create campaign leads from a scored leads JSON file"
475
+ }
476
+ ], "instantly");
477
+ writeWizardLine();
478
+ if (!process.env.INSTANTLY_API_KEY || process.env.INSTANTLY_API_KEY.trim().length === 0) {
479
+ throw new Error("INSTANTLY_API_KEY is required for the Instantly sync flow.");
480
+ }
481
+ const inputPath = await promptText(rl, "Where is your scored leads JSON file?", {
482
+ defaultValue: "./data/scored.json",
483
+ required: true
484
+ });
485
+ const defaultCampaignId = process.env.INSTANTLY_CAMPAIGN_ID?.trim();
486
+ const campaignId = await promptText(rl, "Instantly campaign ID", {
487
+ defaultValue: defaultCampaignId && defaultCampaignId.length > 0 ? defaultCampaignId : undefined,
488
+ required: defaultCampaignId === undefined || defaultCampaignId.length === 0
489
+ });
490
+ const apply = await promptYesNo(rl, "Create the leads in Instantly now?", false);
491
+ const allowDuplicates = await promptYesNo(rl, "Allow duplicate emails in the campaign?", false);
492
+ writeWizardLine();
493
+ const leads = await readJsonFile(inputPath, z.array(ScoredLeadSchema));
494
+ const result = await syncProvider.sync(target, leads, {
495
+ apply,
496
+ instantlyCampaignId: campaignId,
497
+ allowDuplicates
498
+ });
499
+ const skipped = result.skipped ?? 0;
500
+ writeWizardLine(`${apply ? "Sent" : "Prepared"} ${result.synced} lead${result.synced === 1 ? "" : "s"} for ${target}.`);
501
+ if (skipped > 0) {
502
+ writeWizardLine(`Skipped ${skipped} duplicate lead${skipped === 1 ? "" : "s"}.`);
503
+ }
504
+ if (result.dryRun) {
505
+ writeWizardLine("This was a dry run. Re-run and confirm the write when you are ready.");
506
+ }
507
+ writeWizardLine();
508
+ writeWizardLine("Equivalent raw command:");
509
+ const syncArgs = [
510
+ "salesprompter",
511
+ "sync:outreach",
512
+ "--target",
513
+ target,
514
+ "--in",
515
+ inputPath,
516
+ "--campaign-id",
517
+ campaignId
518
+ ];
519
+ if (allowDuplicates) {
520
+ syncArgs.push("--allow-duplicates");
521
+ }
522
+ if (apply) {
523
+ syncArgs.push("--apply");
524
+ }
525
+ writeWizardLine(` ${buildCommandLine(syncArgs)}`);
526
+ }
449
527
  async function runWizard(options) {
450
528
  if (runtimeOutputOptions.json || runtimeOutputOptions.quiet) {
451
529
  throw new Error("wizard does not support --json or --quiet.");
@@ -466,14 +544,14 @@ async function runWizard(options) {
466
544
  description: "Example: I sell Deel and want the kind of companies Deel sells to"
467
545
  },
468
546
  {
469
- value: "target-account",
470
- label: "Find people at a specific company",
471
- description: "Example: find contacts at deel.com"
547
+ value: "lead-generation",
548
+ label: "Generate leads",
549
+ description: "Find people at a target company or from your BigQuery data"
472
550
  },
473
551
  {
474
- value: "vendor-lookup",
475
- label: "Search BigQuery for matching leads",
476
- description: "Best if your lead data is already in BigQuery and you want SQL or results"
552
+ value: "outreach-sync",
553
+ label: "Send leads to outreach",
554
+ description: "Push scored leads into Instantly"
477
555
  }
478
556
  ], "vendor-icp");
479
557
  writeWizardLine();
@@ -481,11 +559,11 @@ async function runWizard(options) {
481
559
  await runVendorIcpWizard(rl);
482
560
  return;
483
561
  }
484
- if (flow === "target-account") {
485
- await runTargetAccountWizard(rl);
562
+ if (flow === "lead-generation") {
563
+ await runLeadGenerationWizard(rl);
486
564
  return;
487
565
  }
488
- await runVendorLookupWizard(rl);
566
+ await runOutreachSyncWizard(rl);
489
567
  }
490
568
  finally {
491
569
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salesprompter-cli",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "JSON-first sales prospecting CLI for ICP definition, lead generation, enrichment, scoring, and CRM/outreach sync.",
5
5
  "type": "module",
6
6
  "bin": {