salesprompter-cli 0.1.2 → 0.1.3

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/README.md CHANGED
@@ -12,6 +12,25 @@
12
12
  - Analyze upstream lead-list and domain-enrichment bottlenecks
13
13
  - Replace opaque Pipedream logic with deterministic CLI workflows
14
14
 
15
+ ## Documentation
16
+
17
+ This repository now includes a Mintlify docs site for the wider Salesprompter universe, including the app contract, CLI surface, Chrome extension contract, and the main warehouse-backed workflows.
18
+
19
+ - Docs home: `./index.mdx`
20
+ - Quickstart: `./quickstart.mdx`
21
+ - Architecture: `./architecture.mdx`
22
+ - App: `./platform/app.mdx`
23
+ - CLI: `./platform/cli.mdx`
24
+ - Chrome extension: `./platform/chrome-extension.mdx`
25
+ - Domain finder: `./workflows/domain-finder.mdx`
26
+ - Command reference: `./reference/cli.mdx`
27
+
28
+ Run the docs locally with:
29
+
30
+ ```bash
31
+ npm run docs:dev
32
+ ```
33
+
15
34
  ## Integration Contract
16
35
 
17
36
  This CLI is not a standalone toy. It is a production integration surface for the Salesprompter app.
@@ -39,11 +58,11 @@ Global output flags:
39
58
  The CLI stores a local session file at `~/.config/salesprompter/auth-session.json` (or `SALESPROMPTER_CONFIG_DIR`).
40
59
 
41
60
  ```bash
42
- # Device flow through Salesprompter backend (recommended)
43
- salesprompter auth:login
61
+ # Production path: generate a short-lived CLI token in the Salesprompter app
62
+ salesprompter auth:login --token "$SALESPROMPTER_TOKEN" --api-url "https://salesprompter.ai"
44
63
 
45
- # Direct login using app-issued bearer token
46
- salesprompter auth:login --token "$SALESPROMPTER_TOKEN"
64
+ # Optional: use device flow only if your Salesprompter app exposes it
65
+ salesprompter auth:login
47
66
 
48
67
  # Verify active identity with backend
49
68
  salesprompter auth:whoami --verify
@@ -54,7 +73,7 @@ salesprompter auth:logout
54
73
 
55
74
  Environment variables:
56
75
 
57
- - `SALESPROMPTER_API_BASE_URL`: override backend URL (default `https://app.salesprompter.com`)
76
+ - `SALESPROMPTER_API_BASE_URL`: override backend URL (default `https://salesprompter.ai`)
58
77
  - `SALESPROMPTER_CONFIG_DIR`: override local config dir
59
78
  - `SALESPROMPTER_SKIP_AUTH=1`: bypass auth guard (tests/dev only)
60
79
  - `INSTANTLY_API_KEY`: required for real `sync:outreach --target instantly`
@@ -63,11 +82,12 @@ Environment variables:
63
82
 
64
83
  App compatibility:
65
84
 
66
- - If your app exposes `/api/cli/auth/device/start` and `/api/cli/auth/device/poll`, use `salesprompter auth:login`.
85
+ - Current Salesprompter production uses app-issued CLI tokens.
86
+ - If your app exposes `/api/cli/auth/device/start` and `/api/cli/auth/device/poll`, `salesprompter auth:login` will use device flow.
67
87
  - If device auth is not enabled, create a CLI token from the app endpoint `POST /api/cli/auth/token` and use:
68
88
 
69
89
  ```bash
70
- salesprompter auth:login --token "<token-from-app>"
90
+ salesprompter auth:login --token "<token-from-app>" --api-url "https://salesprompter.ai"
71
91
  ```
72
92
 
73
93
  ## Why this shape works for humans and LLMs
package/dist/auth.js CHANGED
@@ -2,7 +2,7 @@ import os from "node:os";
2
2
  import path from "node:path";
