salesprompter-cli 0.1.71 → 0.1.72
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 +2 -2
- package/dist/cli.js +22 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -175,12 +175,12 @@ the app's CLI imports view.
|
|
|
175
175
|
- Respect provider terms and customer data boundaries.
|
|
176
176
|
- `affiliate:grow` is an alias for `affiliate:run`. It excludes repeated `--seed-profile` customers, removes profiles already stored in prior workspace affiliate audiences, and verifies the final persisted count before preparing Instantly.
|
|
177
177
|
- If every collected profile is known or excluded, no audience or Instantly campaign is created. A stale Sales Navigator session also fails before persistence with a safe retry instruction.
|
|
178
|
-
- Affiliate outreach uses
|
|
178
|
+
- Affiliate outreach uses Hunter first, requires Hunter's `valid` verdict before import, and sends recovered addresses through Hunter Email Verifier before creating a draft Instantly campaign. Catch-all, disposable, webmail, invalid, unknown, claimed, and unresolved addresses are excluded. Instantly verification remains enabled as a second gate.
|
|
179
179
|
- Affiliate preparation uses exactly three emails with three observable variants per step; `affiliate:regenerate-sequence` rebuilds and syncs them through the Salesprompter app.
|
|
180
180
|
- `affiliate:list` shows safe workspace summaries. `affiliate:analytics` shows aggregate and step/variant outcomes without exposing lead data; unsupported per-step meeting and won fields render as `n/a`.
|
|
181
181
|
- `affiliate:run` defaults to `--timing-mode custom`, so its daily limit and weekday sending window are honored. Use `--timing-mode auto` only when capacity-derived scheduling is intended.
|
|
182
182
|
- `affiliate:enrich` starts durable email recovery and adds only newly found addresses to an existing campaign. It returns a background-processing status for large audiences instead of blocking the terminal. Pass `--source-audience-run-id` to merge a newer compatible audience into that campaign without creating a duplicate campaign.
|
|
183
|
-
- `affiliate:finish` closes the loop: it repairs stalled verification in 1,000-lead batches, quarantines stale pending or invalid leads outside the sending campaign, accepts an explicitly audited recovery fallback, activates only a fully verified campaign, and reads the live state back. Use `--requeue-pending` only after restoring Instantly verification capacity.
|
|
183
|
+
- `affiliate:finish` closes the loop: it requires persisted Hunter-valid evidence for new campaigns, repairs stalled Instantly verification in 1,000-lead batches, quarantines stale pending or invalid leads outside the sending campaign, accepts an explicitly audited recovery fallback, activates only a fully verified campaign, and reads the live state back. Use `--requeue-pending` only after restoring Instantly verification capacity.
|
|
184
184
|
- A draft campaign does not send until `affiliate:activate` is run.
|
|
185
185
|
- The CLI is designed for interactive users and agent-assisted workflows.
|
|
186
186
|
- A repo-local Chrome extension compatibility copy is available in `chrome-extension/` for local LinkedIn session sync and popup copy/debug flows.
|
package/dist/cli.js
CHANGED
|
@@ -283,6 +283,8 @@ const AffiliateOutreachHealthSchema = z.object({
|
|
|
283
283
|
pendingVerification: z.number().int().nonnegative(),
|
|
284
284
|
invalid: z.number().int().nonnegative(),
|
|
285
285
|
unsafe: z.number().int().nonnegative(),
|
|
286
|
+
hunterVerified: z.number().int().nonnegative().default(0),
|
|
287
|
+
hunterEvidenceMissing: z.number().int().nonnegative().default(0),
|
|
286
288
|
contacted: z.number().int().nonnegative(),
|
|
287
289
|
replied: z.number().int().nonnegative(),
|
|
288
290
|
statusCounts: z.record(z.string(), z.number().int().nonnegative()),
|
|
@@ -6903,18 +6905,23 @@ async function finishAffiliateOutreachViaApp(session, audienceRunId, options) {
|
|
|
6903
6905
|
}
|
|
6904
6906
|
function describeAffiliateOutreachHealth(health) {
|
|
6905
6907
|
const leads = health.leads;
|
|
6908
|
+
const hunterSummary = leads
|
|
6909
|
+
? leads.hunterEvidenceMissing > 0
|
|
6910
|
+
? `Hunter evidence recorded for ${leads.hunterVerified}/${leads.total} leads (${leads.hunterEvidenceMissing} legacy or missing)`
|
|
6911
|
+
: `${leads.hunterVerified}/${leads.total} Hunter-valid`
|
|
6912
|
+
: null;
|
|
6906
6913
|
if (health.done && leads) {
|
|
6907
|
-
return `Done: the campaign is running with ${leads.verified}/${leads.total} verified leads.`;
|
|
6914
|
+
return `Done: the campaign is running with ${leads.verified}/${leads.total} Instantly-verified leads; ${hunterSummary}.`;
|
|
6908
6915
|
}
|
|
6909
6916
|
if (health.verdict === "unsafe_running" && leads) {
|
|
6910
6917
|
return `Attention: the campaign is running with ${leads.unsafe} unsafe leads.`;
|
|
6911
6918
|
}
|
|
6912
6919
|
if (health.verdict === "ready_to_activate" && leads) {
|
|
6913
|
-
return `Ready to activate: ${leads.verified}/${leads.total}
|
|
6920
|
+
return `Ready to activate: ${leads.verified}/${leads.total} Instantly-verified; ${hunterSummary}.`;
|
|
6914
6921
|
}
|
|
6915
6922
|
if (health.liveChecked && leads) {
|
|
6916
6923
|
const campaignState = health.campaign?.statusLabel ?? "unknown";
|
|
6917
|
-
return `Not done: the campaign is ${campaignState}; ${leads.verified}/${leads.total}
|
|
6924
|
+
return `Not done: the campaign is ${campaignState}; ${leads.verified}/${leads.total} Instantly-verified; ${hunterSummary}; ${leads.contacted} contacted.`;
|
|
6918
6925
|
}
|
|
6919
6926
|
return health.blockers[0]?.message ?? "Live campaign status could not be verified.";
|
|
6920
6927
|
}
|
|
@@ -13985,6 +13992,9 @@ function parseAffiliateOutreachCommandOptions(options) {
|
|
|
13985
13992
|
if (!parsedTimingMode.success) {
|
|
13986
13993
|
throw new Error("--timing-mode must be either auto or custom.");
|
|
13987
13994
|
}
|
|
13995
|
+
if (options.allowAcceptAll) {
|
|
13996
|
+
throw new Error("--allow-accept-all is no longer supported. Affiliate outreach requires Hunter status valid.");
|
|
13997
|
+
}
|
|
13988
13998
|
const trimmedCampaignName = options.campaignName?.trim();
|
|
13989
13999
|
const campaignName = trimmedCampaignName
|
|
13990
14000
|
? z.string().max(120, "--campaign-name must be 120 characters or fewer.").parse(trimmedCampaignName)
|
|
@@ -13994,7 +14004,7 @@ function parseAffiliateOutreachCommandOptions(options) {
|
|
|
13994
14004
|
language: z.string().trim().min(1).max(40).parse(options.language),
|
|
13995
14005
|
numberOfSteps: 3,
|
|
13996
14006
|
minEmailScore: z.coerce.number().int().min(0).max(100).parse(options.minEmailScore),
|
|
13997
|
-
allowAcceptAll:
|
|
14007
|
+
allowAcceptAll: false,
|
|
13998
14008
|
timingMode: parsedTimingMode.data,
|
|
13999
14009
|
dailyLimit: z.coerce.number().int().min(1).max(1000).parse(options.dailyLimit),
|
|
14000
14010
|
timezone: z.string().trim().min(1).max(100).parse(options.timezone),
|
|
@@ -15169,7 +15179,7 @@ addAffiliateAudienceOptions(program
|
|
|
15169
15179
|
.option("--language <language>", "Sequence language", "English")
|
|
15170
15180
|
.option("--steps <number>", "Exactly 3 sequence emails (fixed)", "3")
|
|
15171
15181
|
.option("--min-email-score <number>", "Minimum Hunter confidence score", "80")
|
|
15172
|
-
.option("--allow-accept-all", "
|
|
15182
|
+
.option("--allow-accept-all", "Deprecated: catch-all emails are rejected", false)
|
|
15173
15183
|
.option("--timing-mode <mode>", "Schedule mode: custom honors the daily limit and sending window; auto derives them from capacity", "custom")
|
|
15174
15184
|
.option("--daily-limit <number>", "Maximum new leads contacted per day", "25")
|
|
15175
15185
|
.option("--timezone <timezone>", "Instantly sending timezone", "America/Detroit")
|
|
@@ -15243,6 +15253,13 @@ addAffiliateAudienceOptions(program
|
|
|
15243
15253
|
? "complete"
|
|
15244
15254
|
: "not_reported",
|
|
15245
15255
|
persistence: "verified",
|
|
15256
|
+
emailVerification: {
|
|
15257
|
+
provider: "hunter",
|
|
15258
|
+
policy: "valid_only",
|
|
15259
|
+
verified: Number(finalOutreach.stats.hunterVerifiedEmails ?? 0),
|
|
15260
|
+
rejected: Number(finalOutreach.stats.hunterRejectedEmails ?? 0),
|
|
15261
|
+
secondaryProvider: "instantly"
|
|
15262
|
+
},
|
|
15246
15263
|
outreach: finalOutreach.status,
|
|
15247
15264
|
activation: finalOutreach.status === "active" ? "complete" : "not_requested",
|
|
15248
15265
|
},
|
package/package.json
CHANGED