@coldiq/mcp 0.2.4 → 0.2.6

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.
@@ -7,12 +7,12 @@ export const findSignalsDescription = 'Retrieve sales intelligence signals — f
7
7
  'Company-targeted (funding | acquisition | hiring | job_change | intent): accepts companies/domains/industries/countries/since filters. ' +
8
8
  'intent REQUIRES at least one of companies or domains. ' +
9
9
  'Feed-style (news | startup_post): country and since only — does NOT filter by company. Passing companies/domains for these types is rejected. ' +
10
- 'hiring returns aggregated company-level hiring activity (e.g. "X is rapidly expanding") — for individual job postings use search_jobs instead.';
10
+ 'hiring returns individual job postings with company context (title, location, descriptionText, company industries) — for richer job-board queries with description/seniority/easy-apply filters use search_jobs instead.';
11
11
  export const findSignalsSchema = {
12
12
  signal_type: z
13
13
  .enum(['funding', 'acquisition', 'hiring', 'job_change', 'news', 'intent', 'startup_post'])
14
14
  .describe('Signal type to retrieve. ' +
15
- 'Company-targeted: "funding" (fundraising rounds), "acquisition" (M&A), "hiring" (company hiring surge not individual postings), ' +
15
+ 'Company-targeted: "funding" (fundraising rounds), "acquisition" (M&A), "hiring" (individual job postings indexed by Signalbase, with company context), ' +
16
16
  '"job_change" (people who recently changed roles), "intent" (companies showing buying intent). ' +
17
17
  'Feed-style (country/date filter only — company filter not supported): "news" (company news events), "startup_post" (Product Hunt, Hacker News, etc.)'),
18
18
  companies: z
@@ -30,7 +30,7 @@ export const findSignalsSchema = {
30
30
  industries: z
31
31
  .array(z.string())
32
32
  .optional()
33
- .describe('Industry names to filter by (e.g. ["Software", "SaaS"]). Only used by company-targeted signal types.'),
33
+ .describe('Industry names to filter by (e.g. ["Software", "SaaS"]). Forwarded to upstream for funding and acquisition. For hiring, filtered client-side against each row\'s `industries` field (case-insensitive substring match). Ignored for job_change, intent, news, startup_post (those signal types have no industry data to filter on).'),
34
34
  countries: z
35
35
  .array(z.string())
36
36
  .optional()
@@ -84,6 +84,30 @@ export async function findSignalsHandler(input) {
84
84
  typed.data.data = typed.data.data.slice(0, limit);
85
85
  }
86
86
  }
87
+ // Signalbase /hiring-signals does not accept an industry filter upstream, so the
88
+ // `industries` param would otherwise be silently dropped. Filter client-side:
89
+ // each hiring row carries an `industries` string (e.g. "Law Practice and Legal
90
+ // Services") which we substring-match against the user-supplied list.
91
+ if (restInput.signal_type === 'hiring' && Array.isArray(restInput.industries) && restInput.industries.length > 0) {
92
+ const wanted = restInput.industries
93
+ .map((s) => (typeof s === 'string' ? s.toLowerCase() : ''))
94
+ .filter((s) => s.length > 0);
95
+ if (wanted.length > 0) {
96
+ const typed = result;
97
+ const rows = typed.data?.data;
98
+ if (Array.isArray(rows)) {
99
+ typed.data.data = rows.filter((row) => {
100
+ if (!row || typeof row !== 'object')
101
+ return false;
102
+ const industriesField = row.industries;
103
+ if (typeof industriesField !== 'string' || industriesField.length === 0)
104
+ return false;
105
+ const haystack = industriesField.toLowerCase();
106
+ return wanted.some((needle) => haystack.includes(needle));
107
+ });
108
+ }
109
+ }
110
+ }
87
111
  return { content: [{ type: 'text', text: JSON.stringify(result) }] };
88
112
  }
89
113
  //# sourceMappingURL=find-signals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"find-signals.js","sourceRoot":"","sources":["../../src/tools/find-signals.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"find-signals.js","sourceRoot":"","sources":["../../src/tools/find-signals.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  export declare const verifyEmailName = "verify_email";
3
- export declare const verifyEmailDescription = "Check whether an email address is valid and deliverable. Returns verification status (valid, invalid, catch-all, unknown). Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider \u2014 pass use_providers only if you need a specific tool.";
3
+ export declare const verifyEmailDescription = "Check whether an email address is valid and deliverable. Returns a normalized `status` field \u2014 one of \"valid\", \"invalid\", \"catch_all\", \"risky\", \"disposable\", \"unknown\" \u2014 alongside the raw provider response. Findymail (the default) only distinguishes valid vs invalid; richer status values come from providers like icypeas, instantly, or linkupapi. Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider \u2014 pass use_providers only if you need a specific tool.";
4
4
  export declare const verifyEmailSchema: {
5
5
  email: z.ZodString;
6
6
  use_providers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
7
  };
