salesprompter-cli 0.1.26 → 0.1.27

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 (3) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.js +158 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,7 +5,7 @@ Salesprompter CLI helps you go from company or product input to qualified leads
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm i -g salesprompter-cli
8
+ curl -fsSL https://docs.salesprompter.ai/install.sh | bash
9
9
  ```
10
10
 
11
11
  or run directly:
@@ -17,6 +17,12 @@ npx -y salesprompter-cli@latest
17
17
  ## Quickstart
18
18
 
19
19
  ```bash
20
+ # Run first-time setup
21
+ salesprompter setup
22
+
23
+ # Run a local health check
24
+ salesprompter doctor
25
+
20
26
  # Sign in from the CLI
21
27
  salesprompter auth:login
22
28
 
@@ -32,7 +38,7 @@ For headless or automation use, generate a CLI token in the app and run `salespr
32
38
 
33
39
  ```bash
34
40
  # Start the guided workflow
35
- salesprompter
41
+ salesprompter wizard
36
42
 
37
43
  # Show machine-readable output
38
44
  salesprompter --json auth:whoami
@@ -44,6 +50,9 @@ salesprompter contacts:find-linkedin-urls --in ./contacts.tsv --out ./contacts.e
44
50
  # When authenticated, Salesprompter first enriches company domains in the app, then the CLI builds the email batch.
45
51
  salesprompter contacts:resolve-emails --in ./contacts.tsv --out-dir ./email-run --dry-run
46
52
 
53
+ # See included capability packs
54
+ salesprompter packs:list
55
+
47
56
  # Explore the full command surface
48
57
  salesprompter --help
49
58
  ```
package/dist/cli.js CHANGED
@@ -248,6 +248,36 @@ const SalesNavigatorCrawlReportResponseSchema = z.object({
248
248
  status: z.literal("ok"),
249
249
  job: SalesNavigatorCrawlJobSummarySchema
250
250
  });
251
+ const cliPacks = [
252
+ {
253
+ slug: "contacts",
254
+ title: "Contacts",
255
+ summary: "Resolve profile URLs and work from pasted contact lists.",
256
+ commands: ["contacts:resolve-profiles", "contacts:resolve-emails"],
257
+ installStatus: "included"
258
+ },
259
+ {
260
+ slug: "research",
261
+ title: "Research",
262
+ summary: "Scrape markets and enrich companies before outreach.",
263
+ commands: ["market:scrape", "companies:enrich"],
264
+ installStatus: "included"
265
+ },
266
+ {
267
+ slug: "discovery",
268
+ title: "Discovery",
269
+ summary: "Find leads from product and market inputs.",
270
+ commands: ["leads:discover", "search:run", "search:status", "search:export", "search:count"],
271
+ installStatus: "included"
272
+ },
273
+ {
274
+ slug: "outreach",
275
+ title: "Outreach",
276
+ summary: "Prepare and sync qualified leads into downstream systems.",
277
+ commands: ["sync:outreach", "sync:crm"],
278
+ installStatus: "included"
279
+ }
280
+ ];
251
281
  const helpAliasByCommandName = new Map([
252
282
  ["contacts:find-linkedin-urls", "contacts:resolve-profiles"],
253
283
  ["contacts:process-emails", "contacts:resolve-emails"],
@@ -260,6 +290,11 @@ const helpAliasByCommandName = new Map([
260
290
  ["salesnav:count", "search:count"]
261
291
  ]);
262
292
  const helpVisibleCommandNames = new Set([
293
+ "setup",
294
+ "doctor",
295
+ "packs:list",
296
+ "packs:add",
297
+ "upgrade",
263
298
  "auth:login",
264
299
  "wizard",
265
300
  "auth:whoami",
@@ -4512,6 +4547,9 @@ program.configureHelp({
4512
4547
  });
4513
4548
  program.addHelpText("after", `
4514
4549
  LLM operator tips:
