hunter-mate 0.1.25 → 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.
- package/dist/assets/extension/background/{service-worker.20261017183328.js → service-worker.20261020181646.js} +60 -4
- package/dist/assets/extension/background/service-worker.js +60 -4
- package/dist/assets/extension/build-info.json +1 -1
- package/dist/assets/extension/content/index.js +284 -64
- package/dist/assets/extension/manifest.json +3 -3
- package/dist/assets/extension/sidepanel/index.html +1 -1
- package/dist/assets/extension/sidepanel/index.js +14 -14
- package/dist/assets/server/main.mjs +2318 -1987
- package/dist/index.js +52 -68
- package/dist/watchdog.js +62 -6
- package/dist/web/dist/404.html +1 -1
- package/dist/web/dist/_next/static/chunks/187-f067914dcd1330c2.js +32 -0
- package/dist/web/dist/_next/static/chunks/253-f4ac7af6647e4dba.js +1 -0
- package/dist/web/dist/_next/static/chunks/{589-f984bff035a1cb85.js → 589-5bb84ab8060e960b.js} +1 -1
- package/dist/web/dist/_next/static/chunks/659-b23050764c004f5f.js +1 -0
- package/dist/web/dist/_next/static/chunks/{686-9f419b70feea9470.js → 686-5f4ee3649cce07f1.js} +1 -1
- package/dist/web/dist/_next/static/chunks/728-cffab7e836020551.js +12 -0
- package/dist/web/dist/_next/static/chunks/{865-0ed23dd43c0832a2.js → 865-8e1d8c34192526ed.js} +1 -1
- package/dist/web/dist/_next/static/chunks/896-9dce6a3bc525edba.js +1 -0
- package/dist/web/dist/_next/static/chunks/{935-7be3e60dd8bc29d2.js → 935-12f1084f0e18c962.js} +1 -1
- package/dist/web/dist/_next/static/chunks/{a7067448-e416655baf443992.js → a7067448-3f2b194cfadb91fb.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/_not-found/{page-5b7249eb3c9a6cb9.js → page-46929212b0496a89.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/admin/data/{page-14698e9c4ddaa6d9.js → page-666f99fbfee46cc9.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/auth/verify/{page-05304d5803008d61.js → page-2da5807d6cdfdb4e.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/companies/{page-e8d02fe997579315.js → page-390d5e3073ec151d.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/company/admin/{page-c2584183bc4b34d1.js → page-02244f3f1a212c76.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/entity/{page-08755f96102f0565.js → page-d59a8103f8107d3b.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-fa83ce1b6c3b345d.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/layout-15c4c2ba595b2a92.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/logs/{page-be50a4e10b1a0024.js → page-badf48f4e7e32e17.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/matching/jobs/[id]/talents/{page-cf445b0cb8c2cb0a.js → page-73bca3864b8b9e44.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/matching/portraits/[id]/jobs/{page-c7ff0d79b6a75915.js → page-477c66bee61225fa.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/{page-bd282e1e5f0965f1.js → page-8ea324b366e3d374.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/parselog/{page-9814e75d6900a743.js → page-4f5c186442feb386.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/recordings/page-0fb8cafdd2f6762c.js +1 -0
- package/dist/web/dist/_next/static/chunks/app/resource-usage/{page-f6fa06bfe21bcd32.js → page-76be36ca978391a3.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/shared/[token]/{page-c9c5042a2d07c0bc.js → page-fe2b986867d317c0.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/snapshots/[id]/agent-prompt/{page-f54cf2f0058035ca.js → page-60ea46364a74b294.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/talents/{page-0edef6d07b3cf69d.js → page-5a2caa7a503ee041.js} +1 -1
- package/dist/web/dist/_next/static/chunks/app/team/insights/{page-8b3934df3e292368.js → page-5385dcd363f6e0cd.js} +1 -1
- package/dist/web/dist/_next/static/chunks/webpack-9cebd25e322e2cd7.js +1 -0
- package/dist/web/dist/_next/static/css/8f3c454cab3414d0.css +3 -0
- package/dist/web/dist/admin/data.html +1 -1
- package/dist/web/dist/admin/data.txt +5 -5
- package/dist/web/dist/auth/verify.html +1 -1
- package/dist/web/dist/auth/verify.txt +5 -5
- package/dist/web/dist/companies.html +1 -1
- package/dist/web/dist/companies.txt +5 -5
- package/dist/web/dist/company/admin.html +1 -1
- package/dist/web/dist/company/admin.txt +5 -5
- package/dist/web/dist/entity.html +1 -1
- package/dist/web/dist/entity.txt +5 -5
- package/dist/web/dist/index.html +1 -1
- package/dist/web/dist/index.txt +5 -5
- package/dist/web/dist/jobs.html +1 -1
- package/dist/web/dist/jobs.txt +5 -5
- package/dist/web/dist/logs.html +1 -1
- package/dist/web/dist/logs.txt +5 -5
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +5 -5
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +5 -5
- package/dist/web/dist/parselog.html +1 -1
- package/dist/web/dist/parselog.txt +5 -5
- package/dist/web/dist/recordings.html +1 -1
- package/dist/web/dist/recordings.txt +5 -5
- package/dist/web/dist/resource-usage.html +1 -1
- package/dist/web/dist/resource-usage.txt +5 -5
- package/dist/web/dist/shared/placeholder.html +1 -1
- package/dist/web/dist/shared/placeholder.txt +5 -5
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +5 -5
- package/dist/web/dist/talents.html +1 -1
- package/dist/web/dist/talents.txt +5 -5
- package/dist/web/dist/team/insights.html +1 -1
- package/dist/web/dist/team/insights.txt +5 -5
- package/package.json +3 -6
- package/dist/web/dist/_next/static/chunks/105-dcd8f6d5867c8995.js +0 -32
- package/dist/web/dist/_next/static/chunks/166.b263e636ff66212f.js +0 -1
- package/dist/web/dist/_next/static/chunks/253-a05d05b94bfbd7a4.js +0 -1
- package/dist/web/dist/_next/static/chunks/555-e2a871b9d2eccb03.js +0 -12
- package/dist/web/dist/_next/static/chunks/852-ad19b97821a4cf9e.js +0 -1
- package/dist/web/dist/_next/static/chunks/app/jobs/page-4827a9ef286b6483.js +0 -1
- package/dist/web/dist/_next/static/chunks/app/layout-af39afc7866e74db.js +0 -1
- package/dist/web/dist/_next/static/chunks/app/recordings/page-441016638b43c4f8.js +0 -1
- package/dist/web/dist/_next/static/chunks/webpack-54e74ccc9e9451ee.js +0 -1
- package/dist/web/dist/_next/static/css/10ba1fa1d6ce23a7.css +0 -3
- package/dist/web/dist/_next/static/css/f60d210841fab76b.css +0 -1
- /package/dist/web/dist/_next/static/{5MA8faUttk6FzlxGWnOlM → tYFZz41gyWi4-BhxuxlGU}/_buildManifest.js +0 -0
- /package/dist/web/dist/_next/static/{5MA8faUttk6FzlxGWnOlM → tYFZz41gyWi4-BhxuxlGU}/_ssgManifest.js +0 -0
|
@@ -228,6 +228,7 @@ var require_hbr = __commonJS({
|
|
|
228
228
|
exports.createHbrEvent = createHbrEvent;
|
|
229
229
|
exports.createNetworkEvent = createNetworkEvent;
|
|
230
230
|
exports.createConsoleEvent = createConsoleEvent;
|
|
231
|
+
exports.createExceptionEvent = createExceptionEvent;
|
|
231
232
|
exports.createResumeEvent = createResumeEvent;
|
|
232
233
|
exports.createActionEvent = createActionEvent;
|
|
233
234
|
function createHbrEvent(type, sessionId, payload, options) {
|
|
@@ -247,6 +248,9 @@ var require_hbr = __commonJS({
|
|
|
247
248
|
function createConsoleEvent(sessionId, data, privacy = "private") {
|
|
248
249
|
return createHbrEvent("console", sessionId, data, { privacy });
|
|
249
250
|
}
|
|
251
|
+
function createExceptionEvent(sessionId, data, privacy = "private") {
|
|
252
|
+
return createHbrEvent("exception", sessionId, data, { privacy });
|
|
253
|
+
}
|
|
250
254
|
function createResumeEvent(sessionId, data, privacy = "private") {
|
|
251
255
|
return createHbrEvent("resume", sessionId, data, { privacy });
|
|
252
256
|
}
|
|
@@ -2339,6 +2343,31 @@ async function findDetailTabToReuse(url) {
|
|
|
2339
2343
|
return idle?.id;
|
|
2340
2344
|
}
|
|
2341
2345
|
|
|
2346
|
+
// src/background/linkedin-search-filter.ts
|
|
2347
|
+
var LINKEDIN_DEFAULT_LOAD_TIMEOUT_MS = 9e4;
|
|
2348
|
+
var MIN_TIMEOUT_MS = 5e3;
|
|
2349
|
+
var MAX_TIMEOUT_MS = 3e5;
|
|
2350
|
+
function clampLoadTimeoutMs(raw) {
|
|
2351
|
+
const n = Number(raw);
|
|
2352
|
+
if (!Number.isFinite(n) || n <= 0) return LINKEDIN_DEFAULT_LOAD_TIMEOUT_MS;
|
|
2353
|
+
return Math.min(Math.max(n, MIN_TIMEOUT_MS), MAX_TIMEOUT_MS);
|
|
2354
|
+
}
|
|
2355
|
+
function buildCardMatcher(filters) {
|
|
2356
|
+
const needle = (v) => typeof v === "string" && v.trim() ? v.trim().toLowerCase() : null;
|
|
2357
|
+
const locNeedle = filters.geoUrn ? null : needle(filters.location);
|
|
2358
|
+
const coNeedle = needle(filters.company);
|
|
2359
|
+
return {
|
|
2360
|
+
locNeedle,
|
|
2361
|
+
coNeedle,
|
|
2362
|
+
match(ctx) {
|
|
2363
|
+
const h = (ctx || "").toLowerCase();
|
|
2364
|
+
if (locNeedle && !h.includes(locNeedle)) return false;
|
|
2365
|
+
if (coNeedle && !h.includes(coNeedle)) return false;
|
|
2366
|
+
return true;
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2342
2371
|
// src/background/control.ts
|
|
2343
2372
|
var RUNTIME_BRIDGE_FILE = "content/control-runtime.js";
|
|
2344
2373
|
async function invokeRuntimeBridge(command, args) {
|
|
@@ -2940,12 +2969,25 @@ var LINKEDIN_EXTRACT_SOURCE = String.raw`(async () => {
|
|
|
2940
2969
|
});
|
|
2941
2970
|
} else if (pageClass === 'list') {
|
|
2942
2971
|
const seen = new Set();
|
|
2972
|
+
// 卡片上下文:LinkedIn list 页 a[href*=/in/] 埋在结果卡内,向上找最小"像卡片"的祖先
|
|
2973
|
+
// (innerText 40-500 字符),抓 headline/地区/公司行——location/company 过滤的判定依据
|
|
2974
|
+
// (2026-10-18 寻访实测:LinkedIn 对自由文本 location/company 查询参数基本不生效,
|
|
2975
|
+
// 必须在 client 端按卡片文本过滤,否则过滤器名存实亡)。
|
|
2976
|
+
const cardCtx = (a) => {
|
|
2977
|
+
let el = a;
|
|
2978
|
+
for (let up = 0; up < 5 && el.parentElement; up++) {
|
|
2979
|
+
el = el.parentElement;
|
|
2980
|
+
const t = (el.innerText || '').replace(/\s+/g, ' ').trim();
|
|
2981
|
+
if (t.length >= 40) return t.slice(0, 400);
|
|
2982
|
+
}
|
|
2983
|
+
return null;
|
|
2984
|
+
};
|
|
2943
2985
|
for (const a of Array.from(document.querySelectorAll('a[href]'))) {
|
|
2944
2986
|
const href = a.href || '';
|
|
2945
2987
|
let m = href.match(/linkedin\.com\/in\/([^/?#]+)/);
|
|
2946
2988
|
if (m && !seen.has('t:' + m[1])) {
|
|
2947
2989
|
seen.add('t:' + m[1]);
|
|
2948
|
-
links.talent.push({ url: 'https://www.linkedin.com/in/' + m[1] + '/', name: (a.textContent || '').trim().split('\n')[0] || m[1] });
|
|
2990
|
+
links.talent.push({ url: 'https://www.linkedin.com/in/' + m[1] + '/', name: (a.textContent || '').trim().split('\n')[0] || m[1], ctx: cardCtx(a) });
|
|
2949
2991
|
}
|
|
2950
2992
|
m = href.match(/linkedin\.com\/company\/([^/?#]+)/);
|
|
2951
2993
|
if (m && !seen.has('c:' + m[1])) {
|
|
@@ -3025,7 +3067,7 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3025
3067
|
const maxPages = Math.min(Math.max(Number(args.maxPages) || 3, 1), 10);
|
|
3026
3068
|
const keepTab = args.keepTab === true;
|
|
3027
3069
|
const activateTab = args.activateTab !== false;
|
|
3028
|
-
const loadTimeoutMs =
|
|
3070
|
+
const loadTimeoutMs = clampLoadTimeoutMs(args.loadTimeoutMs);
|
|
3029
3071
|
const delayBase = typeof args.delayMs === "number" ? Number(args.delayMs) : 2500;
|
|
3030
3072
|
let effectiveKeywords = keywords;
|
|
3031
3073
|
if (!filters.geoUrn && typeof filters.location === "string" && filters.location.trim()) {
|
|
@@ -3039,6 +3081,9 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3039
3081
|
if (typeof filters.geoUrn === "string" && filters.geoUrn) u.searchParams.set("geoUrn", filters.geoUrn);
|
|
3040
3082
|
if (typeof filters.company === "string" && filters.company) u.searchParams.set("company", filters.company);
|
|
3041
3083
|
if (typeof filters.school === "string" && filters.school) u.searchParams.set("school", filters.school);
|
|
3084
|
+
const matcher = buildCardMatcher(filters);
|
|
3085
|
+
const locNeedle = matcher.locNeedle;
|
|
3086
|
+
const coNeedle = matcher.coNeedle;
|
|
3042
3087
|
const tab = await chrome.tabs.create({ url: u.toString(), active: false });
|
|
3043
3088
|
log("info", "hm.linkedin.search tab created", { tabId: tab.id, url: u.toString(), maxPages, activateTab });
|
|
3044
3089
|
if (activateTab && tab.id != null) {
|
|
@@ -3066,13 +3111,24 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3066
3111
|
const extracted = await cdpEvaluate(tab.id, LINKEDIN_EXTRACT_SOURCE);
|
|
3067
3112
|
lastUrl = extracted?.url || lastUrl;
|
|
3068
3113
|
const pageLeads = extracted?.links?.talent || [];
|
|
3114
|
+
let pageFiltered = 0;
|
|
3069
3115
|
for (const l of pageLeads) {
|
|
3116
|
+
if ((locNeedle || coNeedle) && !matcher.match(l.ctx)) {
|
|
3117
|
+
pageFiltered++;
|
|
3118
|
+
continue;
|
|
3119
|
+
}
|
|
3070
3120
|
if (l.url && !leads.has(l.url)) {
|
|
3071
|
-
leads.set(l.url, {
|
|
3121
|
+
leads.set(l.url, {
|
|
3122
|
+
url: l.url,
|
|
3123
|
+
name: l.name ?? null,
|
|
3124
|
+
page,
|
|
3125
|
+
source: "linkedin",
|
|
3126
|
+
...l.ctx ? { snippet: l.ctx.slice(0, 200) } : {}
|
|
3127
|
+
});
|
|
3072
3128
|
}
|
|
3073
3129
|
}
|
|
3074
3130
|
pagesScanned = page;
|
|
3075
|
-
log("info", "hm.linkedin.search page extracted", { page, pageLeads: pageLeads.length, total: leads.size });
|
|
3131
|
+
log("info", "hm.linkedin.search page extracted", { page, pageLeads: pageLeads.length, pageFiltered, total: leads.size });
|
|
3076
3132
|
if (page >= maxPages) break;
|
|
3077
3133
|
const clicked = await cdpEvaluate(tab.id, LINKEDIN_NEXT_CLICK_SOURCE).catch(() => false);
|
|
3078
3134
|
const urlBefore = (await chrome.tabs.get(tab.id).catch(() => null))?.url || "";
|
|
@@ -228,6 +228,7 @@ var require_hbr = __commonJS({
|
|
|
228
228
|
exports.createHbrEvent = createHbrEvent;
|
|
229
229
|
exports.createNetworkEvent = createNetworkEvent;
|
|
230
230
|
exports.createConsoleEvent = createConsoleEvent;
|
|
231
|
+
exports.createExceptionEvent = createExceptionEvent;
|
|
231
232
|
exports.createResumeEvent = createResumeEvent;
|
|
232
233
|
exports.createActionEvent = createActionEvent;
|
|
233
234
|
function createHbrEvent(type, sessionId, payload, options) {
|
|
@@ -247,6 +248,9 @@ var require_hbr = __commonJS({
|
|
|
247
248
|
function createConsoleEvent(sessionId, data, privacy = "private") {
|
|
248
249
|
return createHbrEvent("console", sessionId, data, { privacy });
|
|
249
250
|
}
|
|
251
|
+
function createExceptionEvent(sessionId, data, privacy = "private") {
|
|
252
|
+
return createHbrEvent("exception", sessionId, data, { privacy });
|
|
253
|
+
}
|
|
250
254
|
function createResumeEvent(sessionId, data, privacy = "private") {
|
|
251
255
|
return createHbrEvent("resume", sessionId, data, { privacy });
|
|
252
256
|
}
|
|
@@ -2339,6 +2343,31 @@ async function findDetailTabToReuse(url) {
|
|
|
2339
2343
|
return idle?.id;
|
|
2340
2344
|
}
|
|
2341
2345
|
|
|
2346
|
+
// src/background/linkedin-search-filter.ts
|
|
2347
|
+
var LINKEDIN_DEFAULT_LOAD_TIMEOUT_MS = 9e4;
|
|
2348
|
+
var MIN_TIMEOUT_MS = 5e3;
|
|
2349
|
+
var MAX_TIMEOUT_MS = 3e5;
|
|
2350
|
+
function clampLoadTimeoutMs(raw) {
|
|
2351
|
+
const n = Number(raw);
|
|
2352
|
+
if (!Number.isFinite(n) || n <= 0) return LINKEDIN_DEFAULT_LOAD_TIMEOUT_MS;
|
|
2353
|
+
return Math.min(Math.max(n, MIN_TIMEOUT_MS), MAX_TIMEOUT_MS);
|
|
2354
|
+
}
|
|
2355
|
+
function buildCardMatcher(filters) {
|
|
2356
|
+
const needle = (v) => typeof v === "string" && v.trim() ? v.trim().toLowerCase() : null;
|
|
2357
|
+
const locNeedle = filters.geoUrn ? null : needle(filters.location);
|
|
2358
|
+
const coNeedle = needle(filters.company);
|
|
2359
|
+
return {
|
|
2360
|
+
locNeedle,
|
|
2361
|
+
coNeedle,
|
|
2362
|
+
match(ctx) {
|
|
2363
|
+
const h = (ctx || "").toLowerCase();
|
|
2364
|
+
if (locNeedle && !h.includes(locNeedle)) return false;
|
|
2365
|
+
if (coNeedle && !h.includes(coNeedle)) return false;
|
|
2366
|
+
return true;
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
|
|
2342
2371
|
// src/background/control.ts
|
|
2343
2372
|
var RUNTIME_BRIDGE_FILE = "content/control-runtime.js";
|
|
2344
2373
|
async function invokeRuntimeBridge(command, args) {
|
|
@@ -2940,12 +2969,25 @@ var LINKEDIN_EXTRACT_SOURCE = String.raw`(async () => {
|
|
|
2940
2969
|
});
|
|
2941
2970
|
} else if (pageClass === 'list') {
|
|
2942
2971
|
const seen = new Set();
|
|
2972
|
+
// 卡片上下文:LinkedIn list 页 a[href*=/in/] 埋在结果卡内,向上找最小"像卡片"的祖先
|
|
2973
|
+
// (innerText 40-500 字符),抓 headline/地区/公司行——location/company 过滤的判定依据
|
|
2974
|
+
// (2026-10-18 寻访实测:LinkedIn 对自由文本 location/company 查询参数基本不生效,
|
|
2975
|
+
// 必须在 client 端按卡片文本过滤,否则过滤器名存实亡)。
|
|
2976
|
+
const cardCtx = (a) => {
|
|
2977
|
+
let el = a;
|
|
2978
|
+
for (let up = 0; up < 5 && el.parentElement; up++) {
|
|
2979
|
+
el = el.parentElement;
|
|
2980
|
+
const t = (el.innerText || '').replace(/\s+/g, ' ').trim();
|
|
2981
|
+
if (t.length >= 40) return t.slice(0, 400);
|
|
2982
|
+
}
|
|
2983
|
+
return null;
|
|
2984
|
+
};
|
|
2943
2985
|
for (const a of Array.from(document.querySelectorAll('a[href]'))) {
|
|
2944
2986
|
const href = a.href || '';
|
|
2945
2987
|
let m = href.match(/linkedin\.com\/in\/([^/?#]+)/);
|
|
2946
2988
|
if (m && !seen.has('t:' + m[1])) {
|
|
2947
2989
|
seen.add('t:' + m[1]);
|
|
2948
|
-
links.talent.push({ url: 'https://www.linkedin.com/in/' + m[1] + '/', name: (a.textContent || '').trim().split('\n')[0] || m[1] });
|
|
2990
|
+
links.talent.push({ url: 'https://www.linkedin.com/in/' + m[1] + '/', name: (a.textContent || '').trim().split('\n')[0] || m[1], ctx: cardCtx(a) });
|
|
2949
2991
|
}
|
|
2950
2992
|
m = href.match(/linkedin\.com\/company\/([^/?#]+)/);
|
|
2951
2993
|
if (m && !seen.has('c:' + m[1])) {
|
|
@@ -3025,7 +3067,7 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3025
3067
|
const maxPages = Math.min(Math.max(Number(args.maxPages) || 3, 1), 10);
|
|
3026
3068
|
const keepTab = args.keepTab === true;
|
|
3027
3069
|
const activateTab = args.activateTab !== false;
|
|
3028
|
-
const loadTimeoutMs =
|
|
3070
|
+
const loadTimeoutMs = clampLoadTimeoutMs(args.loadTimeoutMs);
|
|
3029
3071
|
const delayBase = typeof args.delayMs === "number" ? Number(args.delayMs) : 2500;
|
|
3030
3072
|
let effectiveKeywords = keywords;
|
|
3031
3073
|
if (!filters.geoUrn && typeof filters.location === "string" && filters.location.trim()) {
|
|
@@ -3039,6 +3081,9 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3039
3081
|
if (typeof filters.geoUrn === "string" && filters.geoUrn) u.searchParams.set("geoUrn", filters.geoUrn);
|
|
3040
3082
|
if (typeof filters.company === "string" && filters.company) u.searchParams.set("company", filters.company);
|
|
3041
3083
|
if (typeof filters.school === "string" && filters.school) u.searchParams.set("school", filters.school);
|
|
3084
|
+
const matcher = buildCardMatcher(filters);
|
|
3085
|
+
const locNeedle = matcher.locNeedle;
|
|
3086
|
+
const coNeedle = matcher.coNeedle;
|
|
3042
3087
|
const tab = await chrome.tabs.create({ url: u.toString(), active: false });
|
|
3043
3088
|
log("info", "hm.linkedin.search tab created", { tabId: tab.id, url: u.toString(), maxPages, activateTab });
|
|
3044
3089
|
if (activateTab && tab.id != null) {
|
|
@@ -3066,13 +3111,24 @@ async function runLinkedInSearch(args, log, ctx) {
|
|
|
3066
3111
|
const extracted = await cdpEvaluate(tab.id, LINKEDIN_EXTRACT_SOURCE);
|
|
3067
3112
|
lastUrl = extracted?.url || lastUrl;
|
|
3068
3113
|
const pageLeads = extracted?.links?.talent || [];
|
|
3114
|
+
let pageFiltered = 0;
|
|
3069
3115
|
for (const l of pageLeads) {
|
|
3116
|
+
if ((locNeedle || coNeedle) && !matcher.match(l.ctx)) {
|
|
3117
|
+
pageFiltered++;
|
|
3118
|
+
continue;
|
|
3119
|
+
}
|
|
3070
3120
|
if (l.url && !leads.has(l.url)) {
|
|
3071
|
-
leads.set(l.url, {
|
|
3121
|
+
leads.set(l.url, {
|
|
3122
|
+
url: l.url,
|
|
3123
|
+
name: l.name ?? null,
|
|
3124
|
+
page,
|
|
3125
|
+
source: "linkedin",
|
|
3126
|
+
...l.ctx ? { snippet: l.ctx.slice(0, 200) } : {}
|
|
3127
|
+
});
|
|
3072
3128
|
}
|
|
3073
3129
|
}
|
|
3074
3130
|
pagesScanned = page;
|
|
3075
|
-
log("info", "hm.linkedin.search page extracted", { page, pageLeads: pageLeads.length, total: leads.size });
|
|
3131
|
+
log("info", "hm.linkedin.search page extracted", { page, pageLeads: pageLeads.length, pageFiltered, total: leads.size });
|
|
3076
3132
|
if (page >= maxPages) break;
|
|
3077
3133
|
const clicked = await cdpEvaluate(tab.id, LINKEDIN_NEXT_CLICK_SOURCE).catch(() => false);
|
|
3078
3134
|
const urlBefore = (await chrome.tabs.get(tab.id).catch(() => null))?.url || "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"buildTime":"2026-10-
|
|
1
|
+
{"buildTime":"2026-10-20T18:16:46.896Z","version":"0.1.27"}
|