hunter-mate 0.1.3 → 0.1.5

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 (104) hide show
  1. package/LICENSE +21 -0
  2. package/dist/assets/extension/background/service-worker.js +113 -24
  3. package/dist/assets/extension/content/index.js +239 -134
  4. package/dist/assets/extension/manifest.json +2 -4
  5. package/dist/assets/extension/sidepanel/index.js +76 -2
  6. package/dist/assets/server/app.module.js +4 -2
  7. package/dist/assets/server/app.module.js.map +1 -1
  8. package/dist/assets/server/build-info.json +1 -1
  9. package/dist/assets/server/db/sqlite.module.js +4 -0
  10. package/dist/assets/server/db/sqlite.module.js.map +1 -1
  11. package/dist/assets/server/devops/devops-sink-init.d.ts +14 -1
  12. package/dist/assets/server/devops/devops-sink-init.js +8 -3
  13. package/dist/assets/server/devops/devops-sink-init.js.map +1 -1
  14. package/dist/assets/server/doctor/doctor.controller.d.ts +13 -0
  15. package/dist/assets/server/doctor/doctor.controller.js +62 -0
  16. package/dist/assets/server/doctor/doctor.controller.js.map +1 -0
  17. package/dist/assets/server/doctor/doctor.module.d.ts +2 -0
  18. package/dist/assets/server/doctor/doctor.module.js +27 -0
  19. package/dist/assets/server/doctor/doctor.module.js.map +1 -0
  20. package/dist/assets/server/doctor/doctor.service.d.ts +15 -0
  21. package/dist/assets/server/doctor/doctor.service.js +209 -0
  22. package/dist/assets/server/doctor/doctor.service.js.map +1 -0
  23. package/dist/assets/server/doctor/doctor.types.d.ts +46 -0
  24. package/dist/assets/server/doctor/doctor.types.js +3 -0
  25. package/dist/assets/server/doctor/doctor.types.js.map +1 -0
  26. package/dist/assets/server/extraction/adapter.service.d.ts +18 -4
  27. package/dist/assets/server/extraction/adapter.service.js +129 -15
  28. package/dist/assets/server/extraction/adapter.service.js.map +1 -1
  29. package/dist/assets/server/extraction/anomaly-report.service.d.ts +12 -0
  30. package/dist/assets/server/extraction/anomaly-report.service.js +81 -0
  31. package/dist/assets/server/extraction/anomaly-report.service.js.map +1 -0
  32. package/dist/assets/server/extraction/entities/adapter-rule.entity.d.ts +13 -0
  33. package/dist/assets/server/extraction/entities/adapter-rule.entity.js +71 -0
  34. package/dist/assets/server/extraction/entities/adapter-rule.entity.js.map +1 -0
  35. package/dist/assets/server/extraction/entities/parse-log.entity.d.ts +4 -1
  36. package/dist/assets/server/extraction/entities/parse-log.entity.js +15 -0
  37. package/dist/assets/server/extraction/entities/parse-log.entity.js.map +1 -1
  38. package/dist/assets/server/extraction/extraction-entity.controller.d.ts +40 -2
  39. package/dist/assets/server/extraction/extraction-entity.controller.js +196 -13
  40. package/dist/assets/server/extraction/extraction-entity.controller.js.map +1 -1
  41. package/dist/assets/server/extraction/extraction-rule.service.js +16 -8
  42. package/dist/assets/server/extraction/extraction-rule.service.js.map +1 -1
  43. package/dist/assets/server/extraction/extraction.module.js +12 -2
  44. package/dist/assets/server/extraction/extraction.module.js.map +1 -1
  45. package/dist/assets/server/extraction/extraction.service.d.ts +17 -1
  46. package/dist/assets/server/extraction/extraction.service.js +125 -42
  47. package/dist/assets/server/extraction/extraction.service.js.map +1 -1
  48. package/dist/assets/server/extraction/linkedin-extractor.d.ts +1 -0
  49. package/dist/assets/server/extraction/linkedin-extractor.js +244 -0
  50. package/dist/assets/server/extraction/linkedin-extractor.js.map +1 -0
  51. package/dist/assets/server/extraction/rrweb-snapshot.utils.d.ts +15 -0
  52. package/dist/assets/server/extraction/rrweb-snapshot.utils.js +48 -0
  53. package/dist/assets/server/extraction/rrweb-snapshot.utils.js.map +1 -0
  54. package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.d.ts +1 -0
  55. package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.js +60 -0
  56. package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.js.map +1 -0
  57. package/dist/assets/server/extraction/script-rule.d.ts +1 -0
  58. package/dist/assets/server/extraction/script-rule.js +4 -0
  59. package/dist/assets/server/extraction/script-rule.js.map +1 -1
  60. package/dist/assets/server/extraction/snapshot-analysis.service.d.ts +23 -0
  61. package/dist/assets/server/extraction/snapshot-analysis.service.js +147 -0
  62. package/dist/assets/server/extraction/snapshot-analysis.service.js.map +1 -0
  63. package/dist/assets/server/recording/entities/recording-snapshot.entity.d.ts +16 -0
  64. package/dist/assets/server/recording/entities/recording-snapshot.entity.js +91 -0
  65. package/dist/assets/server/recording/entities/recording-snapshot.entity.js.map +1 -0
  66. package/dist/assets/server/recording/recording-event-bus.service.d.ts +4 -0
  67. package/dist/assets/server/recording/recording-event-bus.service.js +25 -0
  68. package/dist/assets/server/recording/recording-event-bus.service.js.map +1 -0
  69. package/dist/assets/server/recording/recording-snapshot.service.d.ts +13 -0
  70. package/dist/assets/server/recording/recording-snapshot.service.js +81 -0
  71. package/dist/assets/server/recording/recording-snapshot.service.js.map +1 -0
  72. package/dist/assets/server/recording/recording-snapshot.service.spec.d.ts +1 -0
  73. package/dist/assets/server/recording/recording-snapshot.service.spec.js +65 -0
  74. package/dist/assets/server/recording/recording-snapshot.service.spec.js.map +1 -0
  75. package/dist/assets/server/recording/recording.controller.d.ts +3 -1
  76. package/dist/assets/server/recording/recording.controller.js +7 -3
  77. package/dist/assets/server/recording/recording.controller.js.map +1 -1
  78. package/dist/assets/server/recording/recording.module.js +11 -4
  79. package/dist/assets/server/recording/recording.module.js.map +1 -1
  80. package/dist/assets/server/recording/recording.service.d.ts +5 -21
  81. package/dist/assets/server/recording/recording.service.js +22 -9
  82. package/dist/assets/server/recording/recording.service.js.map +1 -1
  83. package/dist/assets/server/site/entities/site-registry.entity.d.ts +2 -0
  84. package/dist/assets/server/site/entities/site-registry.entity.js +10 -0
  85. package/dist/assets/server/site/entities/site-registry.entity.js.map +1 -1
  86. package/dist/assets/server/site/site.controller.d.ts +2 -0
  87. package/dist/assets/server/site/site.controller.js +1 -1
  88. package/dist/assets/server/site/site.controller.js.map +1 -1
  89. package/dist/assets/server/site/site.service.d.ts +2 -1
  90. package/dist/assets/server/site/site.service.js +10 -3
  91. package/dist/assets/server/site/site.service.js.map +1 -1
  92. package/dist/auto-doctor.d.ts +8 -0
  93. package/dist/auto-doctor.js +34 -0
  94. package/dist/commands/doctor.d.ts +43 -0
  95. package/dist/commands/doctor.js +179 -7
  96. package/dist/commands/extension.js +2 -2
  97. package/dist/commands/extras.d.ts +1 -1
  98. package/dist/commands/extras.js +4 -3
  99. package/dist/commands/install.js +11 -8
  100. package/dist/index.js +7 -0
  101. package/dist/native-check.js +8 -1
  102. package/dist/updater.d.ts +9 -5
  103. package/dist/updater.js +75 -9
  104. package/package.json +3 -3
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HiredChina
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -2546,7 +2546,10 @@ var PATH_CLASS_HINTS = [
2546
2546
  { re: /\/(company|companies|employer)\b/i, cls: "company" },
2547
2547
  { re: /\/(search|talent|people|directory)\b/i, cls: "list" }
2548
2548
  ];