3
3
  import { access, mkdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import { z } from "zod";
5
- const DEFAULT_API_BASE_URL = "https://app.salesprompter.com";
5
+ const DEFAULT_API_BASE_URL = "https://salesprompter.ai";
6
6
  const CLIENT_HEADER = "salesprompter-cli/0.2";
7
7
  const DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 3;
8
8
  const DEFAULT_DEVICE_TIMEOUT_SECONDS = 180;
@@ -94,6 +94,18 @@ function normalizeApiBaseUrl(apiBaseUrl) {
94
94
  const value = (apiBaseUrl ?? process.env.SALESPROMPTER_API_BASE_URL ?? DEFAULT_API_BASE_URL).trim();
95
95
  return value.replace(/\/+$/, "");
96
96
  }
97
+ function isDeviceFlowUnavailableError(message) {
98
+ if (message.includes("invalid JSON response")) {
99
+ return true;
100
+ }
101
+ return /request failed \((401|403|404|405|500|501|502|503|504)\)/.test(message);
102
+ }
103
+ function buildDeviceFlowUnavailableMessage(apiBaseUrl) {
104
+ return [
105
+ "device login is not configured on this Salesprompter app.",
106
+ `Generate a CLI token in the app and run \`salesprompter auth:login --token <token> --api-url "${apiBaseUrl}"\`.`
107
+ ].join(" ");
108
+ }
97
109
  async function hasSessionFile() {
98
110
  try {
99
111
  await access(getSessionPath());
@@ -106,7 +118,18 @@ async function hasSessionFile() {
106
118
  async function httpJson(url, init, schema) {
107
119
  const response = await fetch(url, init);
108
120
  const text = await response.text();
109
- const payload = text.length > 0 ? JSON.parse(text) : {};
121
+ let payload = {};
122
+ if (text.length > 0) {
123
+ try {
124
+ payload = JSON.parse(text);
125
+ }
126
+ catch {
127
+ if (!response.ok) {
128
+ throw new Error(`request failed (${response.status}) for ${url}`);
129
+ }
130
+ throw new Error(`invalid JSON response for ${url}`);
131
+ }
132
+ }
110
133
  if (!response.ok) {
111
134
  throw new Error(`request failed (${response.status}) for ${url}`);
112
135
  }
@@ -195,8 +218,8 @@ export async function loginWithDeviceFlow(options) {
195
218
  }
196
219
  catch (error) {
197
220
  const message = error instanceof Error ? error.message : String(error);
198
- if (message.includes("(404)")) {
199
- throw new Error("device login is not configured on this Salesprompter app. Generate a CLI token in the app and run `salesprompter auth:login --token <token>`.");
221
+ if (isDeviceFlowUnavailableError(message)) {
222
+ throw new Error(buildDeviceFlowUnavailableMessage(apiBaseUrl));
200
223
  }
201
224
  throw error;
202
225
  }
package/dist/cli.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  import { Command } from "commander";
3
4
  import { z } from "zod";
4
5
  import { clearAuthSession, loginWithDeviceFlow, loginWithToken, requireAuthSession, shouldBypassAuth, verifySession } from "./auth.js";
@@ -11,6 +12,8 @@ import { buildHistoricalVendorIcp, buildVendorIcp } from "./icp-templates.js";
11
12
  import { InstantlySyncProvider } from "./instantly.js";
12
13
  import { buildLeadlistsFunnelQueries } from "./leadlists-funnel.js";
13
14
  import { readJsonFile, splitCsv, writeJsonFile, writeTextFile } from "./io.js";
15
+ const require = createRequire(import.meta.url);
16
+ const { version: packageVersion } = require("../package.json");
14
17
  const program = new Command();
15
18
  const leadProvider = new AccountLeadProvider(new HeuristicCompanyProvider(), new HeuristicPeopleSearchProvider());
16
19
  const enrichmentProvider = new HeuristicEnrichmentProvider();
@@ -166,14 +169,14 @@ async function fetchHistoricalQueryRows(tables) {
166
169
  program
167
170
  .name("salesprompter")
168
171
  .description("Sales workflow CLI for ICP definition, lead generation, enrichment, scoring, and sync.")
169
- .version("0.1.1")
172
+ .version(packageVersion)
170
173
  .option("--json", "Emit compact machine-readable JSON output", false)
171
174
  .option("--quiet", "Suppress successful stdout output", false);
172
175
  program
173
176
  .command("auth:login")
174
- .description("Authenticate CLI with Salesprompter app credentials.")
177
+ .description("Authenticate CLI with a Salesprompter app token, or device flow if the app supports it.")
175
178
  .option("--token <token>", "App-issued bearer token for direct login")
176
- .option("--api-url <url>", "Salesprompter API base URL, defaults to SALESPROMPTER_API_BASE_URL or app.salesprompter.com")
179
+ .option("--api-url <url>", "Salesprompter API base URL, defaults to SALESPROMPTER_API_BASE_URL or salesprompter.ai")
177
180
  .option("--timeout-seconds <number>", "Device flow wait timeout in seconds", "180")
178
181
  .action(async (options) => {
179
182
  const timeoutSeconds = z.coerce.number().int().min(30).max(1800).parse(options.timeoutSeconds);
@@ -190,7 +193,9 @@ program
190
193
  return;
191
194
  }
192
195
  const startedAt = new Date().toISOString();
193
- process.stderr.write("Starting device login flow. Complete login in the browser.\n");
196
+ if (!runtimeOutputOptions.json && !runtimeOutputOptions.quiet) {
197
+ process.stderr.write("Starting device login flow. Complete login in the browser.\n");
198
+ }
194
199
  const result = await loginWithDeviceFlow({
195
200
  apiBaseUrl: options.apiUrl,
196
201
  timeoutSeconds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salesprompter-cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for defining ICPs, generating leads, enriching them, scoring them, and syncing to GTM tools.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,6 +13,9 @@
13
13
  "scripts": {
14
14
  "build": "tsc -p tsconfig.json",
15
15
  "check": "tsc --noEmit -p tsconfig.json",
16
+ "docs:dev": "npx mint dev",
17
+ "docs:broken-links": "npx mint broken-links",
18
+ "docs:a11y": "npx mint a11y",
16
19
  "start": "node ./dist/cli.js",
17
20
  "test": "npm run build && tsc -p tsconfig.test.json && node --test dist-tests/tests/**/*.test.js"
18
21
  },