@reconcrap/boss-recommend-mcp 2.1.21 → 2.1.22
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/README.md +5 -2
- package/bin/boss-recommend-mcp.js +4 -4
- package/config/screening-config.example.json +33 -33
- package/package.json +8 -8
- package/scripts/install-macos.sh +280 -280
- package/scripts/postinstall.cjs +44 -44
- package/skills/boss-chat/README.md +42 -42
- package/skills/boss-chat/SKILL.md +106 -106
- package/skills/boss-recommend-pipeline/README.md +13 -13
- package/skills/boss-recommend-pipeline/SKILL.md +219 -214
- package/skills/boss-recruit-pipeline/README.md +19 -19
- package/skills/boss-recruit-pipeline/SKILL.md +89 -89
- package/src/chat-mcp.js +127 -127
- package/src/chat-runtime-config.js +775 -775
- package/src/cli.js +573 -573
- package/src/core/boss-cards/index.js +199 -199
- package/src/core/browser/index.js +2419 -2415
- package/src/core/capture/index.js +1201 -1201
- package/src/core/cv-acquisition/index.js +238 -238
- package/src/core/cv-capture-target/index.js +299 -299
- package/src/core/greet-quota/index.js +71 -71
- package/src/core/infinite-list/index.js +1326 -1326
- package/src/core/reporting/legacy-csv.js +334 -332
- package/src/core/run/index.js +32 -32
- package/src/core/run/timing.js +33 -33
- package/src/core/screening/index.js +2135 -2135
- package/src/core/self-heal/index.js +973 -973
- package/src/core/self-heal/viewport.js +564 -564
- package/src/detached-worker.js +99 -99
- package/src/domains/chat/cards.js +137 -137
- package/src/domains/chat/constants.js +9 -9
- package/src/domains/chat/detail.js +113 -113
- package/src/domains/chat/index.js +7 -7
- package/src/domains/chat/jobs.js +620 -620
- package/src/domains/chat/page-guard.js +122 -122
- package/src/domains/chat/roots.js +56 -56
- package/src/domains/chat/run-service.js +571 -571
- package/src/domains/common/account-rights-panel.js +314 -314
- package/src/domains/common/recovery-settle.js +159 -159
- package/src/domains/recommend/actions.js +472 -472
- package/src/domains/recommend/cards.js +243 -243
- package/src/domains/recommend/colleague-contact.js +333 -333
- package/src/domains/recommend/constants.js +228 -159
- package/src/domains/recommend/detail.js +650 -650
- package/src/domains/recommend/filters.js +748 -377
- package/src/domains/recommend/index.js +4 -3
- package/src/domains/recommend/jobs.js +542 -542
- package/src/domains/recommend/location.js +736 -0
- package/src/domains/recommend/refresh.js +504 -361
- package/src/domains/recommend/roots.js +80 -80
- package/src/domains/recommend/run-service.js +987 -854
- package/src/domains/recommend/scopes.js +246 -246
- package/src/domains/recruit/actions.js +277 -277
- package/src/domains/recruit/cards.js +74 -74
- package/src/domains/recruit/constants.js +236 -236
- package/src/domains/recruit/detail.js +588 -588
- package/src/domains/recruit/index.js +9 -9
- package/src/domains/recruit/instruction-parser.js +866 -866
- package/src/domains/recruit/refresh.js +45 -45
- package/src/domains/recruit/roots.js +68 -68
- package/src/domains/recruit/run-service.js +1620 -1620
- package/src/domains/recruit/search.js +3229 -3229
- package/src/index.js +13 -0
- package/src/parser.js +376 -8
- package/src/recommend-mcp.js +929 -915
- package/src/recommend-scheduler.js +496 -496
- package/src/recruit-mcp.js +2121 -2121
|
@@ -12,17 +12,17 @@ import {
|
|
|
12
12
|
querySelectorAll,
|
|
13
13
|
sleep
|
|
14
14
|
} from "../../core/browser/index.js";
|
|
15
|
-
import {
|
|
16
|
-
buildScreeningCandidateFromDetail,
|
|
17
|
-
htmlToText
|
|
18
|
-
} from "../../core/screening/index.js";
|
|
19
|
-
import {
|
|
20
|
-
closeBossAccountRightsBlockingPanel,
|
|
21
|
-
findBossAccountRightsBlockingPanel
|
|
22
|
-
} from "../common/account-rights-panel.js";
|
|
23
|
-
import {
|
|
24
|
-
CHAT_ACTIVE_CANDIDATE_SELECTORS,
|
|
25
|
-
CHAT_ASK_RESUME_BUTTON_SELECTORS,
|
|
15
|
+
import {
|
|
16
|
+
buildScreeningCandidateFromDetail,
|
|
17
|
+
htmlToText
|
|
18
|
+
} from "../../core/screening/index.js";
|
|
19
|
+
import {
|
|
20
|
+
closeBossAccountRightsBlockingPanel,
|
|
21
|
+
findBossAccountRightsBlockingPanel
|
|
22
|
+
} from "../common/account-rights-panel.js";
|
|
23
|
+
import {
|
|
24
|
+
CHAT_ACTIVE_CANDIDATE_SELECTORS,
|
|
25
|
+
CHAT_ASK_RESUME_BUTTON_SELECTORS,
|
|
26
26
|
CHAT_ATTACHMENT_RESUME_BUTTON_SELECTORS,
|
|
27
27
|
CHAT_BLOCKING_PANEL_CLOSE_SELECTORS,
|
|
28
28
|
CHAT_BLOCKING_PANEL_TEXT_QUERIES,
|
|
@@ -51,8 +51,8 @@ import {
|
|
|
51
51
|
makeForbiddenChatResumeNavigationError
|
|
52
52
|
} from "./page-guard.js";
|
|
53
53
|
|
|
54
|
-
export const CHAT_UNSAFE_ONLINE_RESUME_LINK_CODE = "CHAT_UNSAFE_ONLINE_RESUME_LINK";
|
|
55
|
-
export const CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE = "CHAT_ONLINE_RESUME_MODAL_NOT_OPEN";
|
|
54
|
+
export const CHAT_UNSAFE_ONLINE_RESUME_LINK_CODE = "CHAT_UNSAFE_ONLINE_RESUME_LINK";
|
|
55
|
+
export const CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE = "CHAT_ONLINE_RESUME_MODAL_NOT_OPEN";
|
|
56
56
|
|
|
57
57
|
const CHAT_CONVERSATION_CONTROL_SCOPE_SELECTORS = Object.freeze([
|
|
58
58
|
".conversation-main",
|
|
@@ -129,15 +129,15 @@ export function makeUnsafeChatOnlineResumeLinkError(target = {}, buttonHTML = ""
|
|
|
129
129
|
return error;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
export function isUnsafeChatOnlineResumeLinkError(error) {
|
|
133
|
-
return error?.code === CHAT_UNSAFE_ONLINE_RESUME_LINK_CODE
|
|
134
|
-
|| /CHAT_UNSAFE_ONLINE_RESUME_LINK/i.test(String(error?.message || error || ""));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export function isChatOnlineResumeModalOpenFailureError(error) {
|
|
138
|
-
return error?.code === CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE
|
|
139
|
-
|| /Chat online resume modal did not open/i.test(String(error?.message || error || ""));
|
|
140
|
-
}
|
|
132
|
+
export function isUnsafeChatOnlineResumeLinkError(error) {
|
|
133
|
+
return error?.code === CHAT_UNSAFE_ONLINE_RESUME_LINK_CODE
|
|
134
|
+
|| /CHAT_UNSAFE_ONLINE_RESUME_LINK/i.test(String(error?.message || error || ""));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function isChatOnlineResumeModalOpenFailureError(error) {
|
|
138
|
+
return error?.code === CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE
|
|
139
|
+
|| /Chat online resume modal did not open/i.test(String(error?.message || error || ""));
|
|
140
|
+
}
|
|
141
141
|
|
|
142
142
|
export function createChatProfileNetworkRecorder(client) {
|
|
143
143
|
const events = [];
|
|
@@ -248,9 +248,9 @@ function chatCandidateIdFromAttributes(attributes = {}) {
|
|
|
248
248
|
);
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
async function hydrateActiveChatCandidate(client, activeCandidate = null) {
|
|
252
|
-
if (!activeCandidate?.node_id) return activeCandidate;
|
|
253
|
-
let attributes = {};
|
|
251
|
+
async function hydrateActiveChatCandidate(client, activeCandidate = null) {
|
|
252
|
+
if (!activeCandidate?.node_id) return activeCandidate;
|
|
253
|
+
let attributes = {};
|
|
254
254
|
let outerHTML = "";
|
|
255
255
|
try {
|
|
256
256
|
[attributes, outerHTML] = await Promise.all([
|
|
@@ -264,25 +264,25 @@ async function hydrateActiveChatCandidate(client, activeCandidate = null) {
|
|
|
264
264
|
candidate_id: chatCandidateIdFromAttributes(attributes) || null,
|
|
265
265
|
label: normalizeDetailText(htmlToText(outerHTML)),
|
|
266
266
|
outer_html_length: outerHTML.length
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
export async function readChatActiveCandidateState(client) {
|
|
271
|
-
const rootState = await getChatRoots(client);
|
|
272
|
-
const activeCandidate = await queryFirstAcrossChatRoots(
|
|
273
|
-
client,
|
|
274
|
-
rootState.roots,
|
|
275
|
-
CHAT_ACTIVE_CANDIDATE_SELECTORS
|
|
276
|
-
);
|
|
277
|
-
return {
|
|
278
|
-
roots: rootState.roots,
|
|
279
|
-
active_candidate: await hydrateActiveChatCandidate(client, activeCandidate)
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
export async function waitForChatOnlineResumeButton(client, {
|
|
284
|
-
timeoutMs = 12000,
|
|
285
|
-
intervalMs = 250,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export async function readChatActiveCandidateState(client) {
|
|
271
|
+
const rootState = await getChatRoots(client);
|
|
272
|
+
const activeCandidate = await queryFirstAcrossChatRoots(
|
|
273
|
+
client,
|
|
274
|
+
rootState.roots,
|
|
275
|
+
CHAT_ACTIVE_CANDIDATE_SELECTORS
|
|
276
|
+
);
|
|
277
|
+
return {
|
|
278
|
+
roots: rootState.roots,
|
|
279
|
+
active_candidate: await hydrateActiveChatCandidate(client, activeCandidate)
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export async function waitForChatOnlineResumeButton(client, {
|
|
284
|
+
timeoutMs = 12000,
|
|
285
|
+
intervalMs = 250,
|
|
286
286
|
expectedCandidateId = ""
|
|
287
287
|
} = {}) {
|
|
288
288
|
const started = Date.now();
|
|
@@ -758,29 +758,29 @@ export async function quickChatResumeModalOpenProbe(client, {
|
|
|
758
758
|
};
|
|
759
759
|
}
|
|
760
760
|
|
|
761
|
-
export async function findChatBlockingPanel(client, {
|
|
762
|
-
textQueries = CHAT_BLOCKING_PANEL_TEXT_QUERIES
|
|
763
|
-
} = {}) {
|
|
764
|
-
const panel = await findBossAccountRightsBlockingPanel(client, { textQueries });
|
|
765
|
-
return panel.open
|
|
766
|
-
? { ...panel, reason: "blocking_panel_text_visible" }
|
|
767
|
-
: panel;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
export async function closeChatBlockingPanels(client, {
|
|
771
|
-
attemptsLimit = 2,
|
|
772
|
-
closeSelectors = CHAT_BLOCKING_PANEL_CLOSE_SELECTORS,
|
|
773
|
-
textQueries = CHAT_BLOCKING_PANEL_TEXT_QUERIES
|
|
774
|
-
} = {}) {
|
|
775
|
-
return closeBossAccountRightsBlockingPanel(client, {
|
|
776
|
-
attemptsLimit,
|
|
777
|
-
closeSelectors,
|
|
778
|
-
resolveRoots: getChatRoots,
|
|
779
|
-
textQueries
|
|
780
|
-
});
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
export async function readChatResumeHtml(client, resumeState) {
|
|
761
|
+
export async function findChatBlockingPanel(client, {
|
|
762
|
+
textQueries = CHAT_BLOCKING_PANEL_TEXT_QUERIES
|
|
763
|
+
} = {}) {
|
|
764
|
+
const panel = await findBossAccountRightsBlockingPanel(client, { textQueries });
|
|
765
|
+
return panel.open
|
|
766
|
+
? { ...panel, reason: "blocking_panel_text_visible" }
|
|
767
|
+
: panel;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
export async function closeChatBlockingPanels(client, {
|
|
771
|
+
attemptsLimit = 2,
|
|
772
|
+
closeSelectors = CHAT_BLOCKING_PANEL_CLOSE_SELECTORS,
|
|
773
|
+
textQueries = CHAT_BLOCKING_PANEL_TEXT_QUERIES
|
|
774
|
+
} = {}) {
|
|
775
|
+
return closeBossAccountRightsBlockingPanel(client, {
|
|
776
|
+
attemptsLimit,
|
|
777
|
+
closeSelectors,
|
|
778
|
+
resolveRoots: getChatRoots,
|
|
779
|
+
textQueries
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
export async function readChatResumeHtml(client, resumeState) {
|
|
784
784
|
let popupHTML = "";
|
|
785
785
|
let contentHTML = "";
|
|
786
786
|
let resumeIframeHTML = "";
|
|
@@ -1001,12 +1001,12 @@ export async function openChatOnlineResume(client, {
|
|
|
1001
1001
|
}
|
|
1002
1002
|
}
|
|
1003
1003
|
|
|
1004
|
-
const error = new Error("Chat online resume modal did not open");
|
|
1005
|
-
error.code = CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE;
|
|
1006
|
-
error.retryable = true;
|
|
1007
|
-
error.attempts = attempts;
|
|
1008
|
-
throw error;
|
|
1009
|
-
}
|
|
1004
|
+
const error = new Error("Chat online resume modal did not open");
|
|
1005
|
+
error.code = CHAT_ONLINE_RESUME_MODAL_NOT_OPEN_CODE;
|
|
1006
|
+
error.retryable = true;
|
|
1007
|
+
error.attempts = attempts;
|
|
1008
|
+
throw error;
|
|
1009
|
+
}
|
|
1010
1010
|
|
|
1011
1011
|
export async function readChatConversationReadyState(client) {
|
|
1012
1012
|
const rootState = await getChatRoots(client);
|
|
@@ -1194,21 +1194,21 @@ export async function sendChatMessage(client, expectedText = "", {
|
|
|
1194
1194
|
};
|
|
1195
1195
|
}
|
|
1196
1196
|
|
|
1197
|
-
export async function clickChatAskResume(client, {
|
|
1198
|
-
timeoutMs = 8000,
|
|
1199
|
-
settleMs = 700,
|
|
1200
|
-
skipWhenAttachmentResumeAvailable = true
|
|
1201
|
-
} = {}) {
|
|
1197
|
+
export async function clickChatAskResume(client, {
|
|
1198
|
+
timeoutMs = 8000,
|
|
1199
|
+
settleMs = 700,
|
|
1200
|
+
skipWhenAttachmentResumeAvailable = true
|
|
1201
|
+
} = {}) {
|
|
1202
1202
|
const started = Date.now();
|
|
1203
1203
|
let lastState = null;
|
|
1204
1204
|
let lastDisabledAskResume = null;
|
|
1205
1205
|
while (Date.now() - started <= timeoutMs) {
|
|
1206
1206
|
const state = await readChatConversationReadyState(client);
|
|
1207
1207
|
lastState = state;
|
|
1208
|
-
if (skipWhenAttachmentResumeAvailable && state.attachment_resume_enabled) {
|
|
1209
|
-
return {
|
|
1210
|
-
ok: true,
|
|
1211
|
-
already_requested: true,
|
|
1208
|
+
if (skipWhenAttachmentResumeAvailable && state.attachment_resume_enabled) {
|
|
1209
|
+
return {
|
|
1210
|
+
ok: true,
|
|
1211
|
+
already_requested: true,
|
|
1212
1212
|
attachment_resume_available: true,
|
|
1213
1213
|
control: state.attachment_resume
|
|
1214
1214
|
};
|
|
@@ -1390,32 +1390,32 @@ export async function waitForChatResumeRequestMessage(client, {
|
|
|
1390
1390
|
};
|
|
1391
1391
|
}
|
|
1392
1392
|
|
|
1393
|
-
export async function requestChatResumeForPassedCandidate(client, {
|
|
1394
|
-
greetingText = "Hi同学,能麻烦发下简历吗?",
|
|
1395
|
-
maxAttempts = 3,
|
|
1396
|
-
askResumeTimeoutMs = 8000,
|
|
1397
|
-
dryRun = false,
|
|
1398
|
-
skipWhenAttachmentResumeAvailable = true
|
|
1399
|
-
} = {}) {
|
|
1400
|
-
const effectiveGreetingText = normalizeDetailText(greetingText) || "Hi同学,能麻烦发下简历吗?";
|
|
1401
|
-
const initialState = await readChatConversationReadyState(client);
|
|
1402
|
-
if (skipWhenAttachmentResumeAvailable && initialState.attachment_resume_enabled) {
|
|
1403
|
-
return {
|
|
1404
|
-
requested: false,
|
|
1405
|
-
skipped: true,
|
|
1406
|
-
reason: "attachment_resume_already_available",
|
|
1407
|
-
initial_state: initialState
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
if (initialState.already_requested_resume) {
|
|
1411
|
-
return {
|
|
1412
|
-
requested: false,
|
|
1413
|
-
skipped: true,
|
|
1414
|
-
reason: "resume_request_already_pending",
|
|
1415
|
-
initial_state: initialState
|
|
1416
|
-
};
|
|
1417
|
-
}
|
|
1418
|
-
if (dryRun) {
|
|
1393
|
+
export async function requestChatResumeForPassedCandidate(client, {
|
|
1394
|
+
greetingText = "Hi同学,能麻烦发下简历吗?",
|
|
1395
|
+
maxAttempts = 3,
|
|
1396
|
+
askResumeTimeoutMs = 8000,
|
|
1397
|
+
dryRun = false,
|
|
1398
|
+
skipWhenAttachmentResumeAvailable = true
|
|
1399
|
+
} = {}) {
|
|
1400
|
+
const effectiveGreetingText = normalizeDetailText(greetingText) || "Hi同学,能麻烦发下简历吗?";
|
|
1401
|
+
const initialState = await readChatConversationReadyState(client);
|
|
1402
|
+
if (skipWhenAttachmentResumeAvailable && initialState.attachment_resume_enabled) {
|
|
1403
|
+
return {
|
|
1404
|
+
requested: false,
|
|
1405
|
+
skipped: true,
|
|
1406
|
+
reason: "attachment_resume_already_available",
|
|
1407
|
+
initial_state: initialState
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1410
|
+
if (initialState.already_requested_resume) {
|
|
1411
|
+
return {
|
|
1412
|
+
requested: false,
|
|
1413
|
+
skipped: true,
|
|
1414
|
+
reason: "resume_request_already_pending",
|
|
1415
|
+
initial_state: initialState
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
if (dryRun) {
|
|
1419
1419
|
return {
|
|
1420
1420
|
requested: false,
|
|
1421
1421
|
skipped: false,
|
|
@@ -1447,11 +1447,11 @@ export async function requestChatResumeForPassedCandidate(client, {
|
|
|
1447
1447
|
|
|
1448
1448
|
const attempts = [];
|
|
1449
1449
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
1450
|
-
const before = await getChatResumeRequestMessageState(client);
|
|
1451
|
-
const askResult = await clickChatAskResume(client, {
|
|
1452
|
-
timeoutMs: askResumeTimeoutMs,
|
|
1453
|
-
skipWhenAttachmentResumeAvailable
|
|
1454
|
-
});
|
|
1450
|
+
const before = await getChatResumeRequestMessageState(client);
|
|
1451
|
+
const askResult = await clickChatAskResume(client, {
|
|
1452
|
+
timeoutMs: askResumeTimeoutMs,
|
|
1453
|
+
skipWhenAttachmentResumeAvailable
|
|
1454
|
+
});
|
|
1455
1455
|
let confirmResult = {
|
|
1456
1456
|
confirmed: false,
|
|
1457
1457
|
assumed_requested: Boolean(askResult.already_requested),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from "./constants.js";
|
|
2
|
-
export * from "./roots.js";
|
|
3
|
-
export * from "./cards.js";
|
|
4
|
-
export * from "./jobs.js";
|
|
5
|
-
export * from "./page-guard.js";
|
|
6
|
-
export * from "./detail.js";
|
|
7
|
-
export * from "./run-service.js";
|
|
1
|
+
export * from "./constants.js";
|
|
2
|
+
export * from "./roots.js";
|
|
3
|
+
export * from "./cards.js";
|
|
4
|
+
export * from "./jobs.js";
|
|
5
|
+
export * from "./page-guard.js";
|
|
6
|
+
export * from "./detail.js";
|
|
7
|
+
export * from "./run-service.js";
|