2549
- var enabledDomains = /* @__PURE__ */ new Set();
2549
+ var sitePolicyMap = /* @__PURE__ */ new Map();
2550
+ function getSitePolicy(hostname) {
2551
+ return sitePolicyMap.get(etldPlusOne(hostname)) ?? { record: false, parse: false };
2552
+ }
2550
2553
  async function syncSites() {
2551
2554
  let entries = [];
2552
2555
  try {
@@ -2558,10 +2561,19 @@ async function syncSites() {
2558
2561
  } catch {
2559
2562
  return [];
2560
2563
  }
2561
- const next = new Set(entries.filter((e) => e.enabled).map((e) => e.domain));
2562
- const changed = symmetricDiffers(enabledDomains, next);
2563
- enabledDomains = next;
2564
- if (changed) await registerDynamicScripts([...next]);
2564
+ const next = /* @__PURE__ */ new Map();
2565
+ for (const e of entries) {
2566
+ if (!e.enabled) continue;
2567
+ next.set(e.domain, {
2568
+ record: true,
2569
+ parse: true,
2570
+ adapterPlatform: e.adapterPlatform || e.platform
2571
+ });
2572
+ }
2573
+ sitePolicyMap.clear();
2574
+ for (const [k, v] of next) sitePolicyMap.set(k, v);
2575
+ const domains = [...sitePolicyMap.keys()];
2576
+ await registerDynamicScripts(domains);
2565
2577
  return entries;
2566
2578
  }
2567
2579
  async function registerDynamicScripts(domains) {
@@ -2582,11 +2594,6 @@ async function registerDynamicScripts(domains) {
2582
2594
  ]);
2583
2595
  console.log(`[HunterMate] dynamic content scripts registered for ${domains.length} domains`);
2584
2596
  }