4550
+ - Install with: curl -fsSL https://docs.salesprompter.ai/install.sh | bash
4551
+ - First-run setup: salesprompter setup
4552
+ - Run a quick health check: salesprompter doctor
4515
4553
  - New here? Create your account at https://salesprompter.ai/sign-up, then run: salesprompter auth:login
4516
4554
  - Prefer non-interactive auth: set SALESPROMPTER_TOKEN (+ optional SALESPROMPTER_API_BASE_URL).
4517
4555
  - Use machine output for tools: add --json.
@@ -4519,6 +4557,117 @@ LLM operator tips:
4519
4557
  - Preview contact enrichment first: contacts:resolve-profiles --in <contacts.tsv> --dry-run.
4520
4558
  - For bigger runs, start with a small sample before processing the full file.
4521
4559
  `);
4560
+ program
4561
+ .command("setup")
4562
+ .description("Run the fastest first-run setup path for the Salesprompter CLI.")
4563
+ .option("--api-url <url>", "Salesprompter API base URL, defaults to SALESPROMPTER_API_BASE_URL or salesprompter.ai")
4564
+ .option("--timeout-seconds <number>", "Auth login timeout in seconds when setup needs to sign in", "180")
4565
+ .action(async (options) => {
4566
+ const timeoutSeconds = z.coerce.number().int().min(30).max(1800).parse(options.timeoutSeconds);
4567
+ printOutput({
4568
+ status: "ok",
4569
+ command: "setup",
4570
+ next: [
4571
+ "salesprompter auth:login",
4572
+ "salesprompter auth:whoami --verify",
4573
+ "salesprompter wizard"
4574
+ ],
4575
+ docs: "https://docs.salesprompter.ai/quickstart"
4576
+ });
4577
+ if (process.stdin.isTTY && process.stdout.isTTY && !runtimeOutputOptions.json && !runtimeOutputOptions.quiet) {
4578
+ await runWizard({
4579
+ apiUrl: options.apiUrl,
4580
+ timeoutSeconds
4581
+ });
4582
+ }
4583
+ });
4584
+ program
4585
+ .command("doctor")
4586
+ .description("Check local CLI prerequisites, auth state, and optional enrichment setup.")
4587
+ .action(async () => {
4588
+ const nodeMajor = Number(process.versions.node.split(".")[0] ?? "0");
4589
+ const readiness = await resolveLlmAuthReadiness();
4590
+ const hasOpenAiKey = Boolean(process.env.OPENAI_API_KEY || process.env.SALESPROMPTER_OPENAI_API_KEY);
4591
+ const hasLinkedInSession = Boolean(process.env.LINKEDIN_CSRF_TOKEN ||
4592
+ process.env.SALESPROMPTER_LINKEDIN_CSRF_TOKEN ||
4593
+ process.env.LINKEDIN_X_LI_IDENTITY ||
4594
+ process.env.SALESPROMPTER_LINKEDIN_X_LI_IDENTITY ||
4595
+ process.env.LINKEDIN_SALES_NAV_COOKIE ||
4596
+ process.env.SALESPROMPTER_LINKEDIN_SALES_NAV_COOKIE);
4597
+ printOutput({
4598
+ status: "ok",
4599
+ command: "doctor",
4600
+ checks: {
4601
+ node: {
4602
+ ok: nodeMajor >= 20,
4603
+ current: process.versions.node,
4604
+ required: ">=20.0.0"
4605
+ },
4606
+ auth: {
4607
+ ok: readiness.ready,
4608
+ mode: readiness.mode,
4609
+ apiBaseUrl: readiness.apiBaseUrl,
4610
+ reason: readiness.reason ?? null
4611
+ },
4612
+ companyCleaningAi: {
4613
+ ok: hasOpenAiKey,
4614
+ envVarPresent: hasOpenAiKey
4615
+ },
4616
+ linkedInSession: {
4617
+ ok: hasLinkedInSession,
4618
+ envVarPresent: hasLinkedInSession
4619
+ }
4620
+ },
4621
+ recommended: [
4622
+ readiness.ready ? null : "salesprompter auth:login",
4623
+ hasOpenAiKey ? null : "Set OPENAI_API_KEY to enable --company-cleaning ai",
4624
+ hasLinkedInSession ? null : "Set LINKEDIN_CSRF_TOKEN, LINKEDIN_X_LI_IDENTITY, and LINKEDIN_SALES_NAV_COOKIE for direct LinkedIn lookup"
4625
+ ].filter(Boolean)
4626
+ });
4627
+ });
4628
+ program
4629
+ .command("packs:list")
4630
+ .description("Show the product capability packs included in the CLI.")
4631
+ .action(() => {
4632
+ printOutput({
4633
+ status: "ok",
4634
+ packs: cliPacks
4635
+ });
4636
+ });
4637
+ program
4638
+ .command("packs:add")
4639
+ .description("Explain how to unlock a capability pack in the Salesprompter CLI.")
4640
+ .argument("<pack>", "Pack slug, for example contacts, research, discovery, or outreach")
4641
+ .action((pack) => {
4642
+ const normalized = String(pack).trim().toLowerCase();
4643
+ const match = cliPacks.find((entry) => entry.slug === normalized);
4644
+ if (!match) {
4645
+ throw new Error(`Unknown pack "${pack}". Run "salesprompter packs:list" to see the supported packs.`);
4646
+ }
4647
+ printOutput({
4648
+ status: "ok",
4649
+ pack: match.slug,
4650
+ title: match.title,
4651
+ available: true,
4652
+ installStatus: match.installStatus,
4653
+ commands: match.commands,
4654
+ message: `The ${match.title} pack is already included. Start with: salesprompter ${match.commands[0]}`
4655
+ });
4656
+ });
4657
+ program
4658
+ .command("upgrade")
4659
+ .description("Show the recommended upgrade command for the current installation.")
4660
+ .action(() => {
4661
+ printOutput({
4662
+ status: "ok",
4663
+ command: "upgrade",
4664
+ recommended: {
4665
+ npmGlobal: "npm i -g salesprompter-cli@latest",
4666
+ npx: "npx -y salesprompter-cli@latest",
4667
+ docs: "https://docs.salesprompter.ai/quickstart"
4668
+ }
4669
+ });
4670
+ });
4522
4671
  program
4523
4672
  .command("auth:login")
4524
4673
  .description("Authenticate CLI with a Salesprompter app token, or device flow if the app supports it.")
@@ -4734,10 +4883,18 @@ program
4734
4883
  program.hook("preAction", async (_thisCommand, actionCommand) => {
4735
4884
  applyGlobalOutputOptions(actionCommand);
4736
4885
  const commandName = actionCommand.name();
4886
+ const parentCommandName = actionCommand.parent && typeof actionCommand.parent.name === "function"
4887
+ ? actionCommand.parent.name()
4888
+ : "";
4737
4889
  if (commandName.startsWith("auth:") ||
4890
+ commandName === "setup" ||
4891
+ commandName === "doctor" ||
4892
+ commandName === "upgrade" ||
4738
4893
  commandName === "wizard" ||
4739
4894
  commandName === "llm:ready" ||
4740
- commandName === "contacts:find-linkedin-urls") {
4895
+ commandName === "contacts:find-linkedin-urls" ||
4896
+ commandName.startsWith("packs:") ||
4897
+ ((commandName === "list" || commandName === "add") && parentCommandName === "packs")) {
4741
4898
  return;
4742
4899
  }
4743
4900
  const commandOptions = actionCommand.opts();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salesprompter-cli",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "description": "Sales workflow CLI for guided lead generation, enrichment, scoring, and sync.",
5
5
  "type": "module",
6
6
  "bin": {