8
+ export declare function addNormalizedStatus(data: unknown, providerId: string): unknown;
8
9
  export declare function verifyEmailHandler(input: Record<string, unknown>): Promise<{
9
10
  content: {
10
11
  type: "text";
@@ -1 +1 @@
1
- {"version":3,"file":"verify-email.d.ts","sourceRoot":"","sources":["../../src/tools/verify-email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,eAAe,iBAAiB,CAAA;AAE7C,eAAO,MAAM,sBAAsB,+RACsP,CAAA;AAEzR,eAAO,MAAM,iBAAiB;;;CAG7B,CAAA;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAWtE"}
1
+ {"version":3,"file":"verify-email.d.ts","sourceRoot":"","sources":["../../src/tools/verify-email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,eAAO,MAAM,eAAe,iBAAiB,CAAA;AAE7C,eAAO,MAAM,sBAAsB,shBACud,CAAA;AAE1f,eAAO,MAAM,iBAAiB;;;CAG7B,CAAA;AA8BD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAiC9E;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;;GAYtE"}
@@ -2,11 +2,66 @@ import { z } from 'zod';
2
2
  import { executeWithFallback, isExecutionError } from '../executor.js';
3
3
  import { resolvePreferredProviders, getProvidersForCapability } from '../utils/provider-resolver.js';
4
4
  export const verifyEmailName = 'verify_email';
5
- export const verifyEmailDescription = 'Check whether an email address is valid and deliverable. Returns verification status (valid, invalid, catch-all, unknown). Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider — pass use_providers only if you need a specific tool.';
5
+ export const verifyEmailDescription = 'Check whether an email address is valid and deliverable. Returns a normalized `status` field — one of "valid", "invalid", "catch_all", "risky", "disposable", "unknown" — alongside the raw provider response. Findymail (the default) only distinguishes valid vs invalid; richer status values come from providers like icypeas, instantly, or linkupapi. Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider — pass use_providers only if you need a specific tool.';
6
6
  export const verifyEmailSchema = {
7
7
  email: z.string().email().describe('Email address to verify'),
8
8
  use_providers: z.array(z.string()).optional().describe(`Optional ordered list of providers to use. Leave empty to let ColdIQ automatically pick the best tool for your inputs — recommended for most use cases. Available providers: ${getProvidersForCapability('verify_email').join(', ')}. Provider names are matched fuzzily, so minor typos are tolerated.`),
9
9
  };
10
+ const STATUS_ALIASES = {
11
+ valid: 'valid',
12
+ deliverable: 'valid',
13
+ ok: 'valid',
14
+ invalid: 'invalid',
15
+ undeliverable: 'invalid',
16
+ bounce: 'invalid',
17
+ bounced: 'invalid',
18
+ catch_all: 'catch_all',
19
+ catchall: 'catch_all',
20
+ 'catch-all': 'catch_all',
21
+ accept_all: 'catch_all',
22
+ acceptall: 'catch_all',
23
+ risky: 'risky',
24
+ disposable: 'disposable',
25
+ unknown: 'unknown',
26
+ };
27
+ function normalizeStatus(raw) {
28
+ if (typeof raw !== 'string' || raw.length === 0)
29
+ return 'unknown';
30
+ return STATUS_ALIASES[raw.toLowerCase()] ?? 'unknown';
31
+ }
32
+ // Provider responses are heterogeneous. We surface a single `status` field on the
33
+ // payload while leaving the raw upstream fields untouched so callers that already
34
+ // depend on them keep working.
35
+ export function addNormalizedStatus(data, providerId) {
36
+ if (!data || typeof data !== 'object' || Array.isArray(data))
37
+ return data;
38
+ const d = { ...data };
39
+ // If the response already carries a status string, normalize it and stop.
40
+ if (typeof d.status === 'string') {
41
+ d.status = normalizeStatus(d.status);
42
+ return d;
43
+ }
44
+ if (providerId === 'findymail') {
45
+ // Findymail's /api/verify returns { email, verified: boolean, provider } — no
46
+ // catch_all/unknown distinction. Map the boolean to valid/invalid only.
47
+ d.status = d.verified === true ? 'valid' : 'invalid';
48
+ return d;
49
+ }
50
+ if (providerId === 'icypeas') {
51
+ const item = d.item;
52
+ d.status = normalizeStatus(item?.status);
53
+ return d;
54
+ }
55
+ if (providerId === 'linkupapi-validate') {
56
+ // LinkupAPI shapes vary; accept any of the common signal fields.
57
+ const truthy = d.verified === true || d.valid === true || d.result === 'valid';
58
+ d.status = truthy ? 'valid' : normalizeStatus(d.result ?? d.valid ?? d.verified);
59
+ return d;
60
+ }
61
+ // Unknown provider — leave the original payload alone and flag the gap.
62
+ d.status = 'unknown';
63
+ return d;
64
+ }
10
65
  export async function verifyEmailHandler(input) {
11
66
  const { use_providers: rawUseProviders, ...restInput } = input;
12
67
  const resolved = resolvePreferredProviders('verify_email', restInput, rawUseProviders);
@@ -17,6 +72,7 @@ export async function verifyEmailHandler(input) {
17
72
  if (isExecutionError(result)) {
18
73
  return { content: [{ type: 'text', text: JSON.stringify(result) }], isError: true };
19
74
  }
75
+ result.data = addNormalizedStatus(result.data, result._meta.provider);
20
76
  return { content: [{ type: 'text', text: JSON.stringify(result) }] };
21
77
  }
22
78
  //# sourceMappingURL=verify-email.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verify-email.js","sourceRoot":"","sources":["../../src/tools/verify-email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAA;AAEpG,MAAM,CAAC,MAAM,eAAe,GAAG,cAAc,CAAA;AAE7C,MAAM,CAAC,MAAM,sBAAsB,GACjC,uRAAuR,CAAA;AAEzR,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;IAC7D,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gLAAgL,yBAAyB,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,qEAAqE,CAAC;CAClW,CAAA;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAA8B;IACrE,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,GAAG,KAAK,CAAA;IAC9D,MAAM,QAAQ,GAAG,yBAAyB,CAAC,cAAc,EAAE,SAAS,EAAE,eAAe,CAAC,CAAA;IACtF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IACtG,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,cAAc,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACzI,IAAI,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;IAC9F,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAA;AAC/E,CAAC"}
1
+ {"version":3,"file":"verify-email.js","sourceRoot":"","sources":["../../src/tools/verify-email.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"compact-people.d.ts","sourceRoot":"","sources":["../../src/utils/compact-people.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AA6CD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,CAgC/E;AAyCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CA6HrE;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,IAAI,CAAA;CAChB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CA2ChF"}
1
+ {"version":3,"file":"compact-people.d.ts","sourceRoot":"","sources":["../../src/utils/compact-people.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AA6CD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,CAgC/E;AA6CD,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,IAAI,CA8HrE;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,EAAE,IAAI,CAAA;CAChB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CA2ChF"}
@@ -94,6 +94,7 @@ export function extractPeopleArray(data, providerId) {
94
94
  // Providers nest person fields at different depths:
95
95
  // - LeadsFactory wraps in `{ contact: {...person}, company: {...}, persona_index, ... }`
96
96
  // - AI-Ark wraps in `{ id, profile: {...person} }`
97
+ // - Prospeo wraps in `{ person: {...person fields including current_job_title}, ... }`
97
98
  // - Apollo / PDL / FullEnrich keep person fields at the top level
98
99
  // Merging the nested objects into the outer scope lets the candidate-path resolver
99
100
  // find person fields regardless of provider. The sibling `company` on LeadsFactory
@@ -109,6 +110,9 @@ function unwrapRecord(record) {
109
110
  if (r.contact && typeof r.contact === 'object' && !Array.isArray(r.contact)) {
110
111
  Object.assign(merged, r.contact);
111
112
  }
113
+ if (r.person && typeof r.person === 'object' && !Array.isArray(r.person)) {
114
+ Object.assign(merged, r.person);
115
+ }
112
116
  return merged;
113
117
  }
114
118
  // Confirm a candidate value really points at LinkedIn before surfacing it as
@@ -152,6 +156,7 @@ export function normalizePerson(record) {
152
156
  'title',
153
157
  'job_title',
154
158
  'jobTitle',
159
+ 'current_job_title',
155
160
  'position',
156
161
  'current_position.title',
157
162
  'current_position',
@@ -1 +1 @@
1
- {"version":3,"file":"compact-people.js","sourceRoot":"","sources":["../../src/utils/compact-people.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,4EAA4E;AAC5E,qFAAqF;AACrF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAChF,oDAAoD;AAiBpD,SAAS,OAAO,CAAC,GAAY,EAAE,IAAY;IACzC,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,GAAG,GAAY,GAAG,CAAA;IACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,IAAI,IAAI;YAAE,OAAO,SAAS,CAAA;QACjC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;YACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAA;YAC5C,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAChB,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,GAAG,GAAI,GAA+B,CAAC,IAAI,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,IAAI,CAAC,GAAY,EAAE,KAAe;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9D,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3C,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,GAAc;IACjC,MAAM,GAAG,GAAc,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;;YAClD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,8EAA8E;AAC9E,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,IAAa,EAAE,UAAkB;IAClE,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAA;IACvC,MAAM,CAAC,GAAG,IAA+B,CAAA;IAEzC,8EAA8E;IAC9E,+DAA+D;IAC/D,IAAI,UAAU,KAAK,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzE,MAAM,GAAG,GAAc,EAAE,CAAA;QACzB,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,kBAAoD,EAAE,CAAC;YAC3E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAA;QACjE,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,4CAA4C;IAC5C,IAAI,UAAU,KAAK,2BAA2B,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAA;QACpB,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAI,KAAiC,CAAC,QAAQ,CAAA;YAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAA;QAC9C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;QAC5F,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAChB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,oDAAoD;AACpD,2FAA2F;AAC3F,qDAAqD;AACrD,oEAAoE;AACpE,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,SAAS,YAAY,CAAC,MAAe;IACnC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/E,MAAM,CAAC,GAAG,MAAiC,CAAA;IAC3C,MAAM,MAAM,GAA4B,EAAE,GAAG,CAAC,EAAE,CAAA;IAChD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAkC,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAkC,CAAC,CAAA;IAC7D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,6EAA6E;AAC7E,gFAAgF;AAChF,4EAA4E;AAC5E,iFAAiF;AACjF,iDAAiD;AACjD,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACzD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,GAAY,EAAE,KAAe;IACjD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACzB,IAAI,aAAa,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnB,MAAM,GAAG,GAAkB,EAAE,CAAA;IAE7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACpF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvF,IAAI,QAAQ;QAAE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;IACtC,IAAI,SAAS;QAAE,GAAG,CAAC,UAAU,GAAG,SAAS,CAAA;IACzC,IAAI,QAAQ;QAAE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;IACtC,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,SAAS,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7B,0BAA0B;QAC1B,OAAO;QACP,WAAW;QACX,UAAU;QACV,UAAU;QACV,wBAAwB;QACxB,kBAAkB;QAClB,UAAU;KACX,CAAC,CAAC,CAAA;IACH,IAAI,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAE5B,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,EAAE;QAC3B,8BAA8B;QAC9B,WAAW;QACX,oBAAoB;QACpB,WAAW,EAAG,SAAS;QACvB,OAAO;KACR,CAAC,CAAA;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAA;IACxC,IAAI,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;IAExC,4EAA4E;IAC5E,mFAAmF;IACnF,uEAAuE;IACvE,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,EAAE;QAC/B,cAAc;QACd,aAAa;QACb,0CAA0C;QAC1C,8BAA8B;QAC9B,aAAa;QACb,UAAU;QACV,KAAK;KACN,CAAC,CAAA;IACF,IAAI,QAAQ;QAAE,GAAG,CAAC,YAAY,GAAG,QAAQ,CAAA;IAEzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7B,OAAO;QACP,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,UAAU;QACV,eAAe;QACf,kBAAkB;KACnB,CAAC,CAAC,CAAA;IACH,IAAI,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAE5B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC/B,kBAAkB;QAClB,SAAS;QACT,kBAAkB;QAClB,8BAA8B;KAC/B,CAAC,CAAC,CAAA;IACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC5B,eAAe;QACf,MAAM;QACN,mBAAmB;QACnB,+BAA+B;KAChC,CAAC,CAAC,CAAA;IACH,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnE,IAAI,gBAAgB;QAAE,GAAG,CAAC,QAAQ,GAAG,gBAAgB,CAAA;IAErD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACnC,iCAAiC;QACjC,mBAAmB;QACnB,cAAc;QACd,kBAAkB;QAClB,sBAAsB;QACtB,aAAa;KACd,CAAC,CAAC,CAAA;IACH,IAAI,WAAW;QAAE,GAAG,CAAC,YAAY,GAAG,WAAW,CAAA;IAE/C,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACrC,mCAAmC;QACnC,6BAA6B;QAC7B,0BAA0B;QAC1B,gBAAgB;QAChB,iBAAiB;QACjB,qBAAqB;KACtB,CAAC,CAAC,CAAA;IACH,IAAI,aAAa;QAAE,GAAG,CAAC,cAAc,GAAG,aAAa,CAAA;IAErD,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACvC,qEAAqE;QACrE,yDAAyD;QACzD,yCAAyC;QACzC,2BAA2B;QAC3B,sBAAsB;QACtB,0BAA0B;KAC3B,CAAC,CAAC,CAAA;IACH,IAAI,eAAe;QAAE,GAAG,CAAC,oBAAoB,GAAG,eAAe,CAAA;IAE/D,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,EAAE;QAC3B,sCAAsC;QACtC,4CAA4C;QAC5C,sCAAsC;QACtC,4BAA4B;QAC5B,mBAAmB;QACnB,cAAc;QACd,kBAAkB;QAClB,4BAA4B;KAC7B,CAAC,CAAA;IACF,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACtG,GAAG,CAAC,iBAAiB,GAAG,YAAY,CAAA;IACtC,CAAC;IAED,oDAAoD;IACpD,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9C,OAAO,GAAG,CAAA;AACZ,CAAC;AASD,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,UAAkB;IAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACpD,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC5B,IAAI,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,eAAmC,CAAA;IACvC,IAAI,aAAa,GAAoB,EAAE,CAAA;IACvC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,EAAE,GAAI,IAAgC,CAAC,QAAQ,CAAA;QACrD,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,eAAe,GAAG,QAAQ,CAAE,EAA8B,CAAC,QAAQ,CAAC,CAAA;YACpE,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,EAAE,eAAe,IAAI,EAAE,CAAC,CAAA;YAC3D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;gBAC5B,IAAI,CAAC;oBAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,IAAI,KAAyB,CAAA;IAC7B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAI,IAAgC,CAAC,QAAQ,CAAA;QACvD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,CAAC,GAAI,IAAgC,CAAC,KAAK,CAAA;YACjD,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,KAAK,GAAG,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAmB,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,aAAa,CAAC,EAAE,CAAA;IACnE,IAAI,KAAK,KAAK,SAAS;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAC1C,IAAI,eAAe,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,iBAAiB,GAAG,eAAe,CAAA;IACxF,+EAA+E;IAC/E,gFAAgF;IAChF,gFAAgF;IAChF,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACvD,IAAgC,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QACxD,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
1
+ {"version":3,"file":"compact-people.js","sourceRoot":"","sources":["../../src/utils/compact-people.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,EAAE;AACF,4EAA4E;AAC5E,qFAAqF;AACrF,kFAAkF;AAClF,mFAAmF;AACnF,gFAAgF;AAChF,oDAAoD;AAiBpD,SAAS,OAAO,CAAC,GAAY,EAAE,IAAY;IACzC,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,SAAS,CAAA;IACjC,IAAI,GAAG,GAAY,GAAG,CAAA;IACtB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,GAAG,IAAI,IAAI;YAAE,OAAO,SAAS,CAAA;QACjC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;YACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAA;YAC5C,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAChB,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACnC,GAAG,GAAI,GAA+B,CAAC,IAAI,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,IAAI,CAAC,GAAY,EAAE,KAAe;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACzB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO,CAAC,CAAA;IACzD,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC9D,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAC3C,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,GAAc;IACjC,MAAM,GAAG,GAAc,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAA;;YAClD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,8EAA8E;AAC9E,kEAAkE;AAClE,MAAM,UAAU,kBAAkB,CAAC,IAAa,EAAE,UAAkB;IAClE,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,EAAE,CAAA;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACpC,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAA;IACvC,MAAM,CAAC,GAAG,IAA+B,CAAA;IAEzC,8EAA8E;IAC9E,+DAA+D;IAC/D,IAAI,UAAU,KAAK,cAAc,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACzE,MAAM,GAAG,GAAc,EAAE,CAAA;QACzB,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,kBAAoD,EAAE,CAAC;YAC3E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAA;QACjE,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED,4CAA4C;IAC5C,IAAI,UAAU,KAAK,2BAA2B,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,CAAA;QACpB,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAI,KAAiC,CAAC,QAAQ,CAAA;YAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBAAE,OAAO,QAAQ,CAAA;QAC9C,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;QAC5F,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAChB,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,oDAAoD;AACpD,2FAA2F;AAC3F,qDAAqD;AACrD,yFAAyF;AACzF,oEAAoE;AACpE,mFAAmF;AACnF,mFAAmF;AACnF,mFAAmF;AACnF,SAAS,YAAY,CAAC,MAAe;IACnC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAA;IAC/E,MAAM,CAAC,GAAG,MAAiC,CAAA;IAC3C,MAAM,MAAM,GAA4B,EAAE,GAAG,CAAC,EAAE,CAAA;IAChD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAkC,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5E,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAkC,CAAC,CAAA;IAC7D,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,MAAiC,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,6EAA6E;AAC7E,gFAAgF;AAChF,4EAA4E;AAC5E,iFAAiF;AACjF,iDAAiD;AACjD,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACzD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;IAC7B,OAAO,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA;AACxC,CAAC;AAED,SAAS,YAAY,CAAC,GAAY,EAAE,KAAe;IACjD,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACzB,IAAI,aAAa,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAA;IAChC,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,MAAM,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IAC9B,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IAEnB,MAAM,GAAG,GAAkB,EAAE,CAAA;IAE7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAA;IACpF,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IACvF,IAAI,QAAQ;QAAE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;IACtC,IAAI,SAAS;QAAE,GAAG,CAAC,UAAU,GAAG,SAAS,CAAA;IACzC,IAAI,QAAQ;QAAE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAA;IACtC,IAAI,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,CAAC;QAC9C,GAAG,CAAC,SAAS,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACjE,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7B,0BAA0B;QAC1B,OAAO;QACP,WAAW;QACX,UAAU;QACV,mBAAmB;QACnB,UAAU;QACV,wBAAwB;QACxB,kBAAkB;QAClB,UAAU;KACX,CAAC,CAAC,CAAA;IACH,IAAI,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAE5B,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,EAAE;QAC3B,8BAA8B;QAC9B,WAAW;QACX,oBAAoB;QACpB,WAAW,EAAG,SAAS;QACvB,OAAO;KACR,CAAC,CAAA;IACF,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAA;IACxC,IAAI,SAAS;QAAE,GAAG,CAAC,SAAS,GAAG,SAAS,CAAA;IAExC,4EAA4E;IAC5E,mFAAmF;IACnF,uEAAuE;IACvE,MAAM,QAAQ,GAAG,YAAY,CAAC,CAAC,EAAE;QAC/B,cAAc;QACd,aAAa;QACb,0CAA0C;QAC1C,8BAA8B;QAC9B,aAAa;QACb,UAAU;QACV,KAAK;KACN,CAAC,CAAA;IACF,IAAI,QAAQ;QAAE,GAAG,CAAC,YAAY,GAAG,QAAQ,CAAA;IAEzC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC7B,OAAO;QACP,YAAY;QACZ,gBAAgB;QAChB,YAAY;QACZ,UAAU;QACV,eAAe;QACf,kBAAkB;KACnB,CAAC,CAAC,CAAA;IACH,IAAI,KAAK;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAE5B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC/B,kBAAkB;QAClB,SAAS;QACT,kBAAkB;QAClB,8BAA8B;KAC/B,CAAC,CAAC,CAAA;IACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QAC5B,eAAe;QACf,MAAM;QACN,mBAAmB;QACnB,+BAA+B;KAChC,CAAC,CAAC,CAAA;IACH,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnE,IAAI,gBAAgB;QAAE,GAAG,CAAC,QAAQ,GAAG,gBAAgB,CAAA;IAErD,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACnC,iCAAiC;QACjC,mBAAmB;QACnB,cAAc;QACd,kBAAkB;QAClB,sBAAsB;QACtB,aAAa;KACd,CAAC,CAAC,CAAA;IACH,IAAI,WAAW;QAAE,GAAG,CAAC,YAAY,GAAG,WAAW,CAAA;IAE/C,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACrC,mCAAmC;QACnC,6BAA6B;QAC7B,0BAA0B;QAC1B,gBAAgB;QAChB,iBAAiB;QACjB,qBAAqB;KACtB,CAAC,CAAC,CAAA;IACH,IAAI,aAAa;QAAE,GAAG,CAAC,cAAc,GAAG,aAAa,CAAA;IAErD,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE;QACvC,qEAAqE;QACrE,yDAAyD;QACzD,yCAAyC;QACzC,2BAA2B;QAC3B,sBAAsB;QACtB,0BAA0B;KAC3B,CAAC,CAAC,CAAA;IACH,IAAI,eAAe;QAAE,GAAG,CAAC,oBAAoB,GAAG,eAAe,CAAA;IAE/D,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC,EAAE;QAC3B,sCAAsC;QACtC,4CAA4C;QAC5C,sCAAsC;QACtC,4BAA4B;QAC5B,mBAAmB;QACnB,cAAc;QACd,kBAAkB;QAClB,4BAA4B;KAC7B,CAAC,CAAA;IACF,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,CAAC,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACtG,GAAG,CAAC,iBAAiB,GAAG,YAAY,CAAA;IACtC,CAAC;IAED,oDAAoD;IACpD,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9C,OAAO,GAAG,CAAA;AACZ,CAAC;AASD,MAAM,UAAU,cAAc,CAAC,IAAa,EAAE,UAAkB;IAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IACpD,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC5B,IAAI,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,eAAmC,CAAA;IACvC,IAAI,aAAa,GAAoB,EAAE,CAAA;IACvC,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,EAAE,GAAI,IAAgC,CAAC,QAAQ,CAAA;QACrD,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YACjC,eAAe,GAAG,QAAQ,CAAE,EAA8B,CAAC,QAAQ,CAAC,CAAA;YACpE,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,EAAE,eAAe,IAAI,EAAE,CAAC,CAAA;YAC3D,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;gBAC5B,IAAI,CAAC;oBAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,+EAA+E;IAC/E,IAAI,KAAyB,CAAA;IAC7B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAI,IAAgC,CAAC,QAAQ,CAAA;QACvD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,CAAC,GAAI,IAAgC,CAAC,KAAK,CAAA;YACjD,IAAI,OAAO,CAAC,KAAK,QAAQ;gBAAE,KAAK,GAAG,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAmB,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,aAAa,CAAC,EAAE,CAAA;IACnE,IAAI,KAAK,KAAK,SAAS;QAAE,GAAG,CAAC,KAAK,GAAG,KAAK,CAAA;IAC1C,IAAI,eAAe,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,iBAAiB,GAAG,eAAe,CAAA;IACxF,+EAA+E;IAC/E,gFAAgF;IAChF,gFAAgF;IAChF,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACvD,IAAgC,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QACxD,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAA;IACrB,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coldiq/mcp",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/registry.ts CHANGED
@@ -1305,7 +1305,7 @@ const findPeopleProviders: ProviderEntry[] = [
1305
1305
  }),
1306
1306
  hasResult: (data) => {
1307
1307
  const d = data as Record<string, unknown>
1308
- return isNonEmptyArray(d.data)
1308
+ return isNonEmptyArray(d.results)
1309
1309
  },
1310
1310
  },
1311
1311
  {
@@ -2909,8 +2909,22 @@ const enrichPersonProviders: ProviderEntry[] = [
2909
2909
  },
2910
2910
  }),
2911
2911
  hasResult: (data) => {
2912
+ // Apollo /people/match always returns { person: {...} } even on weak matches
2913
+ // where every useful field is null (just echoing back the input first/last name).
2914
+ // Treat as a real match only when at least one enrichment field is populated,
2915
+ // so the executor falls through to the next provider instead of returning a
2916
+ // silent empty record.
2912
2917
  const d = data as Record<string, unknown>
2913
- return !!d.person && typeof d.person === 'object'
2918
+ const person = d.person as Record<string, unknown> | undefined
2919
+ if (!person || typeof person !== 'object') return false
2920
+ return Boolean(
2921
+ person.linkedin_url ||
2922
+ person.email ||
2923
+ person.title ||
2924
+ person.headline ||
2925
+ person.organization_id ||
2926
+ isNonEmptyArray(person.employment_history),
2927
+ )
2914
2928
  },
2915
2929
  },
2916
2930
  {
@@ -10,14 +10,14 @@ export const findSignalsDescription =
10
10
  'Company-targeted (funding | acquisition | hiring | job_change | intent): accepts companies/domains/industries/countries/since filters. ' +
11
11
  'intent REQUIRES at least one of companies or domains. ' +
12
12
  'Feed-style (news | startup_post): country and since only — does NOT filter by company. Passing companies/domains for these types is rejected. ' +
13
- 'hiring returns aggregated company-level hiring activity (e.g. "X is rapidly expanding") — for individual job postings use search_jobs instead.'
13
+ 'hiring returns individual job postings with company context (title, location, descriptionText, company industries) — for richer job-board queries with description/seniority/easy-apply filters use search_jobs instead.'
14
14
 
15
15
  export const findSignalsSchema = {
16
16
  signal_type: z
17
17
  .enum(['funding', 'acquisition', 'hiring', 'job_change', 'news', 'intent', 'startup_post'])
18
18
  .describe(
19
19
  'Signal type to retrieve. ' +
20
- 'Company-targeted: "funding" (fundraising rounds), "acquisition" (M&A), "hiring" (company hiring surge not individual postings), ' +
20
+ 'Company-targeted: "funding" (fundraising rounds), "acquisition" (M&A), "hiring" (individual job postings indexed by Signalbase, with company context), ' +
21
21
  '"job_change" (people who recently changed roles), "intent" (companies showing buying intent). ' +
22
22
  'Feed-style (country/date filter only — company filter not supported): "news" (company news events), "startup_post" (Product Hunt, Hacker News, etc.)'
23
23
  ),
@@ -36,7 +36,7 @@ export const findSignalsSchema = {
36
36
  industries: z
37
37
  .array(z.string())
38
38
  .optional()
39
- .describe('Industry names to filter by (e.g. ["Software", "SaaS"]). Only used by company-targeted signal types.'),
39
+ .describe('Industry names to filter by (e.g. ["Software", "SaaS"]). Forwarded to upstream for funding and acquisition. For hiring, filtered client-side against each row\'s `industries` field (case-insensitive substring match). Ignored for job_change, intent, news, startup_post (those signal types have no industry data to filter on).'),
40
40
  countries: z
41
41
  .array(z.string())
42
42
  .optional()
@@ -97,5 +97,28 @@ export async function findSignalsHandler(input: Record<string, unknown>) {
97
97
  }
98
98
  }
99
99
 
100
+ // Signalbase /hiring-signals does not accept an industry filter upstream, so the
101
+ // `industries` param would otherwise be silently dropped. Filter client-side:
102
+ // each hiring row carries an `industries` string (e.g. "Law Practice and Legal
103
+ // Services") which we substring-match against the user-supplied list.
104
+ if (restInput.signal_type === 'hiring' && Array.isArray(restInput.industries) && restInput.industries.length > 0) {
105
+ const wanted = (restInput.industries as unknown[])
106
+ .map((s) => (typeof s === 'string' ? s.toLowerCase() : ''))
107
+ .filter((s) => s.length > 0)
108
+ if (wanted.length > 0) {
109
+ const typed = result as { data?: { data?: unknown[] } }
110
+ const rows = typed.data?.data
111
+ if (Array.isArray(rows)) {
112
+ typed.data!.data = rows.filter((row) => {
113
+ if (!row || typeof row !== 'object') return false
114
+ const industriesField = (row as Record<string, unknown>).industries
115
+ if (typeof industriesField !== 'string' || industriesField.length === 0) return false
116
+ const haystack = industriesField.toLowerCase()
117
+ return wanted.some((needle) => haystack.includes(needle))
118
+ })
119
+ }
120
+ }
121
+ }
122
+
100
123
  return { content: [{ type: 'text' as const, text: JSON.stringify(result) }] }
101
124
  }
@@ -5,13 +5,76 @@ import { resolvePreferredProviders, getProvidersForCapability } from '../utils/p
5
5
  export const verifyEmailName = 'verify_email'
6
6
 
7
7
  export const verifyEmailDescription =
8
- 'Check whether an email address is valid and deliverable. Returns verification status (valid, invalid, catch-all, unknown). Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider — pass use_providers only if you need a specific tool.'
8
+ 'Check whether an email address is valid and deliverable. Returns a normalized `status` field — one of "valid", "invalid", "catch_all", "risky", "disposable", "unknown" — alongside the raw provider response. Findymail (the default) only distinguishes valid vs invalid; richer status values come from providers like icypeas, instantly, or linkupapi. Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider — pass use_providers only if you need a specific tool.'
9
9
 
10
10
  export const verifyEmailSchema = {
11
11
  email: z.string().email().describe('Email address to verify'),
12
12
  use_providers: z.array(z.string()).optional().describe(`Optional ordered list of providers to use. Leave empty to let ColdIQ automatically pick the best tool for your inputs — recommended for most use cases. Available providers: ${getProvidersForCapability('verify_email').join(', ')}. Provider names are matched fuzzily, so minor typos are tolerated.`),
13
13
  }
14
14
 
15
+ type NormalizedStatus = 'valid' | 'invalid' | 'catch_all' | 'risky' | 'disposable' | 'unknown'
16
+
17
+ const STATUS_ALIASES: Record<string, NormalizedStatus> = {
18
+ valid: 'valid',
19
+ deliverable: 'valid',
20
+ ok: 'valid',
21
+ invalid: 'invalid',
22
+ undeliverable: 'invalid',
23
+ bounce: 'invalid',
24
+ bounced: 'invalid',
25
+ catch_all: 'catch_all',
26
+ catchall: 'catch_all',
27
+ 'catch-all': 'catch_all',
28
+ accept_all: 'catch_all',
29
+ acceptall: 'catch_all',
30
+ risky: 'risky',
31
+ disposable: 'disposable',
32
+ unknown: 'unknown',
33
+ }
34
+
35
+ function normalizeStatus(raw: unknown): NormalizedStatus {
36
+ if (typeof raw !== 'string' || raw.length === 0) return 'unknown'
37
+ return STATUS_ALIASES[raw.toLowerCase()] ?? 'unknown'
38
+ }
39
+
40
+ // Provider responses are heterogeneous. We surface a single `status` field on the
41
+ // payload while leaving the raw upstream fields untouched so callers that already
42
+ // depend on them keep working.
43
+ export function addNormalizedStatus(data: unknown, providerId: string): unknown {
44
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return data
45
+ const d = { ...(data as Record<string, unknown>) }
46
+
47
+ // If the response already carries a status string, normalize it and stop.
48
+ if (typeof d.status === 'string') {
49
+ d.status = normalizeStatus(d.status)
50
+ return d
51
+ }
52
+
53
+ if (providerId === 'findymail') {
54
+ // Findymail's /api/verify returns { email, verified: boolean, provider } — no
55
+ // catch_all/unknown distinction. Map the boolean to valid/invalid only.
56
+ d.status = d.verified === true ? 'valid' : 'invalid'
57
+ return d
58
+ }
59
+
60
+ if (providerId === 'icypeas') {
61
+ const item = d.item as Record<string, unknown> | undefined
62
+ d.status = normalizeStatus(item?.status)
63
+ return d
64
+ }
65
+
66
+ if (providerId === 'linkupapi-validate') {
67
+ // LinkupAPI shapes vary; accept any of the common signal fields.
68
+ const truthy = d.verified === true || d.valid === true || d.result === 'valid'
69
+ d.status = truthy ? 'valid' : normalizeStatus(d.result ?? d.valid ?? d.verified)
70
+ return d
71
+ }
72
+
73
+ // Unknown provider — leave the original payload alone and flag the gap.
74
+ d.status = 'unknown'
75
+ return d
76
+ }
77
+
15
78
  export async function verifyEmailHandler(input: Record<string, unknown>) {
16
79
  const { use_providers: rawUseProviders, ...restInput } = input
17
80
  const resolved = resolvePreferredProviders('verify_email', restInput, rawUseProviders)
@@ -22,5 +85,6 @@ export async function verifyEmailHandler(input: Record<string, unknown>) {
22
85
  if (isExecutionError(result)) {
23
86
  return { content: [{ type: 'text' as const, text: JSON.stringify(result) }], isError: true }
24
87
  }
88
+ result.data = addNormalizedStatus(result.data, result._meta.provider)
25
89
  return { content: [{ type: 'text' as const, text: JSON.stringify(result) }] }
26
90
  }
@@ -102,6 +102,7 @@ export function extractPeopleArray(data: unknown, providerId: string): unknown[]
102
102
  // Providers nest person fields at different depths:
103
103
  // - LeadsFactory wraps in `{ contact: {...person}, company: {...}, persona_index, ... }`
104
104
  // - AI-Ark wraps in `{ id, profile: {...person} }`
105
+ // - Prospeo wraps in `{ person: {...person fields including current_job_title}, ... }`
105
106
  // - Apollo / PDL / FullEnrich keep person fields at the top level
106
107
  // Merging the nested objects into the outer scope lets the candidate-path resolver
107
108
  // find person fields regardless of provider. The sibling `company` on LeadsFactory
@@ -116,6 +117,9 @@ function unwrapRecord(record: unknown): Record<string, unknown> | null {
116
117
  if (r.contact && typeof r.contact === 'object' && !Array.isArray(r.contact)) {
117
118
  Object.assign(merged, r.contact as Record<string, unknown>)
118
119
  }
120
+ if (r.person && typeof r.person === 'object' && !Array.isArray(r.person)) {
121
+ Object.assign(merged, r.person as Record<string, unknown>)
122
+ }
119
123
  return merged
120
124
  }
121
125
 
@@ -159,6 +163,7 @@ export function normalizePerson(record: unknown): CompactPerson | null {
159
163
  'title',
160
164
  'job_title',
161
165
  'jobTitle',
166
+ 'current_job_title',
162
167
  'position',
163
168
  'current_position.title',
164
169
  'current_position',
@@ -92,8 +92,36 @@ describe('apollo-people-match', () => {
92
92
  })
93
93
  })
94
94
 
95
- it('hasResult: true when person object present', () => {
96
- expect(p().hasResult({ person: { name: 'Michel Lieben', id: 'abc' } })).toBe(true)
95
+ it('hasResult: true when person has linkedin_url', () => {
96
+ expect(p().hasResult({ person: { name: 'Michel Lieben', id: 'abc', linkedin_url: 'https://www.linkedin.com/in/michel-lieben' } })).toBe(true)
97
+ })
98
+
99
+ it('hasResult: true when person has email', () => {
100
+ expect(p().hasResult({ person: { name: 'Michel Lieben', email: 'michel@coldiq.com' } })).toBe(true)
101
+ })
102
+
103
+ it('hasResult: true when person has non-empty employment_history', () => {
104
+ expect(p().hasResult({ person: { name: 'Michel Lieben', employment_history: [{ organization_id: 'org_1' }] } })).toBe(true)
105
+ })
106
+
107
+ it('hasResult: false on Apollo silent-empty record (name only, all other fields null)', () => {
108
+ // Apollo /people/match returns 200 with this shape when no real match is found.
109
+ // The executor must fall through to the next provider instead of surfacing junk.
110
+ expect(p().hasResult({
111
+ person: {
112
+ id: '6a0c19edfe0e7300102a02dc',
113
+ first_name: 'Alex',
114
+ last_name: 'Vacca',
115
+ name: 'Alex Vacca',
116
+ linkedin_url: null,
117
+ title: null,
118
+ organization_id: null,
119
+ employment_history: [],
120
+ email: null,
121
+ headline: null,
122
+ seniority: null,
123
+ },
124
+ })).toBe(false)
97
125
  })
98
126
 
99
127
  it('hasResult: false when person is null', () => {
@@ -132,18 +132,22 @@ describe('prospeo-search-person', () => {
132
132
  expect(filters.person_location_search).toBeUndefined()
133
133
  })
134
134
 
135
- it('hasResult: true when data array non-empty', () => {
136
- expect(p().hasResult({ data: [{ name: 'Michel Lieben' }] })).toBe(true)
135
+ it('hasResult: true when results array non-empty', () => {
136
+ expect(p().hasResult({ results: [{ person: { full_name: 'Michel Lieben' } }] })).toBe(true)
137
137
  })
138
138
 
139
- it('hasResult: false when data is empty', () => {
140
- expect(p().hasResult({ data: [] })).toBe(false)
139
+ it('hasResult: false when results is empty', () => {
140
+ expect(p().hasResult({ results: [] })).toBe(false)
141
141
  })
142
142
 
143
143
  it('hasResult: false on empty object', () => {
144
144
  expect(p().hasResult({})).toBe(false)
145
145
  })
146
146
 
147
+ it('hasResult: false when only legacy data field is present (real upstream uses results)', () => {
148
+ expect(p().hasResult({ data: [{ name: 'Stale' }] })).toBe(false)
149
+ })
150
+
147
151
  it('priority is 7', () => {
148
152
  expect(p().priority).toBe(7)
149
153
  })
@@ -108,3 +108,65 @@ describe('find_signals handler — company-targeted types pass through', () => {
108
108
  })
109
109
  }
110
110
  })
111
+
112
+ // ---------------------------------------------------------------------------
113
+ // hiring industries client-side post-filter
114
+ //
115
+ // Signalbase /hiring-signals has no upstream `industry` query param, so the
116
+ // handler filters the result rows by industries instead of silently dropping
117
+ // the filter.
118
+ // ---------------------------------------------------------------------------
119
+
120
+ import { executeWithFallback as mockedExecute } from '../../src/executor.js'
121
+
122
+ describe('find_signals handler — hiring industries post-filter', () => {
123
+ const hiringRows = [
124
+ { id: 'a', title: 'Sales Lead', companyName: 'CreatePay', industries: 'Financial Services' },
125
+ { id: 'b', title: 'Sales Assistant', companyName: 'AstraZeneca', industries: 'Pharmaceutical Manufacturing' },
126
+ { id: 'c', title: 'Account Executive', companyName: 'Monex Europe', industries: 'Financial Services and Foreign Exchange' },
127
+ { id: 'd', title: 'Legal Counsel', companyName: 'Eversheds', industries: 'Law Practice and Legal Services' },
128
+ { id: 'e', title: 'Engineer', companyName: 'NoIndustries', industries: '' },
129
+ ]
130
+
131
+ it('filters rows by case-insensitive industries substring match', async () => {
132
+ vi.mocked(mockedExecute).mockResolvedValueOnce({
133
+ data: { success: true, data: [...hiringRows] },
134
+ _meta: { provider: 'signalbase-hiring', latencyMs: 1 },
135
+ })
136
+ const result = await findSignalsHandler({ signal_type: 'hiring', industries: ['financial services'], limit: 25 })
137
+ const body = JSON.parse(result.content[0].text)
138
+ expect(body.data.data).toHaveLength(2)
139
+ expect(body.data.data.map((r: { id: string }) => r.id)).toEqual(['a', 'c'])
140
+ })
141
+
142
+ it('returns empty array when no row matches any industry', async () => {
143
+ vi.mocked(mockedExecute).mockResolvedValueOnce({
144
+ data: { success: true, data: [...hiringRows] },
145
+ _meta: { provider: 'signalbase-hiring', latencyMs: 1 },
146
+ })
147
+ const result = await findSignalsHandler({ signal_type: 'hiring', industries: ['Aerospace'], limit: 25 })
148
+ const body = JSON.parse(result.content[0].text)
149
+ expect(body.data.data).toEqual([])
150
+ })
151
+
152
+ it('leaves rows untouched when industries is absent', async () => {
153
+ vi.mocked(mockedExecute).mockResolvedValueOnce({
154
+ data: { success: true, data: [...hiringRows] },
155
+ _meta: { provider: 'signalbase-hiring', latencyMs: 1 },
156
+ })
157
+ const result = await findSignalsHandler({ signal_type: 'hiring', limit: 25 })
158
+ const body = JSON.parse(result.content[0].text)
159
+ expect(body.data.data).toHaveLength(5)
160
+ })
161
+
162
+ it('does not apply filter to non-hiring signal types', async () => {
163
+ vi.mocked(mockedExecute).mockResolvedValueOnce({
164
+ data: { success: true, data: [...hiringRows] },
165
+ _meta: { provider: 'signalbase-funding', latencyMs: 1 },
166
+ })
167
+ const result = await findSignalsHandler({ signal_type: 'funding', industries: ['Aerospace'], limit: 25 })
168
+ const body = JSON.parse(result.content[0].text)
169
+ // Untouched: industries is forwarded upstream for funding, not post-filtered here.
170
+ expect(body.data.data).toHaveLength(5)
171
+ })
172
+ })