@reconcrap/boss-recommend-mcp 1.3.0 → 1.3.2

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.
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "../src/cli.js";
2
+ import { runCli } from "../src/cli.js";
3
+
4
+ await runCli(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
@@ -491,8 +491,22 @@ export class BossChatApp {
491
491
  await this.checkpoint();
492
492
  const readyState = await this.page.waitForConversationReady();
493
493
  this.logger.log(
494
- `会话面板就绪。onlineResume=${Boolean(readyState?.hasOnlineResume)} | askResume=${Boolean(readyState?.hasAskResume)}`,
494
+ `会话面板就绪。onlineResume=${Boolean(readyState?.hasOnlineResume)} | askResume=${Boolean(readyState?.hasAskResume)} | attachmentResume=${Boolean(readyState?.hasAttachmentResume)} | attachmentResumeEnabled=${Boolean(readyState?.attachmentResumeEnabled)}`,
495
495
  );
496
+ if (readyState?.attachmentResumeEnabled) {
497
+ baseResult.decision = 'skipped';
498
+ baseResult.reason = '检测到附件简历按钮可用,按策略跳过,不进入在线简历截图与LLM评估。';
499
+ baseResult.artifacts.attachmentResume = {
500
+ present: Boolean(readyState?.hasAttachmentResume),
501
+ enabled: Boolean(readyState?.attachmentResumeEnabled),
502
+ className: String(readyState?.attachmentResumeClass || ''),
503
+ };
504
+ this.logger.log(
505
+ `候选人跳过:name=${customer.name || '未知'} | key=${customer.customerKey} | reason=${baseResult.reason}`,
506
+ );
507
+ await this.stateStore.record(baseResult.customerKey, baseResult, baseAliases);
508
+ return baseResult;
509
+ }
496
510
  if (!readyState?.hasOnlineResume) {
497
511
  throw new Error('ONLINE_RESUME_UNAVAILABLE');
498
512
  }
@@ -718,6 +718,12 @@ function browserConversationReadyState() {
718
718
  const rect = el.getBoundingClientRect();
719
719
  return rect.width > 2 && rect.height > 2;
720
720
  };
721
+ const isDisabled = (el) => {
722
+ const classText = String(el?.className || '').toLowerCase();
723
+ const ariaDisabled = String(el?.getAttribute?.('aria-disabled') || '').toLowerCase() === 'true';
724
+ const disabledAttr = Boolean(el?.hasAttribute?.('disabled'));
725
+ return classText.includes('disabled') || ariaDisabled || disabledAttr;
726
+ };
721
727
  const onlineResume = Array.from(
722
728
  document.querySelectorAll(
723
729
  'a.btn.resume-btn-online, a.resume-btn-online, .resume-btn-online, .btn.resume-btn-online',
@@ -725,18 +731,29 @@ function browserConversationReadyState() {
725
731
  ).find((el) => {
726
732
  if (!isVisible(el)) return false;
727
733
  if (!normalize(el.textContent || '').includes('在线简历')) return false;
734
+ return !isDisabled(el);
735
+ });
736
+ const attachmentResume = Array.from(
737
+ document.querySelectorAll(
738
+ '.btn.resume-btn-file, .resume-btn-file, [class*="resume-btn-file"], button, a, div, span',
739
+ ),
740
+ ).find((el) => {
741
+ if (!isVisible(el)) return false;
742
+ if (!normalize(el.textContent || '').includes('附件简历')) return false;
728
743
  const classText = String(el.className || '').toLowerCase();
729
- const ariaDisabled = String(el.getAttribute('aria-disabled') || '').toLowerCase() === 'true';
730
- const disabledAttr = el.hasAttribute('disabled');
731
- return !classText.includes('disabled') && !ariaDisabled && !disabledAttr;
744
+ return classText.includes('resume-btn-file') || classText.includes('resume') || classText.includes('btn');
732
745
  });
733
746
  const askResume = Array.from(document.querySelectorAll('span.operate-btn, button, a, span')).find(
734
747
  (el) => isVisible(el) && isAskResumeText(el.textContent || ''),
735
748
  );
749
+ const attachmentResumeEnabled = Boolean(attachmentResume) && !isDisabled(attachmentResume);
736
750
  return {
737
751
  hasOnlineResume: Boolean(onlineResume),
738
752
  hasAskResume: Boolean(askResume),
739
753
  onlineResumeClass: String(onlineResume?.className || ''),
754
+ hasAttachmentResume: Boolean(attachmentResume),
755
+ attachmentResumeEnabled,
756
+ attachmentResumeClass: String(attachmentResume?.className || ''),
740
757
  };
741
758
  }
742
759
 
@@ -2180,7 +2197,7 @@ export class BossChatPage {
2180
2197
 
2181
2198
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
2182
2199
  const state = await this.chromeClient.callFunction(browserConversationReadyState);
2183
- if (state?.hasOnlineResume || state?.hasAskResume) {
2200
+ if (state?.hasOnlineResume || state?.hasAskResume || state?.hasAttachmentResume) {
2184
2201
  return state;
2185
2202
  }
2186
2203
  await new Promise((resolve) => setTimeout(resolve, delayMs));