@joohw/boss-cli 0.4.0 → 0.5.0
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 +170 -172
- package/dist/browser/agent_operating_indicator.js +51 -51
- package/dist/browser/human_delay.d.ts +2 -0
- package/dist/browser/human_delay.d.ts.map +1 -1
- package/dist/browser/human_delay.js +4 -0
- package/dist/browser/human_delay.js.map +1 -1
- package/dist/cli/cliRouter.d.ts.map +1 -1
- package/dist/cli/cliRouter.js +56 -43
- package/dist/cli/cliRouter.js.map +1 -1
- package/dist/cli/version.d.ts +22 -0
- package/dist/cli/version.d.ts.map +1 -1
- package/dist/cli/version.js +127 -6
- package/dist/cli/version.js.map +1 -1
- package/dist/common/auth.js +49 -49
- package/dist/common/boss_paywall_popup.js +87 -87
- package/dist/common/boss_session_lock.d.ts.map +1 -1
- package/dist/common/boss_session_lock.js +7 -1
- package/dist/common/boss_session_lock.js.map +1 -1
- package/dist/common/boss_session_page.d.ts +2 -2
- package/dist/common/boss_session_page.d.ts.map +1 -1
- package/dist/common/boss_session_page.js +18 -29
- package/dist/common/boss_session_page.js.map +1 -1
- package/dist/common/boss_sidebar_nav.js +25 -26
- package/dist/common/boss_sidebar_nav.js.map +1 -1
- package/dist/common/c_resume_capture.d.ts +1 -0
- package/dist/common/c_resume_capture.d.ts.map +1 -1
- package/dist/common/c_resume_capture.js +69 -32
- package/dist/common/c_resume_capture.js.map +1 -1
- package/dist/ocr/resume_ocr.d.ts.map +1 -1
- package/dist/ocr/resume_ocr.js +4 -1
- package/dist/ocr/resume_ocr.js.map +1 -1
- package/dist/toolset/action.d.ts.map +1 -1
- package/dist/toolset/action.js +11 -7
- package/dist/toolset/action.js.map +1 -1
- package/dist/toolset/chat.d.ts.map +1 -1
- package/dist/toolset/chat.js +246 -230
- package/dist/toolset/chat.js.map +1 -1
- package/dist/toolset/deep-search.d.ts.map +1 -1
- package/dist/toolset/deep-search.js +289 -265
- package/dist/toolset/deep-search.js.map +1 -1
- package/dist/toolset/greet.d.ts.map +1 -1
- package/dist/toolset/greet.js +1 -6
- package/dist/toolset/greet.js.map +1 -1
- package/dist/toolset/jd.d.ts.map +1 -1
- package/dist/toolset/jd.js +132 -136
- package/dist/toolset/jd.js.map +1 -1
- package/dist/toolset/list.d.ts.map +1 -1
- package/dist/toolset/list.js +52 -45
- package/dist/toolset/list.js.map +1 -1
- package/dist/toolset/preview.d.ts.map +1 -1
- package/dist/toolset/preview.js +6 -8
- package/dist/toolset/preview.js.map +1 -1
- package/dist/toolset/recommend.d.ts.map +1 -1
- package/dist/toolset/recommend.js +222 -196
- package/dist/toolset/recommend.js.map +1 -1
- package/dist/toolset/send.d.ts.map +1 -1
- package/dist/toolset/send.js +6 -9
- package/dist/toolset/send.js.map +1 -1
- package/package.json +65 -65
- package/dist/browser/auth.d.ts +0 -33
- package/dist/browser/auth.d.ts.map +0 -1
- package/dist/browser/auth.js +0 -137
- package/dist/browser/auth.js.map +0 -1
- package/dist/browser/c_resume_capture.d.ts +0 -11
- package/dist/browser/c_resume_capture.d.ts.map +0 -1
- package/dist/browser/c_resume_capture.js +0 -76
- package/dist/browser/c_resume_capture.js.map +0 -1
- package/dist/browser/chat.d.ts +0 -7
- package/dist/browser/chat.d.ts.map +0 -1
- package/dist/browser/chat.js +0 -155
- package/dist/browser/chat.js.map +0 -1
- package/dist/browser/withLoggedInPage.d.ts +0 -7
- package/dist/browser/withLoggedInPage.d.ts.map +0 -1
- package/dist/browser/withLoggedInPage.js +0 -19
- package/dist/browser/withLoggedInPage.js.map +0 -1
- package/dist/facebook-cli/index.d.ts +0 -2
- package/dist/facebook-cli/index.d.ts.map +0 -1
- package/dist/facebook-cli/index.js +0 -2
- package/dist/facebook-cli/index.js.map +0 -1
- package/dist/toolset/c_resume_capture.d.ts +0 -11
- package/dist/toolset/c_resume_capture.d.ts.map +0 -1
- package/dist/toolset/c_resume_capture.js +0 -76
- package/dist/toolset/c_resume_capture.js.map +0 -1
- package/dist/toolset/chat_action.d.ts +0 -7
- package/dist/toolset/chat_action.d.ts.map +0 -1
- package/dist/toolset/chat_action.js +0 -355
- package/dist/toolset/chat_action.js.map +0 -1
- package/dist/toolset/list_candidates.d.ts +0 -4
- package/dist/toolset/list_candidates.d.ts.map +0 -1
- package/dist/toolset/list_candidates.js +0 -120
- package/dist/toolset/list_candidates.js.map +0 -1
- package/dist/toolset/list_positions.d.ts +0 -9
- package/dist/toolset/list_positions.d.ts.map +0 -1
- package/dist/toolset/list_positions.js +0 -41
- package/dist/toolset/list_positions.js.map +0 -1
- package/dist/toolset/open_chat.d.ts +0 -3
- package/dist/toolset/open_chat.d.ts.map +0 -1
- package/dist/toolset/open_chat.js +0 -423
- package/dist/toolset/open_chat.js.map +0 -1
- package/dist/toolset/recommend_greet.d.ts +0 -2
- package/dist/toolset/recommend_greet.d.ts.map +0 -1
- package/dist/toolset/recommend_greet.js +0 -27
- package/dist/toolset/recommend_greet.js.map +0 -1
- package/dist/toolset/search.d.ts +0 -24
- package/dist/toolset/search.d.ts.map +0 -1
- package/dist/toolset/search.js +0 -682
- package/dist/toolset/search.js.map +0 -1
- package/dist/toolset/send_message.d.ts +0 -12
- package/dist/toolset/send_message.d.ts.map +0 -1
- package/dist/toolset/send_message.js +0 -214
- package/dist/toolset/send_message.js.map +0 -1
- package/dist/toolset/skill.d.ts +0 -13
- package/dist/toolset/skill.d.ts.map +0 -1
- package/dist/toolset/skill.js +0 -85
- package/dist/toolset/skill.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@joohw/boss-cli",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Boss直聘自动化 CLI:批量发消息、自动打招呼、候选人管理、深度搜索。基于 Puppeteer/CDP 驱动本机 Chrome,支持 AI Agent 编排",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"boss",
|
|
7
|
-
"boss-cli",
|
|
8
|
-
"boss直聘",
|
|
9
|
-
"boss-zhipin",
|
|
10
|
-
"zhipin",
|
|
11
|
-
"bosszp",
|
|
12
|
-
"招聘自动化",
|
|
13
|
-
"hr-automation",
|
|
14
|
-
"recruitment-automation",
|
|
15
|
-
"puppeteer",
|
|
16
|
-
"cdp",
|
|
17
|
-
"chrome-devtools-protocol",
|
|
18
|
-
"cli",
|
|
19
|
-
"agent",
|
|
20
|
-
"ai-agent",
|
|
21
|
-
"自动打招呼",
|
|
22
|
-
"批量发消息",
|
|
23
|
-
"候选人管理",
|
|
24
|
-
"hr-tools",
|
|
25
|
-
"boss-direct"
|
|
26
|
-
],
|
|
27
|
-
"homepage": "https://
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/joohw/boss-cli.git"
|
|
31
|
-
},
|
|
32
|
-
"bugs": {
|
|
33
|
-
"url": "https://github.com/joohw/boss-cli/issues"
|
|
34
|
-
},
|
|
35
|
-
"type": "module",
|
|
36
|
-
"main": "dist/cli/index.js",
|
|
37
|
-
"types": "dist/cli/index.d.ts",
|
|
38
|
-
"bin": {
|
|
39
|
-
"boss": "dist/cli/index.js"
|
|
40
|
-
},
|
|
41
|
-
"files": [
|
|
42
|
-
"dist",
|
|
43
|
-
"skills",
|
|
44
|
-
"README.md",
|
|
45
|
-
"AGENTS.md",
|
|
46
|
-
"LICENSE"
|
|
47
|
-
],
|
|
48
|
-
"scripts": {
|
|
49
|
-
"build": "tsc",
|
|
50
|
-
"dev": "npm run build && node dist/cli/index.js",
|
|
51
|
-
"deploy": "node scripts/deploy.mjs",
|
|
52
|
-
"test:baidu": "node --env-file=.env scripts/test-baidu-ocr.mjs"
|
|
53
|
-
},
|
|
54
|
-
"dependencies": {
|
|
55
|
-
"dotenv": "^17.4.2",
|
|
56
|
-
"puppeteer-core": "^24.29.1"
|
|
57
|
-
},
|
|
58
|
-
"devDependencies": {
|
|
59
|
-
"@types/node": "^24.10.0",
|
|
60
|
-
"ssh2": "^1.17.0",
|
|
61
|
-
"typescript": "^5.3.3"
|
|
62
|
-
},
|
|
63
|
-
"author": "Joo <1546635571@qq.com>",
|
|
64
|
-
"license": "GPL-3.0"
|
|
65
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@joohw/boss-cli",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Boss直聘自动化 CLI:批量发消息、自动打招呼、候选人管理、深度搜索。基于 Puppeteer/CDP 驱动本机 Chrome,支持 AI Agent 编排",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"boss",
|
|
7
|
+
"boss-cli",
|
|
8
|
+
"boss直聘",
|
|
9
|
+
"boss-zhipin",
|
|
10
|
+
"zhipin",
|
|
11
|
+
"bosszp",
|
|
12
|
+
"招聘自动化",
|
|
13
|
+
"hr-automation",
|
|
14
|
+
"recruitment-automation",
|
|
15
|
+
"puppeteer",
|
|
16
|
+
"cdp",
|
|
17
|
+
"chrome-devtools-protocol",
|
|
18
|
+
"cli",
|
|
19
|
+
"agent",
|
|
20
|
+
"ai-agent",
|
|
21
|
+
"自动打招呼",
|
|
22
|
+
"批量发消息",
|
|
23
|
+
"候选人管理",
|
|
24
|
+
"hr-tools",
|
|
25
|
+
"boss-direct"
|
|
26
|
+
],
|
|
27
|
+
"homepage": "https://boss-cli.com",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/joohw/boss-cli.git"
|
|
31
|
+
},
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/joohw/boss-cli/issues"
|
|
34
|
+
},
|
|
35
|
+
"type": "module",
|
|
36
|
+
"main": "dist/cli/index.js",
|
|
37
|
+
"types": "dist/cli/index.d.ts",
|
|
38
|
+
"bin": {
|
|
39
|
+
"boss": "dist/cli/index.js"
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"dist",
|
|
43
|
+
"skills",
|
|
44
|
+
"README.md",
|
|
45
|
+
"AGENTS.md",
|
|
46
|
+
"LICENSE"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"dev": "npm run build && node dist/cli/index.js",
|
|
51
|
+
"deploy": "node scripts/deploy.mjs",
|
|
52
|
+
"test:baidu": "node --env-file=.env scripts/test-baidu-ocr.mjs"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"dotenv": "^17.4.2",
|
|
56
|
+
"puppeteer-core": "^24.29.1"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^24.10.0",
|
|
60
|
+
"ssh2": "^1.17.0",
|
|
61
|
+
"typescript": "^5.3.3"
|
|
62
|
+
},
|
|
63
|
+
"author": "Joo <1546635571@qq.com>",
|
|
64
|
+
"license": "GPL-3.0"
|
|
65
|
+
}
|
package/dist/browser/auth.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Page } from 'puppeteer-core';
|
|
2
|
-
/** Boss 直聘首页 */
|
|
3
|
-
export declare const BOSS_ZHIPIN_HOME = "https://www.zhipin.com/";
|
|
4
|
-
/** 默认落地页(杭州 SEO 首页);CLI 等未配置环境变量时使用 */
|
|
5
|
-
export declare const BOSS_DEFAULT_LANDING_URL = "https://www.zhipin.com/hangzhou/?seoRefer=index";
|
|
6
|
-
/** 沟通页(登录成功后的典型落地页之一) */
|
|
7
|
-
export declare const BOSS_CHAT_INDEX_URL = "https://www.zhipin.com/web/chat/index";
|
|
8
|
-
/** 尚未有可用的浏览器会话时的提示文本(供工具抛错复用)。 */
|
|
9
|
-
export declare function createWaitManualLoginRequiredText(action: string): string;
|
|
10
|
-
/** 当前 URL 是否为沟通页 `/web/chat/index`(允许带 query) */
|
|
11
|
-
export declare function isBossChatIndexUrl(url: string): boolean;
|
|
12
|
-
/** 未登录时常见跳转:如 `https://www.zhipin.com/web/user/?ka=bticket` */
|
|
13
|
-
export declare function isWebUserLoginUrl(url: string): boolean;
|
|
14
|
-
export type ProbeLoggedInSignals = {
|
|
15
|
-
hasNickname: boolean;
|
|
16
|
-
navLoginCta: boolean;
|
|
17
|
-
hasLogoutHint: boolean;
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* 根据当前页判断是否已登录(不导航)。
|
|
21
|
-
*
|
|
22
|
-
* **已登录(true)**:检测到顶栏昵称、或「退出登录」/logout 等信号。
|
|
23
|
-
* 会短轮询等待 SPA 渲染,避免 `goto` 后立即读静态 HTML 误判。
|
|
24
|
-
*
|
|
25
|
-
* **未登录(false)**:`/web/user/` 登录流 URL、顶栏出现「我要登录」入口、且轮询结束仍无昵称/退出类信号。
|
|
26
|
-
*/
|
|
27
|
-
export declare function probeLoggedInFromPage(page: Page): Promise<{
|
|
28
|
-
loggedIn: boolean;
|
|
29
|
-
url: string;
|
|
30
|
-
}>;
|
|
31
|
-
/** 沟通页且已登录(与 {@link probeLoggedInFromPage} 一致)。 */
|
|
32
|
-
export declare function probeBossChatIndexLoggedIn(page: Page): Promise<boolean>;
|
|
33
|
-
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAI3C,gBAAgB;AAChB,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAE1D,uCAAuC;AACvC,eAAO,MAAM,wBAAwB,oDACc,CAAC;AAEpD,yBAAyB;AACzB,eAAO,MAAM,mBAAmB,0CAA0C,CAAC;AAE3E,kCAAkC;AAClC,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAExE;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAWvD;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUtD;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AA6DF;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,GACT,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB7C;AAED,mDAAmD;AACnD,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAO7E"}
|
package/dist/browser/auth.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { sleepRandom } from './timing.js';
|
|
2
|
-
import { PROBE_LOGIN_POLL_MS } from './human_delay.js';
|
|
3
|
-
/** Boss 直聘首页 */
|
|
4
|
-
export const BOSS_ZHIPIN_HOME = 'https://www.zhipin.com/';
|
|
5
|
-
/** 默认落地页(杭州 SEO 首页);CLI 等未配置环境变量时使用 */
|
|
6
|
-
export const BOSS_DEFAULT_LANDING_URL = 'https://www.zhipin.com/hangzhou/?seoRefer=index';
|
|
7
|
-
/** 沟通页(登录成功后的典型落地页之一) */
|
|
8
|
-
export const BOSS_CHAT_INDEX_URL = 'https://www.zhipin.com/web/chat/index';
|
|
9
|
-
/** 尚未有可用的浏览器会话时的提示文本(供工具抛错复用)。 */
|
|
10
|
-
export function createWaitManualLoginRequiredText(action) {
|
|
11
|
-
return `浏览器尚未初始化,无法${action}。请先运行 boss login 并在浏览器中完成登录。`;
|
|
12
|
-
}
|
|
13
|
-
/** 当前 URL 是否为沟通页 `/web/chat/index`(允许带 query) */
|
|
14
|
-
export function isBossChatIndexUrl(url) {
|
|
15
|
-
try {
|
|
16
|
-
const u = new URL(url);
|
|
17
|
-
if (!u.hostname.includes('zhipin.com')) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
const p = u.pathname.replace(/\/+$/, '') || '/';
|
|
21
|
-
return p === '/web/chat/index';
|
|
22
|
-
}
|
|
23
|
-
catch {
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/** 未登录时常见跳转:如 `https://www.zhipin.com/web/user/?ka=bticket` */
|
|
28
|
-
export function isWebUserLoginUrl(url) {
|
|
29
|
-
try {
|
|
30
|
-
const u = new URL(url);
|
|
31
|
-
if (!u.hostname.includes('zhipin.com')) {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
return u.pathname.includes('/web/user/');
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* 必须在页面里执行的探测脚本(纯字符串)。
|
|
42
|
-
* `tsx`/esbuild 转译 `page.evaluate(() => { ... })` 时可能注入 `__name(...)`,序列化到浏览器后会报 `__name is not defined`。
|
|
43
|
-
*/
|
|
44
|
-
const PROBE_LOGGED_IN_SIGNALS_SCRIPT = `(() => {
|
|
45
|
-
function isNick(t) {
|
|
46
|
-
const s = t.replace(/\\s+/g, " ").trim();
|
|
47
|
-
if (s.length < 2 || s.length > 64) return false;
|
|
48
|
-
return !/^(我要登录|登录|注册|登录\\/注册)$/u.test(s);
|
|
49
|
-
}
|
|
50
|
-
var hasNickname = false;
|
|
51
|
-
var nickSelectors = [
|
|
52
|
-
".user-name",
|
|
53
|
-
"span.user-name",
|
|
54
|
-
"[class*='user-name']",
|
|
55
|
-
".label-name",
|
|
56
|
-
".nav-user .name",
|
|
57
|
-
".nav-user-name",
|
|
58
|
-
"a.nav-user",
|
|
59
|
-
".header-nav [class*='name']",
|
|
60
|
-
];
|
|
61
|
-
var si, i, els, el, t;
|
|
62
|
-
for (si = 0; si < nickSelectors.length; si++) {
|
|
63
|
-
els = document.querySelectorAll(nickSelectors[si]);
|
|
64
|
-
for (i = 0; i < els.length; i++) {
|
|
65
|
-
el = els[i];
|
|
66
|
-
t = (el.textContent || "").trim();
|
|
67
|
-
if (isNick(t)) {
|
|
68
|
-
hasNickname = true;
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (hasNickname) break;
|
|
73
|
-
}
|
|
74
|
-
var navRoots = [];
|
|
75
|
-
var navSels = ["header", ".nav-header", ".nav-wrap", ".top-header", "#header", ".header", ".navbar"];
|
|
76
|
-
var j, ne;
|
|
77
|
-
for (j = 0; j < navSels.length; j++) {
|
|
78
|
-
ne = document.querySelector(navSels[j]);
|
|
79
|
-
if (ne instanceof HTMLElement) navRoots.push(ne);
|
|
80
|
-
}
|
|
81
|
-
var navLoginCta = false;
|
|
82
|
-
for (i = 0; i < navRoots.length; i++) {
|
|
83
|
-
if (/\\b我要登录\\b/u.test(navRoots[i].innerText || "")) {
|
|
84
|
-
navLoginCta = true;
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
var bodyText = document.body instanceof HTMLElement ? document.body.innerText || "" : "";
|
|
89
|
-
var hasLogoutHint =
|
|
90
|
-
/\\b退出登录\\b/u.test(bodyText) ||
|
|
91
|
-
!!document.querySelector("a[href*='logout'], a[href*='signout'], [data-url*='logout']");
|
|
92
|
-
return { hasNickname: hasNickname, navLoginCta: navLoginCta, hasLogoutHint: hasLogoutHint };
|
|
93
|
-
})()`;
|
|
94
|
-
async function probeLoggedInSignals(page) {
|
|
95
|
-
return (await page.evaluate(PROBE_LOGGED_IN_SIGNALS_SCRIPT));
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* 根据当前页判断是否已登录(不导航)。
|
|
99
|
-
*
|
|
100
|
-
* **已登录(true)**:检测到顶栏昵称、或「退出登录」/logout 等信号。
|
|
101
|
-
* 会短轮询等待 SPA 渲染,避免 `goto` 后立即读静态 HTML 误判。
|
|
102
|
-
*
|
|
103
|
-
* **未登录(false)**:`/web/user/` 登录流 URL、顶栏出现「我要登录」入口、且轮询结束仍无昵称/退出类信号。
|
|
104
|
-
*/
|
|
105
|
-
export async function probeLoggedInFromPage(page) {
|
|
106
|
-
const url = page.url();
|
|
107
|
-
if (!url || url === 'about:blank') {
|
|
108
|
-
return { loggedIn: false, url: url || '' };
|
|
109
|
-
}
|
|
110
|
-
if (isWebUserLoginUrl(url)) {
|
|
111
|
-
return { loggedIn: false, url };
|
|
112
|
-
}
|
|
113
|
-
const maxAttempts = 25;
|
|
114
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
115
|
-
const s = await probeLoggedInSignals(page);
|
|
116
|
-
if (s.hasNickname || s.hasLogoutHint) {
|
|
117
|
-
return { loggedIn: true, url };
|
|
118
|
-
}
|
|
119
|
-
if (s.navLoginCta) {
|
|
120
|
-
return { loggedIn: false, url };
|
|
121
|
-
}
|
|
122
|
-
if (attempt < maxAttempts - 1) {
|
|
123
|
-
await sleepRandom(PROBE_LOGIN_POLL_MS.min, PROBE_LOGIN_POLL_MS.max);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return { loggedIn: false, url };
|
|
127
|
-
}
|
|
128
|
-
/** 沟通页且已登录(与 {@link probeLoggedInFromPage} 一致)。 */
|
|
129
|
-
export async function probeBossChatIndexLoggedIn(page) {
|
|
130
|
-
const url = page.url();
|
|
131
|
-
if (!isBossChatIndexUrl(url)) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
const { loggedIn } = await probeLoggedInFromPage(page);
|
|
135
|
-
return loggedIn;
|
|
136
|
-
}
|
|
137
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/browser/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Page } from 'puppeteer-core';
|
|
2
|
-
/** 截图文件名安全段(与 toolset/action 一致) */
|
|
3
|
-
export declare function safeResumeScreenshotFileBase(name: string): string;
|
|
4
|
-
/** 关闭含 `c-resume` iframe 的弹层(聊天「在线简历」与推荐「预览」共用)。 */
|
|
5
|
-
export declare function closeCResumePanel(page: Page): Promise<void>;
|
|
6
|
-
/**
|
|
7
|
-
* 在已出现 `c-resume` iframe 的页面上,对 iframe 整框截图并关闭弹层。
|
|
8
|
-
* `preOpenViewport` 为打开弹层前 `page.viewport()` 的快照(与在线简历截图一致)。
|
|
9
|
-
*/
|
|
10
|
-
export declare function captureCResumeIframeToFile(page: Page, preOpenViewport: Awaited<ReturnType<Page['viewport']>>, absPath: string): Promise<boolean>;
|
|
11
|
-
//# sourceMappingURL=c_resume_capture.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"c_resume_capture.d.ts","sourceRoot":"","sources":["../../src/browser/c_resume_capture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAI3C,oCAAoC;AACpC,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGjE;AAED,oDAAoD;AACpD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BjE;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,IAAI,EACV,eAAe,EAAE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EACtD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,OAAO,CAAC,CAmClB"}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { sleepRandom } from './timing.js';
|
|
2
|
-
import { resumeHeight, setTempHeight } from './viewport_temp.js';
|
|
3
|
-
/** 截图文件名安全段(与 toolset/action 一致) */
|
|
4
|
-
export function safeResumeScreenshotFileBase(name) {
|
|
5
|
-
const t = name.replace(/[/\\?%*:|"<>]/g, '_').trim().slice(0, 64);
|
|
6
|
-
return t.length > 0 ? t : 'candidate';
|
|
7
|
-
}
|
|
8
|
-
/** 关闭含 `c-resume` iframe 的弹层(聊天「在线简历」与推荐「预览」共用)。 */
|
|
9
|
-
export async function closeCResumePanel(page) {
|
|
10
|
-
try {
|
|
11
|
-
await page.evaluate(() => {
|
|
12
|
-
const wraps = Array.from(document.querySelectorAll('.boss-popup__wrapper'));
|
|
13
|
-
for (const w of wraps) {
|
|
14
|
-
if (w.querySelector('iframe[src*="c-resume"], iframe[src*="frame/c-resume"]')) {
|
|
15
|
-
const c = w.querySelector('.boss-popup__close');
|
|
16
|
-
if (c) {
|
|
17
|
-
c.click();
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
const iframe = document.querySelector('iframe[src*="c-resume"], iframe[src*="frame/c-resume"]');
|
|
23
|
-
let node = iframe?.parentElement ?? null;
|
|
24
|
-
for (let i = 0; i < 12 && node; i++) {
|
|
25
|
-
const c = node.querySelector('.boss-popup__close, .drawer-close, .icon-close');
|
|
26
|
-
if (c) {
|
|
27
|
-
c.click();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
node = node.parentElement;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
await sleepRandom(200, 450);
|
|
34
|
-
}
|
|
35
|
-
catch {
|
|
36
|
-
/* ignore */
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* 在已出现 `c-resume` iframe 的页面上,对 iframe 整框截图并关闭弹层。
|
|
41
|
-
* `preOpenViewport` 为打开弹层前 `page.viewport()` 的快照(与在线简历截图一致)。
|
|
42
|
-
*/
|
|
43
|
-
export async function captureCResumeIframeToFile(page, preOpenViewport, absPath) {
|
|
44
|
-
try {
|
|
45
|
-
await setTempHeight(page, preOpenViewport);
|
|
46
|
-
await sleepRandom(100, 320);
|
|
47
|
-
const iframe = await page.$('iframe[src*="c-resume"], iframe[src*="frame/c-resume"]');
|
|
48
|
-
if (!iframe) {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
await iframe.evaluate((el) => {
|
|
52
|
-
el.scrollIntoView({ block: 'start', inline: 'nearest' });
|
|
53
|
-
});
|
|
54
|
-
const box = await iframe.boundingBox();
|
|
55
|
-
if (!box) {
|
|
56
|
-
await iframe.dispose();
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
await iframe.screenshot({
|
|
61
|
-
path: absPath,
|
|
62
|
-
type: 'png',
|
|
63
|
-
captureBeyondViewport: true,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
finally {
|
|
67
|
-
await iframe.dispose();
|
|
68
|
-
}
|
|
69
|
-
await closeCResumePanel(page);
|
|
70
|
-
return true;
|
|
71
|
-
}
|
|
72
|
-
finally {
|
|
73
|
-
await resumeHeight(page, preOpenViewport);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
//# sourceMappingURL=c_resume_capture.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"c_resume_capture.js","sourceRoot":"","sources":["../../src/browser/c_resume_capture.ts"],"names":[],"mappings":"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"}
|
package/dist/browser/chat.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Page } from 'puppeteer-core';
|
|
2
|
-
/**
|
|
3
|
-
* 在已连接浏览器、且当前页为 Boss 已登录主壳(含侧栏 `.menu-list` 稳定)的前提下执行回调。
|
|
4
|
-
* 会先按 URL 确保落在沟通页 `/web/chat/index`,再校验侧栏;回调内可再导航到职位/推荐等业务路由。
|
|
5
|
-
*/
|
|
6
|
-
export declare function withBossSessionPage<T>(callback: (page: Page) => Promise<T>): Promise<T>;
|
|
7
|
-
//# sourceMappingURL=chat.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAmIpD;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAuD7F"}
|
package/dist/browser/chat.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { BOSS_CHAT_INDEX_URL, isBossChatIndexUrl } from './auth.js';
|
|
2
|
-
import { hideAgentOperatingIndicator, showAgentOperatingIndicator, } from './agent_operating_indicator.js';
|
|
3
|
-
import { ensureBrowserSession, getBrowserRef, getPageRef, setSessionPage } from './browser_session.js';
|
|
4
|
-
import { CONTEXT_DESTROY_RETRY_MS } from './human_delay.js';
|
|
5
|
-
import { sleepRandom } from './timing.js';
|
|
6
|
-
const SHOULD_DISABLE_JS = process.env.BOSS_BROWSER_DISABLE_JS === 'true' || process.env.BOSS_BROWSER_DISABLE_JS === '1';
|
|
7
|
-
/** 设为 `1` / `true` 时不注入顶栏滚动提示(调试或截图对比用)。 */
|
|
8
|
-
const SKIP_AGENT_OPERATING_OVERLAY = process.env.BOSS_CLI_NO_AGENT_OVERLAY === '1' ||
|
|
9
|
-
process.env.BOSS_CLI_NO_AGENT_OVERLAY === 'true';
|
|
10
|
-
/** Boss 为 SPA:`load` 后侧栏可能尚未挂载,需单独等待 `.menu-list` 出现 */
|
|
11
|
-
const MENU_LIST_MOUNT_TIMEOUT_MS = 30_000;
|
|
12
|
-
async function pickExistingPage(browser) {
|
|
13
|
-
const pages = (await browser.pages()).filter((p) => !p.isClosed());
|
|
14
|
-
if (pages.length === 0)
|
|
15
|
-
return null;
|
|
16
|
-
const urls = await Promise.all(pages.map((p) => {
|
|
17
|
-
try {
|
|
18
|
-
return p.url();
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return '';
|
|
22
|
-
}
|
|
23
|
-
}));
|
|
24
|
-
const zhipin = pages.find((p, i) => {
|
|
25
|
-
const u = urls[i] ?? '';
|
|
26
|
-
return u.length > 0 && u !== 'about:blank' && u.includes('zhipin.com');
|
|
27
|
-
});
|
|
28
|
-
if (zhipin)
|
|
29
|
-
return zhipin;
|
|
30
|
-
const nonBlank = pages.find((p, i) => {
|
|
31
|
-
const u = urls[i] ?? '';
|
|
32
|
-
return u.length > 0 && u !== 'about:blank';
|
|
33
|
-
});
|
|
34
|
-
return nonBlank ?? null;
|
|
35
|
-
}
|
|
36
|
-
function normalizeMenuText(raw) {
|
|
37
|
-
return (raw ?? '').replace(/\s+/g, ' ').trim();
|
|
38
|
-
}
|
|
39
|
-
async function readMenuListSnapshot(page) {
|
|
40
|
-
return (await page.evaluate(`(() => {
|
|
41
|
-
const root = document.querySelector(".menu-list");
|
|
42
|
-
if (!root) {
|
|
43
|
-
return { exists: false, signature: "" };
|
|
44
|
-
}
|
|
45
|
-
const norm = (v) => (v ?? "").replace(/\\s+/g, " ").trim();
|
|
46
|
-
const links = Array.from(root.querySelectorAll("dl > dt > a"));
|
|
47
|
-
const entries = links.map((a) => {
|
|
48
|
-
const href = a.getAttribute("href") ?? "";
|
|
49
|
-
const labelNode = a.querySelector(".menu-item-content span");
|
|
50
|
-
const label = norm(labelNode?.textContent || a.textContent || "");
|
|
51
|
-
return label + "::" + href;
|
|
52
|
-
});
|
|
53
|
-
return { exists: true, signature: entries.join("|") };
|
|
54
|
-
})()`));
|
|
55
|
-
}
|
|
56
|
-
/** 先按 URL 判断:非 `/web/chat/index` 则进入沟通页,再交由 {@link ensureMenuListStableAfterLoad} 查 `.menu-list` */
|
|
57
|
-
async function ensureBossChatIndexUrlBeforeMenuList(page) {
|
|
58
|
-
if (isBossChatIndexUrl(page.url())) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
await page.goto(BOSS_CHAT_INDEX_URL, { waitUntil: 'load', timeout: 60_000 });
|
|
62
|
-
}
|
|
63
|
-
async function ensureMenuListStableAfterLoad(page) {
|
|
64
|
-
await page.waitForFunction(`(() => document.readyState === "complete" || document.readyState === "interactive")()`, { timeout: 12_000 });
|
|
65
|
-
try {
|
|
66
|
-
await page.waitForFunction(`(() => !!document.querySelector(".menu-list"))()`, { timeout: MENU_LIST_MOUNT_TIMEOUT_MS });
|
|
67
|
-
}
|
|
68
|
-
catch (e) {
|
|
69
|
-
const err = e instanceof Error ? e : new Error(String(e));
|
|
70
|
-
const timedOut = err.name === 'TimeoutError' || /timeout|waiting failed/i.test(err.message);
|
|
71
|
-
if (timedOut) {
|
|
72
|
-
throw new Error(`在 ${MENU_LIST_MOUNT_TIMEOUT_MS / 1000}s 内未出现侧栏 .menu-list(页面或仍在加载,或未登录无法进入主壳)。`);
|
|
73
|
-
}
|
|
74
|
-
throw e;
|
|
75
|
-
}
|
|
76
|
-
const first = await readMenuListSnapshot(page);
|
|
77
|
-
if (!first.exists) {
|
|
78
|
-
throw new Error('当前页面可能未登录或未进入 Boss 主界面。');
|
|
79
|
-
}
|
|
80
|
-
if (!normalizeMenuText(first.signature)) {
|
|
81
|
-
throw new Error('检测到 .menu-list 但菜单内容为空,当前页面状态异常。');
|
|
82
|
-
}
|
|
83
|
-
const stableWindowMs = 3_000;
|
|
84
|
-
const pollMs = 300;
|
|
85
|
-
const deadline = Date.now() + stableWindowMs;
|
|
86
|
-
const expected = first.signature;
|
|
87
|
-
while (Date.now() < deadline) {
|
|
88
|
-
await sleepRandom(pollMs, pollMs);
|
|
89
|
-
const snap = await readMenuListSnapshot(page);
|
|
90
|
-
if (!snap.exists) {
|
|
91
|
-
throw new Error('页面中的 .menu-list 在 3 秒稳定检测内消失,疑似未登录或页面仍在跳转。');
|
|
92
|
-
}
|
|
93
|
-
if (snap.signature !== expected) {
|
|
94
|
-
throw new Error('页面中的 .menu-list 在 3 秒稳定检测内发生变化,疑似页面仍在重定向或刷新。');
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* 在已连接浏览器、且当前页为 Boss 已登录主壳(含侧栏 `.menu-list` 稳定)的前提下执行回调。
|
|
100
|
-
* 会先按 URL 确保落在沟通页 `/web/chat/index`,再校验侧栏;回调内可再导航到职位/推荐等业务路由。
|
|
101
|
-
*/
|
|
102
|
-
export async function withBossSessionPage(callback) {
|
|
103
|
-
const isContextDestroyed = (e) => {
|
|
104
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
105
|
-
return (msg.includes('Execution context was destroyed') ||
|
|
106
|
-
msg.includes('Cannot find context with specified id') ||
|
|
107
|
-
msg.includes('Most likely because of a navigation'));
|
|
108
|
-
};
|
|
109
|
-
const maxAttempts = 2;
|
|
110
|
-
let lastErr;
|
|
111
|
-
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
112
|
-
try {
|
|
113
|
-
await ensureBrowserSession();
|
|
114
|
-
const browser = getBrowserRef();
|
|
115
|
-
if (!browser) {
|
|
116
|
-
throw new Error('无法获取浏览器实例。');
|
|
117
|
-
}
|
|
118
|
-
let page = getPageRef();
|
|
119
|
-
if (!page || page.isClosed()) {
|
|
120
|
-
page = (await pickExistingPage(browser)) ?? (await browser.newPage());
|
|
121
|
-
}
|
|
122
|
-
setSessionPage(page);
|
|
123
|
-
await page.bringToFront();
|
|
124
|
-
await ensureBossChatIndexUrlBeforeMenuList(page);
|
|
125
|
-
if (SHOULD_DISABLE_JS) {
|
|
126
|
-
await page.setJavaScriptEnabled(false);
|
|
127
|
-
}
|
|
128
|
-
await ensureMenuListStableAfterLoad(page);
|
|
129
|
-
if (!SHOULD_DISABLE_JS && !SKIP_AGENT_OPERATING_OVERLAY) {
|
|
130
|
-
await showAgentOperatingIndicator(page).catch(() => {
|
|
131
|
-
/* 注入失败不阻断业务 */
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
try {
|
|
135
|
-
return await callback(page);
|
|
136
|
-
}
|
|
137
|
-
finally {
|
|
138
|
-
if (!SHOULD_DISABLE_JS && !SKIP_AGENT_OPERATING_OVERLAY) {
|
|
139
|
-
await hideAgentOperatingIndicator(page);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch (e) {
|
|
144
|
-
lastErr = e;
|
|
145
|
-
if (attempt < maxAttempts - 1 && isContextDestroyed(e)) {
|
|
146
|
-
// Boss 页面偶发跳转/重渲染会销毁执行上下文;短暂等待并重试一次即可。
|
|
147
|
-
await sleepRandom(CONTEXT_DESTROY_RETRY_MS.min, CONTEXT_DESTROY_RETRY_MS.max);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
throw e;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
throw lastErr instanceof Error ? lastErr : new Error(String(lastErr));
|
|
154
|
-
}
|
|
155
|
-
//# sourceMappingURL=chat.js.map
|
package/dist/browser/chat.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Page } from 'puppeteer-core';
|
|
2
|
-
/**
|
|
3
|
-
* 获取一个“已登录”页面来执行回调;未登录则抛错提示先运行 `boss login`。
|
|
4
|
-
* 说明:boss-cli 采用长期会话(CDP 连接)而非每次启动/关闭浏览器。
|
|
5
|
-
*/
|
|
6
|
-
export declare function withLoggedInPage<T>(callback: (page: Page) => Promise<T>): Promise<T>;
|
|
7
|
-
//# sourceMappingURL=withLoggedInPage.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withLoggedInPage.d.ts","sourceRoot":"","sources":["../../src/browser/withLoggedInPage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAI3C;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAW1F"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ensureBrowserSession, getPageRef } from './browser_session.js';
|
|
2
|
-
import { probeLoggedInFromPage } from './auth.js';
|
|
3
|
-
/**
|
|
4
|
-
* 获取一个“已登录”页面来执行回调;未登录则抛错提示先运行 `boss login`。
|
|
5
|
-
* 说明:boss-cli 采用长期会话(CDP 连接)而非每次启动/关闭浏览器。
|
|
6
|
-
*/
|
|
7
|
-
export async function withLoggedInPage(callback) {
|
|
8
|
-
await ensureBrowserSession();
|
|
9
|
-
const page = getPageRef();
|
|
10
|
-
if (!page) {
|
|
11
|
-
throw new Error('浏览器会话尚未初始化,请先运行 boss login。');
|
|
12
|
-
}
|
|
13
|
-
const { loggedIn } = await probeLoggedInFromPage(page);
|
|
14
|
-
if (!loggedIn) {
|
|
15
|
-
throw new Error('未检测到登录状态,请先运行 boss login 并在浏览器中完成登录。');
|
|
16
|
-
}
|
|
17
|
-
return callback(page);
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=withLoggedInPage.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"withLoggedInPage.js","sourceRoot":"","sources":["../../src/browser/withLoggedInPage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAElD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAI,QAAoC;IAC5E,MAAM,oBAAoB,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/facebook-cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/facebook-cli/index.ts"],"names":[],"mappings":""}
|