salesprompter-cli 0.1.51 → 0.1.53

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 +1 -0
  2. package/dist/cli.js +59 -3
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -72,6 +72,7 @@ salesprompter leads:collect \
72
72
 
73
73
  # Enrich one or more stored imports: Sales Navigator company -> official domain -> Hunter email
74
74
  # This updates workspace data only. It does not create or start outreach.
75
+ # Stale imported company ids fall back to exact-name Account Search automatically.
75
76
  salesprompter leads:enrich-import \
76
77
  --run-id "$CLI_IMPORT_RUN_ID"
77
78
 
package/dist/cli.js CHANGED
@@ -13864,6 +13864,7 @@ async function runSalesNavigatorImportEnrichmentCommand(options) {
13864
13864
  }
13865
13865
  };
13866
13866
  const detailCache = new Map();
13867
+ const companyIdsWithDetails = new Set();
13867
13868
  const enrichResolvedCompanies = async (resolutions) => {
13868
13869
  const resolutionBatchSize = 20;
13869
13870
  for (let offset = 0; offset < resolutions.length; offset += resolutionBatchSize) {
@@ -13886,12 +13887,18 @@ async function runSalesNavigatorImportEnrichmentCommand(options) {
13886
13887
  for (const companyId of ids) {
13887
13888
  const detail = cliImportCompanyRecord(results[companyId]);
13888
13889
  const statusValue = statuses[companyId];
13890
+ const errorValue = errors[companyId];
13891
+ const errorRecord = cliImportCompanyRecord(errorValue);
13892
+ const errorStatusValue = errorRecord?.status ?? errorRecord?.code;
13889
13893
  const status = typeof statusValue === "number"
13890
13894
  ? statusValue
13891
13895
  : typeof statusValue === "string" && /^\d+$/.test(statusValue)
13892
13896
  ? Number(statusValue)
13893
- : response.status;
13894
- const errorValue = errors[companyId];
13897
+ : typeof errorStatusValue === "number"
13898
+ ? errorStatusValue
13899
+ : typeof errorStatusValue === "string" && /^\d+$/.test(errorStatusValue)
13900
+ ? Number(errorStatusValue)
13901
+ : response.status;
13895
13902
  detailCache.set(companyId, {
13896
13903
  detail,
13897
13904
  status,
@@ -13903,14 +13910,59 @@ async function runSalesNavigatorImportEnrichmentCommand(options) {
13903
13910
  });
13904
13911
  }
13905
13912
  }
13906
- for (const resolution of resolutionBatch) {
13913
+ const fallbackResolutions = [];
13914
+ for (let index = 0; index < resolutionBatch.length; index += 1) {
13915
+ const resolution = resolutionBatch[index];
13907
13916
  const cached = detailCache.get(resolution.resolvedCompanyId ?? "");
13917
+ if (cached?.detail && resolution.resolvedCompanyId) {
13918
+ companyIdsWithDetails.add(resolution.resolvedCompanyId);
13919
+ }
13920
+ if (!cached?.detail &&
13921
+ cached?.status === 404 &&
13922
+ !resolution.accountSearchUsed &&
13923
+ resolution.candidate.companyName) {
13924
+ try {
13925
+ const fallback = await resolveCliImportCompanyIdentity({
13926
+ ...resolution.candidate,
13927
+ companyId: null,
13928
+ salesNavCompanyUrl: null,
13929
+ linkedinCompanyUrl: null,
13930
+ }, config, companyTimeoutMs, browserRelay);
13931
+ if (fallback.resolvedCompanyId) {
13932
+ fallbackResolutions.push(fallback);
13933
+ }
13934
+ else {
13935
+ pendingProfiles.push(buildCliImportCompanyProfile(fallback, null, {
13936
+ status: 404,
13937
+ error: "No exact LinkedIn company was found by Account Search",
13938
+ }));
13939
+ }
13940
+ }
13941
+ catch (error) {
13942
+ if (error instanceof CliImportCompanyRateLimitError ||
13943
+ error instanceof CliImportCompanySessionError) {
13944
+ throw error;
13945
+ }
13946
+ pendingProfiles.push(buildCliImportCompanyProfile(resolution, null, {
13947
+ status: 500,
13948
+ error: error instanceof Error ? error.message : String(error),
13949
+ }));
13950
+ }
13951
+ if (index < resolutionBatch.length - 1 &&
13952
+ companyDelayMaxMs > 0) {
13953
+ await delay(randomIntegerBetween(companyDelayMinMs, companyDelayMaxMs));
13954
+ }
13955
+ continue;
13956
+ }
13908
13957
  pendingProfiles.push(buildCliImportCompanyProfile(resolution, cached?.detail ?? null, {
13909
13958
  status: cached?.status ?? 500,
13910
13959
  error: cached?.error ?? "Sales Navigator returned no company detail",
13911
13960
  }));
13912
13961
  }
13913
13962
  await flushCompanyProfiles();
13963
+ if (fallbackResolutions.length > 0) {
13964
+ await enrichResolvedCompanies(fallbackResolutions);
13965
+ }
13914
13966
  if (offset + resolutionBatchSize < resolutions.length &&
13915
13967
  companyDelayMaxMs > 0) {
13916
13968
  await delay(randomIntegerBetween(companyDelayMinMs, companyDelayMaxMs));
@@ -13922,6 +13974,10 @@ async function runSalesNavigatorImportEnrichmentCommand(options) {
13922
13974
  await enrichResolvedCompanies(knownResolutions);
13923
13975
  const knownByAlias = new Map();
13924
13976
  for (const candidate of knownCandidates) {
13977
+ if (!candidate.companyId ||
13978
+ !companyIdsWithDetails.has(candidate.companyId)) {
13979
+ continue;
13980
+ }
13925
13981
  for (const alias of [
13926
13982
  candidate.companyName ?? "",
13927
13983
  aggressivelyCleanLookupCompanyName(candidate.companyName ?? ""),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "salesprompter-cli",
3
- "version": "0.1.51",
3
+ "version": "0.1.53",
4
4
  "description": "Sales workflow CLI for guided lead generation, enrichment, scoring, and sync.",
5
5
  "author": "Daniel Sinewe <hello@danielsinewe.com>",
6
6
  "type": "module",