@reconcrap/boss-recommend-mcp 1.0.7 → 1.0.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reconcrap/boss-recommend-mcp",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Unified MCP pipeline for recommend-page filtering and screening on Boss Zhipin",
5
5
  "keywords": [
6
6
  "boss",
@@ -27,6 +27,7 @@ description: "Use when users ask to run Boss recommend-page filtering and screen
27
27
  - 当用户请求中出现 “recommend / 推荐页 / boss recommend / recommend page” 语义时,只能走 `boss-recommend-pipeline`
28
28
  - 当用户请求中出现 “search / 搜索页 / boss search / search page” 语义时,不能走本技能,必须转交 `boss-recruit-pipeline` 并调用 `run_recruit_pipeline`
29
29
  - 不要调用 `boss-recruit-pipeline`,也不要调用 `run_recruit_pipeline`,除非上一条(search/搜索页语义)命中
30
+ - 当 recommend 流程返回任何错误(包括 `JOB_TRIGGER_NOT_FOUND` / `NO_RECOMMEND_IFRAME` / `BOSS_LOGIN_REQUIRED`)时,禁止把 recommend 请求降级到 recruit 流程;必须先修复 recommend 的页面就绪或登录态问题
30
31
 
31
32
  路由示例(中英文都要兼容):
32
33
 
package/src/pipeline.js CHANGED
@@ -534,6 +534,54 @@ export async function runRecommendPipeline(
534
534
  port: preflight.debug_port
535
535
  });
536
536
  if (!jobListResult.ok) {
537
+ const jobListErrorCode = String(jobListResult.error?.code || "");
538
+ const jobListErrorMessage = String(jobListResult.error?.message || "");
539
+ const pageReadinessFailure = (
540
+ jobListErrorCode === "JOB_TRIGGER_NOT_FOUND"
541
+ || jobListErrorCode === "NO_RECOMMEND_IFRAME"
542
+ || jobListErrorCode === "LOGIN_REQUIRED"
543
+ || jobListErrorMessage.includes("JOB_TRIGGER_NOT_FOUND")
544
+ || jobListErrorMessage.includes("NO_RECOMMEND_IFRAME")
545
+ || jobListErrorMessage.includes("LOGIN_REQUIRED")
546
+ );
547
+ if (pageReadinessFailure) {
548
+ const recheck = await ensureRecommendPageReady(workspaceRoot, {
549
+ port: preflight.debug_port
550
+ });
551
+ const loginRelated = new Set(["LOGIN_REQUIRED", "LOGIN_REQUIRED_AFTER_REDIRECT"]);
552
+ const connectivityRelated = new Set(["DEBUG_PORT_UNREACHABLE"]);
553
+ const guidance = buildChromeSetupGuidance({
554
+ debugPort: preflight.debug_port,
555
+ pageState: recheck.page_state
556
+ });
557
+ if (!recheck.ok || loginRelated.has(recheck.state) || connectivityRelated.has(recheck.state)) {
558
+ return buildFailedResponse(
559
+ connectivityRelated.has(recheck.state)
560
+ ? "BOSS_CHROME_NOT_CONNECTED"
561
+ : loginRelated.has(recheck.state)
562
+ ? "BOSS_LOGIN_REQUIRED"
563
+ : "BOSS_RECOMMEND_PAGE_NOT_READY",
564
+ loginRelated.has(recheck.state)
565
+ ? `检测到当前 Boss 处于未登录状态,请先登录后再继续。登录页:https://www.zhipin.com/web/user/?ka=bticket`
566
+ : connectivityRelated.has(recheck.state)
567
+ ? `读取岗位列表前需要先连接到端口 ${preflight.debug_port} 的 Chrome 远程调试实例。`
568
+ : `读取岗位列表前,请先在端口 ${preflight.debug_port} 的 Chrome 停留在 Boss recommend 页面。`,
569
+ {
570
+ search_params: parsed.searchParams,
571
+ screen_params: parsed.screenParams,
572
+ required_user_action: "prepare_boss_recommend_page",
573
+ guidance,
574
+ diagnostics: {
575
+ debug_port: preflight.debug_port,
576
+ page_state: recheck.page_state,
577
+ stdout: jobListResult.stdout?.slice(-1000),
578
+ stderr: jobListResult.stderr?.slice(-1000),
579
+ result: jobListResult.structured || null
580
+ }
581
+ }
582
+ );
583
+ }
584
+ }
537
585
  return buildFailedResponse(
538
586
  jobListResult.error?.code || "RECOMMEND_JOB_LIST_FAILED",
539
587
  jobListResult.error?.message || "读取推荐岗位列表失败,无法开始筛选。",
@@ -344,6 +344,50 @@ async function testSearchNoIframeWithLoginShouldReturnLoginRequired() {
344
344
  assert.equal(result.guidance.agent_prompt.includes("https://www.zhipin.com/web/user/?ka=bticket"), true);
345
345
  }
346
346
 
347
+ async function testJobTriggerNotFoundShouldMapToLoginRequiredWhenRecheckShowsLogin() {
348
+ const result = await runRecommendPipeline(
349
+ {
350
+ workspaceRoot: process.cwd(),
351
+ instruction: "test",
352
+ confirmation: {},
353
+ overrides: {}
354
+ },
355
+ {
356
+ parseRecommendInstruction: () => createParsed(),
357
+ runPipelinePreflight: () => ({ ok: true, checks: [], debug_port: 9222 }),
358
+ ensureBossRecommendPageReady: async () => ({
359
+ ok: false,
360
+ debug_port: 9222,
361
+ state: "LOGIN_REQUIRED",
362
+ page_state: {
363
+ state: "LOGIN_REQUIRED",
364
+ expected_url: "https://www.zhipin.com/web/chat/recommend",
365
+ current_url: "https://www.zhipin.com/web/user/?ka=bticket",
366
+ login_url: "https://www.zhipin.com/web/user/?ka=bticket"
367
+ }
368
+ }),
369
+ listRecommendJobs: async () => ({
370
+ ok: false,
371
+ stdout: "",
372
+ stderr: "",
373
+ structured: null,
374
+ jobs: [],
375
+ error: {
376
+ code: "JOB_TRIGGER_NOT_FOUND",
377
+ message: "JOB_TRIGGER_NOT_FOUND"
378
+ }
379
+ }),
380
+ runRecommendSearchCli: async () => ({ ok: true, summary: {} }),
381
+ runRecommendScreenCli: async () => ({ ok: true, summary: {} })
382
+ }
383
+ );
384
+
385
+ assert.equal(result.status, "FAILED");
386
+ assert.equal(result.error.code, "BOSS_LOGIN_REQUIRED");
387
+ assert.equal(result.required_user_action, "prepare_boss_recommend_page");
388
+ assert.equal(result.guidance.agent_prompt.includes("https://www.zhipin.com/web/user/?ka=bticket"), true);
389
+ }
390
+
347
391
  async function testNeedJobConfirmationGate() {
348
392
  const result = await runRecommendPipeline(
349
393
  {
@@ -721,6 +765,7 @@ async function main() {
721
765
  await testCompletedPipeline();
722
766
  await testSearchFailure();
723
767
  await testSearchNoIframeWithLoginShouldReturnLoginRequired();
768
+ await testJobTriggerNotFoundShouldMapToLoginRequiredWhenRecheckShowsLogin();
724
769
  await testLoginRequiredShouldReturnGuidance();
725
770
  await testDebugPortUnreachableShouldReturnConnectionCode();
726
771
  await testPreflightRecoveryPlanOrder();