2585
- function symmetricDiffers(a, b) {
2586
- if (a.size !== b.size) return true;
2587
- for (const v of a) if (!b.has(v)) return true;
2588
- return false;
2589
- }
2590
2597
  function isProductionDomain(hostname) {
2591
2598
  const h = hostname.toLowerCase().trim();
2592
2599
  if (!h) return false;
@@ -2621,7 +2628,7 @@ function maybeDiscover(url, title) {
2621
2628
  }
2622
2629
  if (!isProductionDomain(hostname)) return;
2623
2630
  const domain = etldPlusOne(hostname);
2624
- if (discovered.has(domain) || enabledDomains.has(domain)) return;
2631
+ if (discovered.has(domain) || sitePolicyMap.has(domain)) return;
2625
2632
  const haystack = `${title} ${url}`.toLowerCase();
2626
2633
  const hit = RECRUITING_HINTS.find((k) => haystack.includes(k));
2627
2634
  if (!hit) return;
@@ -2965,14 +2972,12 @@ async function createBackgroundLogForwarder(options) {
2965
2972
  var state = {
2966
2973
  serverConnected: false,
2967
2974
  wsConnected: false,
2968
- recordingSessionId: null,
2969
- eventCount: 0,
2970
2975
  ruleVersion: null,
2971
- classification: null,
2972
2976
  sidePanel: "pending",
2973
2977
  serverVersion: null,
2974
2978
  serverBuildTime: null
2975
2979
  };
2980
+ var tabStates = /* @__PURE__ */ new Map();
2976
2981
  var backgroundLogger = createExtensionLogger({ context: "background", sessionId: () => `bg-${Date.now()}` });
2977
2982
  backgroundLogger.patchConsole();
2978
2983
  var logForwarder = null;
@@ -3073,8 +3078,32 @@ async function checkRuleVersion() {
3073
3078
  } catch {
3074
3079
  }
3075
3080
  }
3081
+ async function buildStatusForActiveTab() {
3082
+ try {
3083
+ const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
3084
+ const tab = tabs[0];
3085
+ const tabId = tab?.id;
3086
+ if (tabId == null) {
3087
+ return { ...state, tabId: -1, url: "", recordingSessionId: null, eventCount: 0, classification: null };
3088
+ }
3089
+ const ts = tabStates.get(tabId);
3090
+ if (ts) return { ...state, ...ts };
3091
+ return {
3092
+ ...state,
3093
+ tabId,
3094
+ url: tab.url || "",
3095
+ recordingSessionId: null,
3096
+ eventCount: 0,
3097
+ classification: null
3098
+ };
3099
+ } catch {
3100
+ return { ...state, tabId: -1, url: "", recordingSessionId: null, eventCount: 0, classification: null };
3101
+ }
3102
+ }
3076
3103
  function broadcastState() {
3077
- chrome.runtime.sendMessage({ type: "status", payload: state }).catch(() => {
3104
+ buildStatusForActiveTab().then((payload) => {
3105
+ chrome.runtime.sendMessage({ type: "status", payload }).catch(() => {
3106
+ });
3078
3107
  });
3079
3108
  }
3080
3109
  function connect() {
@@ -3128,6 +3157,7 @@ function connect() {
3128
3157
  status: "ok",
3129
3158
  result: {
3130
3159
  ...state,
3160
+ tabStatesCount: tabStates.size,
3131
3161
  extBasePath: chrome.runtime.getURL(""),
3132
3162
  manifestPermissions: manifest.permissions,
3133
3163
  hasSidePanelInManifest: manifest.permissions?.includes("sidePanel"),
@@ -3215,35 +3245,74 @@ if (typeof chrome !== "undefined" && chrome.sidePanel?.setPanelBehavior) {
3215
3245
  } else {
3216
3246
  state.sidePanel = "error: chrome.sidePanel API not available";
3217
3247
  }
3248
+ chrome.tabs.onActivated.addListener(() => {
3249
+ broadcastState();
3250
+ });
3251
+ chrome.tabs.onUpdated.addListener((_tabId, changeInfo, tab) => {
3252
+ if (!tab.url) return;
3253
+ const ts = tabStates.get(_tabId);
3254
+ if (ts) {
3255
+ ts.url = tab.url;
3256
+ }
3257
+ if (changeInfo.url) {
3258
+ broadcastState();
3259
+ }
3260
+ });
3218
3261
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
3219
3262
  if (message.type === "get-status") {
3220
- sendResponse(state);
3263
+ buildStatusForActiveTab().then((payload) => {
3264
+ sendResponse(payload);
3265
+ });
3266
+ return true;
3267
+ }
3268
+ if (message.type === "query-site-policy") {
3269
+ const url = message.payload?.url;
3270
+ let policy = { record: false, parse: false };
3271
+ try {
3272
+ if (url) {
3273
+ const hostname = new URL(url).hostname;
3274
+ policy = getSitePolicy(hostname);
3275
+ }
3276
+ } catch {
3277
+ }
3278
+ sendResponse(policy);
3221
3279
  return true;
3222
3280
  }
3223
3281
  if (message.type === "recording-started" && message.payload?.sessionId) {
3224
- state.recordingSessionId = message.payload.sessionId;
3225
- state.eventCount = 0;
3226
- state.classification = message.payload.classification ?? null;
3282
+ const tabId = sender.tab?.id ?? -1;
3283
+ const classification = message.payload.classification ?? null;
3284
+ tabStates.set(tabId, {
3285
+ tabId,
3286
+ url: sender.tab?.url || "",
3287
+ recordingSessionId: message.payload.sessionId,
3288
+ eventCount: 0,
3289
+ classification
3290
+ });
3227
3291
  broadcastState();
3228
3292
  sendResponse({ ok: true });
3229
3293
  return true;
3230
3294
  }
3231
3295
  if (message.type === "recording-stopped") {
3232
- state.recordingSessionId = null;
3233
- state.eventCount = 0;
3296
+ const tabId = sender.tab?.id ?? -1;
3297
+ const existing = tabStates.get(tabId);
3298
+ if (existing) {
3299
+ tabStates.set(tabId, { ...existing, recordingSessionId: null, eventCount: 0 });
3300
+ }
3234
3301
  broadcastState();
3235
3302
  sendResponse({ ok: true });
3236
3303
  return true;
3237
3304
  }
3238
3305
  if (message.type === "recording-event") {
3239
- const payload = { ...message.payload, tabId: sender.tab?.id };
3306
+ const tabId = sender.tab?.id ?? -1;
3307
+ const payload = { ...message.payload, tabId };
3240
3308
  if (socket?.readyState === WebSocket.OPEN) {
3241
3309
  socket.send(JSON.stringify(payload));
3242
3310
  } else {
3243
3311
  enqueueRecordingEvent(payload);
3244
3312
  }
3245
- if (message.payload?.sessionId === state.recordingSessionId) {
3246
- state.eventCount++;
3313
+ const ts = tabStates.get(tabId);
3314
+ if (ts && message.payload?.sessionId === ts.recordingSessionId) {
3315
+ ts.eventCount++;
3247
3316
  }
3248
3317
  } else if (message.type === "hm:logs" && Array.isArray(message.logs)) {
3249
3318
  logForwarder?.onLogsMessage(message.logs);
@@ -3251,3 +3320,23 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
3251
3320
  sendResponse({ ok: true });
3252
3321
  return true;
3253
3322
  });
3323
+ chrome.tabs.query({}, (tabs) => {
3324
+ for (const tab of tabs) {
3325
+ const tabId = tab.id;
3326
+ if (tabId == null || !tab.url) continue;
3327
+ const policy = getSitePolicy(new URL(tab.url).hostname);
3328
+ if (policy.record) {
3329
+ tabStates.set(tabId, {
3330
+ tabId,
3331
+ url: tab.url,
3332
+ recordingSessionId: null,
3333
+ eventCount: 0,
3334
+ classification: null
3335
+ });
3336
+ }
3337
+ }
3338
+ broadcastState();
3339
+ });
3340
+ chrome.tabs.onRemoved.addListener((tabId) => {
3341
+ tabStates.delete(tabId);
3342
+ });