@joohw/boss-cli 0.1.4 → 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.
- package/README.md +13 -20
- package/dist/browser/auth.d.ts +0 -1
- package/dist/browser/auth.d.ts.map +1 -1
- package/dist/browser/auth.js +3 -19
- package/dist/browser/auth.js.map +1 -1
- package/dist/browser/browser_session.d.ts +4 -0
- package/dist/browser/browser_session.d.ts.map +1 -1
- package/dist/browser/browser_session.js +27 -14
- package/dist/browser/browser_session.js.map +1 -1
- package/dist/browser/cdp_browser.d.ts +10 -0
- package/dist/browser/cdp_browser.d.ts.map +1 -1
- package/dist/browser/cdp_browser.js +219 -11
- package/dist/browser/cdp_browser.js.map +1 -1
- package/dist/browser/chat.d.ts.map +1 -1
- package/dist/browser/chat.js +5 -3
- package/dist/browser/chat.js.map +1 -1
- package/dist/browser/human_delay.d.ts +88 -0
- package/dist/browser/human_delay.d.ts.map +1 -0
- package/dist/browser/human_delay.js +52 -0
- package/dist/browser/human_delay.js.map +1 -0
- package/dist/browser/index.d.ts +3 -1
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +3 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/timing.d.ts +7 -0
- package/dist/browser/timing.d.ts.map +1 -0
- package/dist/browser/timing.js +34 -0
- package/dist/browser/timing.js.map +1 -0
- package/dist/cli/banner.d.ts.map +1 -1
- package/dist/cli/banner.js +43 -9
- package/dist/cli/banner.js.map +1 -1
- package/dist/cli/cliRouter.d.ts.map +1 -1
- package/dist/cli/cliRouter.js +81 -63
- package/dist/cli/cliRouter.js.map +1 -1
- package/dist/cli/index.js +14 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config.d.ts +9 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +25 -0
- package/dist/config.js.map +1 -1
- package/dist/ocr/baidu_ocr.d.ts +11 -0
- package/dist/ocr/baidu_ocr.d.ts.map +1 -0
- package/dist/ocr/baidu_ocr.js +76 -0
- package/dist/ocr/baidu_ocr.js.map +1 -0
- package/dist/ocr/index.d.ts +3 -0
- package/dist/ocr/index.d.ts.map +1 -0
- package/dist/ocr/index.js +3 -0
- package/dist/ocr/index.js.map +1 -0
- package/dist/ocr/resume_ocr.d.ts +13 -0
- package/dist/ocr/resume_ocr.d.ts.map +1 -0
- package/dist/ocr/resume_ocr.js +35 -0
- package/dist/ocr/resume_ocr.js.map +1 -0
- package/dist/toolset/index.d.ts +12 -2
- package/dist/toolset/index.d.ts.map +1 -1
- package/dist/toolset/index.js +11 -4
- package/dist/toolset/index.js.map +1 -1
- package/dist/toolset/list_candidates.d.ts.map +1 -1
- package/dist/toolset/list_candidates.js +12 -19
- package/dist/toolset/list_candidates.js.map +1 -1
- package/dist/toolset/login.d.ts.map +1 -1
- package/dist/toolset/login.js +7 -4
- package/dist/toolset/login.js.map +1 -1
- package/dist/toolset/open_chat.d.ts +4 -1
- package/dist/toolset/open_chat.d.ts.map +1 -1
- package/dist/toolset/open_chat.js +365 -25
- package/dist/toolset/open_chat.js.map +1 -1
- package/dist/toolset/send_message.d.ts +11 -1
- package/dist/toolset/send_message.d.ts.map +1 -1
- package/dist/toolset/send_message.js +120 -21
- package/dist/toolset/send_message.js.map +1 -1
- package/dist/toolset/skill.d.ts +13 -0
- package/dist/toolset/skill.d.ts.map +1 -0
- package/dist/toolset/skill.js +85 -0
- package/dist/toolset/skill.js.map +1 -0
- package/package.json +5 -2
- package/skills/README.md +11 -0
- package/skills/boss-cli/SKILL.md +58 -0
package/README.md
CHANGED
|
@@ -46,11 +46,12 @@ npm run build
|
|
|
46
46
|
| `boss` | 交互模式 |
|
|
47
47
|
| `boss help` | 打印帮助 |
|
|
48
48
|
| `boss login` | 打开登录页(不校验登录状态;需自行完成登录) |
|
|
49
|
-
| `boss list
|
|
50
|
-
| `boss
|
|
51
|
-
| `boss send
|
|
52
|
-
| `boss
|
|
49
|
+
| `boss list [--unread]` | 读取「全部」聊天列表候选人;`--unread` 仅显示未读 |
|
|
50
|
+
| `boss chat <姓名> [--strict]` | 打开指定联系人会话;默认包含匹配,`--strict` 为精确匹配 |
|
|
51
|
+
| `boss send [--text <内容>] [--action <…>]` | 可只发消息、只执行 action,或**两者同次**(先发消息再 action,步骤间默认随机间隔);`request-resume` \| `agree-resume` \| `confuse-resume`(拒绝附件) |
|
|
52
|
+
| `boss jd` | 读取本地 `~/.boss-cli/jd` 目录下的岗位 Markdown |
|
|
53
53
|
|
|
54
|
+
旧名仍可用:`list-candidates`、`open-chat`、`send-message`、`list-positions`。
|
|
54
55
|
|
|
55
56
|
**交互模式**
|
|
56
57
|
|
|
@@ -65,34 +66,26 @@ npm run build
|
|
|
65
66
|
|
|
66
67
|
---
|
|
67
68
|
|
|
68
|
-
##
|
|
69
|
+
## 浏览器生命周期
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
命令结束(含一次性子命令)时**不会**关闭浏览器窗口:CLI 只断开与浏览器的 CDP 连接,便于 Node 进程退出,浏览器进程仍保留;需要时请自行关闭窗口。
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
# macOS/Linux
|
|
76
|
-
export BOSS_BROWSER_AUTO_CLOSE=1
|
|
77
|
-
|
|
78
|
-
# Windows PowerShell
|
|
79
|
-
$env:BOSS_BROWSER_AUTO_CLOSE="1"
|
|
80
|
-
```
|
|
73
|
+
交互模式(无参数 `boss`)退出时同样**不会**关闭浏览器。
|
|
81
74
|
|
|
82
75
|
---
|
|
83
76
|
|
|
84
77
|
## Headless / Headful(是否显示浏览器窗口)
|
|
85
78
|
|
|
86
|
-
-
|
|
87
|
-
- **`boss login
|
|
88
|
-
-
|
|
79
|
+
- 默认 **headful**(显示浏览器窗口)。
|
|
80
|
+
- **`boss login`**:同样为有头(便于扫码/验证/手动登录)。
|
|
81
|
+
- 若希望其它命令**无头**运行:设置环境变量 `BOSS_BROWSER_HEADLESS=true`(或 `1` / `yes`)。
|
|
89
82
|
|
|
90
83
|
```bash
|
|
91
84
|
# macOS/Linux
|
|
92
|
-
export
|
|
85
|
+
export BOSS_BROWSER_HEADLESS=true
|
|
93
86
|
|
|
94
87
|
# Windows PowerShell
|
|
95
|
-
$env:
|
|
88
|
+
$env:BOSS_BROWSER_HEADLESS="true"
|
|
96
89
|
```
|
|
97
90
|
|
|
98
91
|
---
|
package/dist/browser/auth.d.ts
CHANGED
|
@@ -11,7 +11,6 @@ export declare function createWaitManualLoginRequiredText(action: string): strin
|
|
|
11
11
|
export declare function isBossChatIndexUrl(url: string): boolean;
|
|
12
12
|
/** 未登录时常见跳转:如 `https://www.zhipin.com/web/user/?ka=bticket` */
|
|
13
13
|
export declare function isWebUserLoginUrl(url: string): boolean;
|
|
14
|
-
export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
|
|
15
14
|
export type ProbeLoggedInSignals = {
|
|
16
15
|
hasNickname: boolean;
|
|
17
16
|
navLoginCta: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
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
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { sleepRandom } from './timing.js';
|
|
2
|
+
import { PROBE_LOGIN_POLL_MS } from './human_delay.js';
|
|
1
3
|
/** Boss 直聘首页 */
|
|
2
4
|
export const BOSS_ZHIPIN_HOME = 'https://www.zhipin.com/';
|
|
3
5
|
/** 默认落地页(杭州 SEO 首页);CLI 等未配置环境变量时使用 */
|
|
@@ -35,23 +37,6 @@ export function isWebUserLoginUrl(url) {
|
|
|
35
37
|
return false;
|
|
36
38
|
}
|
|
37
39
|
}
|
|
38
|
-
export function sleep(ms, signal) {
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
if (signal?.aborted) {
|
|
41
|
-
reject(new Error('Aborted'));
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const id = setTimeout(() => {
|
|
45
|
-
signal?.removeEventListener('abort', onAbort);
|
|
46
|
-
resolve();
|
|
47
|
-
}, ms);
|
|
48
|
-
const onAbort = () => {
|
|
49
|
-
clearTimeout(id);
|
|
50
|
-
reject(new Error('Aborted'));
|
|
51
|
-
};
|
|
52
|
-
signal?.addEventListener('abort', onAbort, { once: true });
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
40
|
/**
|
|
56
41
|
* 必须在页面里执行的探测脚本(纯字符串)。
|
|
57
42
|
* `tsx`/esbuild 转译 `page.evaluate(() => { ... })` 时可能注入 `__name(...)`,序列化到浏览器后会报 `__name is not defined`。
|
|
@@ -126,7 +111,6 @@ export async function probeLoggedInFromPage(page) {
|
|
|
126
111
|
return { loggedIn: false, url };
|
|
127
112
|
}
|
|
128
113
|
const maxAttempts = 25;
|
|
129
|
-
const delayMs = 400;
|
|
130
114
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
131
115
|
const s = await probeLoggedInSignals(page);
|
|
132
116
|
if (s.hasNickname || s.hasLogoutHint) {
|
|
@@ -136,7 +120,7 @@ export async function probeLoggedInFromPage(page) {
|
|
|
136
120
|
return { loggedIn: false, url };
|
|
137
121
|
}
|
|
138
122
|
if (attempt < maxAttempts - 1) {
|
|
139
|
-
await
|
|
123
|
+
await sleepRandom(PROBE_LOGIN_POLL_MS.min, PROBE_LOGIN_POLL_MS.max);
|
|
140
124
|
}
|
|
141
125
|
}
|
|
142
126
|
return { loggedIn: false, url };
|
package/dist/browser/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ export declare function disconnectBrowserSession(): Promise<void>;
|
|
|
18
18
|
* 仅断开与浏览器的 CDP 连接,但不主动关闭浏览器进程。
|
|
19
19
|
* 用于 `boss login` 这类“需要用户继续在浏览器里操作”的场景:
|
|
20
20
|
* CLI 可以立刻退出,而浏览器窗口仍保留给用户完成登录。
|
|
21
|
+
*
|
|
22
|
+
* 必须在 disconnect 后对 Chrome 子进程 `unref`,否则 Node 会因子进程仍存活而无法退出。
|
|
23
|
+
*
|
|
24
|
+
* 注意:**绝不调用 `browser.close()`**——历史上在 disconnect 抛错时误走 close 会导致退出 CLI 时浏览器被关掉。
|
|
21
25
|
*/
|
|
22
26
|
export declare function detachBrowserSession(): Promise<void>;
|
|
23
27
|
//# sourceMappingURL=browser_session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser_session.d.ts","sourceRoot":"","sources":["../../src/browser/browser_session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser_session.d.ts","sourceRoot":"","sources":["../../src/browser/browser_session.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAgFpD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAGnE;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmC1D;AAED,wBAAgB,aAAa,IAAI,OAAO,GAAG,IAAI,CAE9C;AAED,wBAAgB,UAAU,IAAI,IAAI,GAAG,IAAI,CAIxC;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAS/C;AAED,0BAA0B;AAC1B,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC,CAY9D;AAWD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuB1D"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { connectBrowser } from './cdp_browser.js';
|
|
1
|
+
import { clearSpawnedChromeProcessRef, connectBrowser } from './cdp_browser.js';
|
|
2
2
|
let browserRef = null;
|
|
3
3
|
let pageRef = null;
|
|
4
4
|
let connectPromise = null;
|
|
@@ -64,7 +64,6 @@ async function establishSession() {
|
|
|
64
64
|
browserRef = b;
|
|
65
65
|
attachDisconnectedHandler(b);
|
|
66
66
|
pageRef = await pickOrCreatePage(b);
|
|
67
|
-
console.error('[boss-cli] 已连接浏览器,当前页:', pageRef.url());
|
|
68
67
|
}
|
|
69
68
|
/**
|
|
70
69
|
* 在 {@link ensureBrowserSession} 之后返回当前已连接的 Browser;
|
|
@@ -152,37 +151,51 @@ export async function disconnectBrowserSession() {
|
|
|
152
151
|
}
|
|
153
152
|
browserRef = null;
|
|
154
153
|
pageRef = null;
|
|
154
|
+
clearSpawnedChromeProcessRef();
|
|
155
|
+
}
|
|
156
|
+
function unrefBrowserChildProcess(proc) {
|
|
157
|
+
if (!proc)
|
|
158
|
+
return;
|
|
159
|
+
try {
|
|
160
|
+
proc.unref();
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
/* ignore */
|
|
164
|
+
}
|
|
155
165
|
}
|
|
156
166
|
/**
|
|
157
167
|
* 仅断开与浏览器的 CDP 连接,但不主动关闭浏览器进程。
|
|
158
168
|
* 用于 `boss login` 这类“需要用户继续在浏览器里操作”的场景:
|
|
159
169
|
* CLI 可以立刻退出,而浏览器窗口仍保留给用户完成登录。
|
|
170
|
+
*
|
|
171
|
+
* 必须在 disconnect 后对 Chrome 子进程 `unref`,否则 Node 会因子进程仍存活而无法退出。
|
|
172
|
+
*
|
|
173
|
+
* 注意:**绝不调用 `browser.close()`**——历史上在 disconnect 抛错时误走 close 会导致退出 CLI 时浏览器被关掉。
|
|
160
174
|
*/
|
|
161
175
|
export async function detachBrowserSession() {
|
|
162
176
|
const b = browserRef;
|
|
163
177
|
if (!b)
|
|
164
178
|
return;
|
|
179
|
+
let proc;
|
|
180
|
+
try {
|
|
181
|
+
proc = typeof b.process === 'function' ? b.process() : undefined;
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
proc = undefined;
|
|
185
|
+
}
|
|
165
186
|
try {
|
|
166
187
|
b.removeAllListeners('disconnected');
|
|
167
|
-
// Puppeteer 支持 disconnect:断开连接但保留浏览器进程
|
|
168
|
-
//(若底层不支持或抛错,则退化为 close)。
|
|
169
188
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
189
|
const anyB = b;
|
|
171
190
|
if (typeof anyB.disconnect === 'function') {
|
|
172
|
-
anyB.disconnect();
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
await b.close();
|
|
191
|
+
await Promise.resolve(anyB.disconnect());
|
|
176
192
|
}
|
|
177
193
|
}
|
|
178
194
|
catch {
|
|
179
|
-
|
|
180
|
-
await b.close();
|
|
181
|
-
}
|
|
182
|
-
catch {
|
|
183
|
-
/* ignore */
|
|
184
|
-
}
|
|
195
|
+
/* 仍不 close;仅断开失败时依赖下方 unref 与进程退出行为 */
|
|
185
196
|
}
|
|
197
|
+
unrefBrowserChildProcess(proc ?? null);
|
|
198
|
+
clearSpawnedChromeProcessRef();
|
|
186
199
|
browserRef = null;
|
|
187
200
|
pageRef = null;
|
|
188
201
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser_session.js","sourceRoot":"","sources":["../../src/browser/browser_session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"browser_session.js","sourceRoot":"","sources":["../../src/browser/browser_session.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type Browser, type CDPSession, type Page } from 'puppeteer-core';
|
|
2
|
+
export declare function clearSpawnedChromeProcessRef(): void;
|
|
3
|
+
/** 最近一次启动是否为无头(仅本进程内、与当前会话一致时有效)。 */
|
|
4
|
+
export declare function wasLastChromeLaunchHeadless(): boolean;
|
|
2
5
|
/** 减轻「正受到自动测试软件的控制」提示与常见自动化特征(非万能,站点仍可能用其它方式检测)。手动开 Chrome 并接 CDP 时可复用。 */
|
|
3
6
|
export declare const LAUNCH_ARGS_LESS_AUTOMATION: readonly ["--disable-blink-features=AutomationControlled", "--disable-infobars"];
|
|
4
7
|
/** 仅用于本地调试:尽量放宽同源/CORS 限制,便于跨域 iframe/canvas 处理。 */
|
|
@@ -27,7 +30,14 @@ export type ConnectBrowserOptions = {
|
|
|
27
30
|
*
|
|
28
31
|
* 若以上均未设置,会按系统尝试常见 Chrome / Edge / Chromium 安装路径。
|
|
29
32
|
* - `BOSS_BROWSER_HEADLESS` — 设为 `true` 时启用无头;默认**有界面**。
|
|
33
|
+
* - `BOSS_BROWSER_VIEWPORT_WIDTH` — 默认 `1280`(CSS 像素)
|
|
34
|
+
* - `BOSS_BROWSER_VIEWPORT_HEIGHT` — 默认 `4000`(在线简历 iframe 常高于一屏,拉高视口便于整框截图)
|
|
30
35
|
*/
|
|
36
|
+
/** 启动浏览器时的默认视口(与环境变量一致);截图恢复时 `viewport()` 为 null 也可用其兜底。 */
|
|
37
|
+
export declare function defaultViewportFromEnv(): {
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
};
|
|
31
41
|
export declare function connectBrowser(options?: ConnectBrowserOptions): Promise<Browser>;
|
|
32
42
|
/** 对某一页创建原生 CDP Session(需要低层域如 `Network.*`、`Fetch.*` 时使用)。 */
|
|
33
43
|
export declare function createPageCDPSession(page: Page): Promise<CDPSession>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdp_browser.d.ts","sourceRoot":"","sources":["../../src/browser/cdp_browser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cdp_browser.d.ts","sourceRoot":"","sources":["../../src/browser/cdp_browser.ts"],"names":[],"mappings":"AAKA,OAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAYrF,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD;AAED,qCAAqC;AACrC,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAmLD,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,kFAG9B,CAAC;AAEX,oDAAoD;AACpD,eAAO,MAAM,0BAA0B,yEAG7B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG;IAClC,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qCAAqC;IACrC,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAA;AAED;;;;;;;;;;;;;;GAcG;AACH,6DAA6D;AAC7D,wBAAgB,sBAAsB,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAO1E;AAED,wBAAsB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,CA0G1F;AAED,8DAA8D;AAC9D,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAE1E"}
|
|
@@ -1,7 +1,140 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
1
2
|
import { existsSync } from 'node:fs';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import readline from 'node:readline';
|
|
2
5
|
import path from 'node:path';
|
|
3
6
|
import puppeteer from 'puppeteer-core';
|
|
4
7
|
import { BROWSER_USER_DATA_DIR, ensureAppDataLayout } from '../config.js';
|
|
8
|
+
/** 与 @puppeteer/browsers 一致,解析 Chrome 启动日志中的 CDP WebSocket URL(可能在 stdout 或 stderr)。 */
|
|
9
|
+
const CDP_WEBSOCKET_ENDPOINT_REGEX = /^DevTools listening on (ws:\/\/.*)$/;
|
|
10
|
+
const LAUNCH_READY_MS = 30_000;
|
|
11
|
+
let spawnedChromeChild = null;
|
|
12
|
+
/** 最近一次 `connectBrowser` 是否以无头方式启动(`browser.process()` 在 connect 模式下不可用,供 login 等逻辑判断)。 */
|
|
13
|
+
let lastChromeLaunchHeadless = false;
|
|
14
|
+
export function clearSpawnedChromeProcessRef() {
|
|
15
|
+
spawnedChromeChild = null;
|
|
16
|
+
}
|
|
17
|
+
/** 最近一次启动是否为无头(仅本进程内、与当前会话一致时有效)。 */
|
|
18
|
+
export function wasLastChromeLaunchHeadless() {
|
|
19
|
+
return lastChromeLaunchHeadless;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Chromium 在启用远程调试时会在用户数据目录写入 `DevToolsActivePort`(首行端口、次行 path)。
|
|
23
|
+
* 当同一 user-data-dir 已有实例在跑时,新起的进程会通过单例立刻退出(常为代码 0),
|
|
24
|
+
* 且本进程的 stdout 可能拿不到 `DevTools listening on`(尤其 Windows),此时应读本文件接到已有实例。
|
|
25
|
+
*/
|
|
26
|
+
async function readDevToolsEndpointFromUserDataDir(userDataDir, maxWaitMs) {
|
|
27
|
+
const portPath = path.join(userDataDir, 'DevToolsActivePort');
|
|
28
|
+
const deadline = Date.now() + maxWaitMs;
|
|
29
|
+
let delay = 40;
|
|
30
|
+
while (Date.now() < deadline) {
|
|
31
|
+
if (existsSync(portPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const fileContent = await readFile(portPath, 'ascii');
|
|
34
|
+
const lines = fileContent
|
|
35
|
+
.split('\n')
|
|
36
|
+
.map((l) => l.trim())
|
|
37
|
+
.filter((l) => l.length > 0);
|
|
38
|
+
const rawPort = lines[0];
|
|
39
|
+
const rawPath = lines[1];
|
|
40
|
+
if (rawPort && rawPath) {
|
|
41
|
+
const port = Number.parseInt(rawPort, 10);
|
|
42
|
+
if (Number.isFinite(port) && port > 0 && port <= 65535) {
|
|
43
|
+
return `ws://127.0.0.1:${port}${rawPath}`;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* 文件可能尚未写完,重试 */
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
52
|
+
delay = Math.min(delay + 40, 200);
|
|
53
|
+
}
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
function waitForDevToolsWebSocketUrl(proc, userDataDir, timeoutMs) {
|
|
57
|
+
const streams = [proc.stdout, proc.stderr].filter((s) => s != null);
|
|
58
|
+
if (streams.length === 0) {
|
|
59
|
+
return Promise.reject(new Error('浏览器子进程无 stdout/stderr,无法获取 CDP 地址'));
|
|
60
|
+
}
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
const rls = [];
|
|
63
|
+
let settled = false;
|
|
64
|
+
let timer;
|
|
65
|
+
const cleanup = () => {
|
|
66
|
+
for (const rl of rls) {
|
|
67
|
+
try {
|
|
68
|
+
rl.close();
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
/* ignore */
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
rls.length = 0;
|
|
75
|
+
};
|
|
76
|
+
const finish = (fn) => {
|
|
77
|
+
if (settled)
|
|
78
|
+
return;
|
|
79
|
+
settled = true;
|
|
80
|
+
if (timer !== undefined) {
|
|
81
|
+
clearTimeout(timer);
|
|
82
|
+
timer = undefined;
|
|
83
|
+
}
|
|
84
|
+
proc.off('exit', onExit);
|
|
85
|
+
proc.off('error', onProcError);
|
|
86
|
+
cleanup();
|
|
87
|
+
fn();
|
|
88
|
+
};
|
|
89
|
+
timer = setTimeout(() => {
|
|
90
|
+
finish(() => {
|
|
91
|
+
reject(new Error(`等待 Chrome 输出 DevTools 地址超时(${timeoutMs}ms)`));
|
|
92
|
+
});
|
|
93
|
+
}, timeoutMs);
|
|
94
|
+
const onExit = (code) => {
|
|
95
|
+
if (timer !== undefined) {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
timer = undefined;
|
|
98
|
+
}
|
|
99
|
+
void (async () => {
|
|
100
|
+
if (code === 0) {
|
|
101
|
+
const fromFile = await readDevToolsEndpointFromUserDataDir(userDataDir, 4000);
|
|
102
|
+
if (fromFile) {
|
|
103
|
+
finish(() => {
|
|
104
|
+
resolve(fromFile);
|
|
105
|
+
});
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
finish(() => {
|
|
110
|
+
reject(new Error(code === 0
|
|
111
|
+
? '无法连接浏览器:新进程已退出(代码 0)且未在本地用户数据目录发现 DevTools 调试端口。若该配置正被「手动打开」的 Chrome 占用(无远程调试),请先关闭该窗口;或结束仍由上次 boss-cli 留下的浏览器后再试。'
|
|
112
|
+
: `浏览器进程在就绪前退出(代码 ${code ?? 'unknown'})`));
|
|
113
|
+
});
|
|
114
|
+
})();
|
|
115
|
+
};
|
|
116
|
+
const onProcError = (err) => {
|
|
117
|
+
finish(() => {
|
|
118
|
+
reject(err);
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
const onLine = (line) => {
|
|
122
|
+
const m = line.trim().match(CDP_WEBSOCKET_ENDPOINT_REGEX);
|
|
123
|
+
if (m?.[1]) {
|
|
124
|
+
finish(() => {
|
|
125
|
+
resolve(m[1]);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
proc.once('exit', onExit);
|
|
130
|
+
proc.once('error', onProcError);
|
|
131
|
+
for (const s of streams) {
|
|
132
|
+
const rl = readline.createInterface(s);
|
|
133
|
+
rls.push(rl);
|
|
134
|
+
rl.on('line', onLine);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
5
138
|
/** 在未配置路径时,尝试常见安装位置(Chrome / Edge / Chromium)。 */
|
|
6
139
|
function findLocalChromiumExecutable() {
|
|
7
140
|
const candidates = [];
|
|
@@ -55,7 +188,18 @@ export const LAUNCH_ARGS_ALLOW_ALL_CORS = [
|
|
|
55
188
|
*
|
|
56
189
|
* 若以上均未设置,会按系统尝试常见 Chrome / Edge / Chromium 安装路径。
|
|
57
190
|
* - `BOSS_BROWSER_HEADLESS` — 设为 `true` 时启用无头;默认**有界面**。
|
|
191
|
+
* - `BOSS_BROWSER_VIEWPORT_WIDTH` — 默认 `1280`(CSS 像素)
|
|
192
|
+
* - `BOSS_BROWSER_VIEWPORT_HEIGHT` — 默认 `4000`(在线简历 iframe 常高于一屏,拉高视口便于整框截图)
|
|
58
193
|
*/
|
|
194
|
+
/** 启动浏览器时的默认视口(与环境变量一致);截图恢复时 `viewport()` 为 null 也可用其兜底。 */
|
|
195
|
+
export function defaultViewportFromEnv() {
|
|
196
|
+
const w = Number.parseInt(process.env.BOSS_BROWSER_VIEWPORT_WIDTH?.trim() ?? '', 10);
|
|
197
|
+
const h = Number.parseInt(process.env.BOSS_BROWSER_VIEWPORT_HEIGHT?.trim() ?? '', 10);
|
|
198
|
+
return {
|
|
199
|
+
width: Number.isFinite(w) && w > 0 ? w : 1280,
|
|
200
|
+
height: Number.isFinite(h) && h > 0 ? h : 4000,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
59
203
|
export async function connectBrowser(options = {}) {
|
|
60
204
|
const executablePath = options.executablePath?.trim() ||
|
|
61
205
|
process.env.CHROME_PATH?.trim() ||
|
|
@@ -73,20 +217,84 @@ export async function connectBrowser(options = {}) {
|
|
|
73
217
|
const headless = options.headless ?? process.env.BOSS_BROWSER_HEADLESS === 'true';
|
|
74
218
|
const allowAllCors = options.allowAllCors ?? process.env.BOSS_BROWSER_ALLOW_ALL_CORS === 'true';
|
|
75
219
|
const disableGpu = process.env.BOSS_BROWSER_DISABLE_GPU === 'true';
|
|
76
|
-
|
|
77
|
-
|
|
220
|
+
clearSpawnedChromeProcessRef();
|
|
221
|
+
lastChromeLaunchHeadless = !!headless;
|
|
222
|
+
const userArgs = [
|
|
223
|
+
...LAUNCH_ARGS_LESS_AUTOMATION,
|
|
224
|
+
...(disableGpu ? ['--disable-gpu'] : []),
|
|
225
|
+
...(allowAllCors ? LAUNCH_ARGS_ALLOW_ALL_CORS : []),
|
|
226
|
+
...(profileDirectory ? [`--profile-directory=${profileDirectory}`] : []),
|
|
227
|
+
];
|
|
228
|
+
let chromeArgs = puppeteer
|
|
229
|
+
.defaultArgs({
|
|
230
|
+
browser: 'chrome',
|
|
78
231
|
userDataDir,
|
|
79
232
|
headless,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
233
|
+
args: userArgs,
|
|
234
|
+
})
|
|
235
|
+
.filter((a) => a !== '--enable-automation');
|
|
236
|
+
if (!chromeArgs.some((a) => a.startsWith('--remote-debugging-'))) {
|
|
237
|
+
chromeArgs.push('--remote-debugging-port=0');
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 不使用 `puppeteer.launch()`:其依赖的 `@puppeteer/browsers` 会在 **Node 进程 `exit` 时 kill 浏览器子进程**,
|
|
241
|
+
* 导致交互模式 / `npm run dev` 退出时窗口被一并关掉。改为自行 `spawn` + `connect`,退出时只断 CDP,浏览器可保留。
|
|
242
|
+
*/
|
|
243
|
+
const proc = spawn(executablePath, chromeArgs, {
|
|
244
|
+
detached: true,
|
|
245
|
+
env: process.env,
|
|
246
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
89
247
|
});
|
|
248
|
+
spawnedChromeChild = proc;
|
|
249
|
+
let wsUrl;
|
|
250
|
+
try {
|
|
251
|
+
wsUrl = await waitForDevToolsWebSocketUrl(proc, userDataDir, LAUNCH_READY_MS);
|
|
252
|
+
}
|
|
253
|
+
catch (e) {
|
|
254
|
+
try {
|
|
255
|
+
proc.kill();
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
/* ignore */
|
|
259
|
+
}
|
|
260
|
+
clearSpawnedChromeProcessRef();
|
|
261
|
+
throw e;
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
proc.stdout?.resume();
|
|
265
|
+
proc.stderr?.resume();
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
/* ignore */
|
|
269
|
+
}
|
|
270
|
+
/** 单例移交时子进程已退出,无句柄可 unref;仅在本进程真正拉起 Chrome 时 unref,避免拖住 Node 退出。 */
|
|
271
|
+
if (proc.exitCode === null && proc.signalCode === null) {
|
|
272
|
+
try {
|
|
273
|
+
proc.unref();
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
/* ignore */
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
clearSpawnedChromeProcessRef();
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
return await puppeteer.connect({
|
|
284
|
+
browserWSEndpoint: wsUrl,
|
|
285
|
+
defaultViewport: defaultViewportFromEnv(),
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
catch (e) {
|
|
289
|
+
try {
|
|
290
|
+
proc.kill();
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
/* ignore */
|
|
294
|
+
}
|
|
295
|
+
clearSpawnedChromeProcessRef();
|
|
296
|
+
throw e;
|
|
297
|
+
}
|
|
90
298
|
}
|
|
91
299
|
/** 对某一页创建原生 CDP Session(需要低层域如 `Network.*`、`Fetch.*` 时使用)。 */
|
|
92
300
|
export async function createPageCDPSession(page) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdp_browser.js","sourceRoot":"","sources":["../../src/browser/cdp_browser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,SAAuD,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE1E,kDAAkD;AAClD,SAAS,2BAA2B;IAClC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QACvC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;QACpC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;QAC9C,IAAI,KAAK,EAAE,CAAC;YACV,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,EAAE,EAAE,CAAC;YACP,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;YAChF,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;YAClF,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACzC,UAAU,CAAC,IAAI,CACb,8DAA8D,EAC9D,gEAAgE,EAChE,oDAAoD,CACrD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,IAAI,CACb,+BAA+B,EAC/B,wBAAwB,EACxB,mBAAmB,EACnB,2BAA2B,EAC3B,gCAAgC,EAChC,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,+CAA+C;IAC/C,oBAAoB;CACZ,CAAC;AAEX,oDAAoD;AACpD,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,wBAAwB;IACxB,kCAAkC;CAC1B,CAAC;AAeX
|
|
1
|
+
{"version":3,"file":"cdp_browser.js","sourceRoot":"","sources":["../../src/browser/cdp_browser.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAoCpD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAwDtF"}
|
package/dist/browser/chat.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { ensureBrowserSession, getBrowserRef, getPageRef, setSessionPage } from './browser_session.js';
|
|
2
|
-
import { BOSS_CHAT_INDEX_URL, isBossChatIndexUrl
|
|
2
|
+
import { BOSS_CHAT_INDEX_URL, isBossChatIndexUrl } from './auth.js';
|
|
3
|
+
import { CHAT_GOTO_SETTLE_MS, CONTEXT_DESTROY_RETRY_MS } from './human_delay.js';
|
|
4
|
+
import { sleepRandom } from './timing.js';
|
|
3
5
|
const SHOULD_DISABLE_JS = process.env.BOSS_BROWSER_DISABLE_JS === 'true' || process.env.BOSS_BROWSER_DISABLE_JS === '1';
|
|
4
6
|
async function pickExistingPage(browser) {
|
|
5
7
|
const pages = (await browser.pages()).filter((p) => !p.isClosed());
|
|
@@ -66,7 +68,7 @@ export async function withChatPage(callback) {
|
|
|
66
68
|
if (!isBossChatIndexUrl(currentUrl)) {
|
|
67
69
|
await page.goto(BOSS_CHAT_INDEX_URL, { waitUntil: 'load', timeout: 60_000 });
|
|
68
70
|
// 等待页面渲染稳定(SPA/异步接口),避免紧接着查询元素时拿不到
|
|
69
|
-
await
|
|
71
|
+
await sleepRandom(CHAT_GOTO_SETTLE_MS.min, CHAT_GOTO_SETTLE_MS.max);
|
|
70
72
|
}
|
|
71
73
|
return await callback(page);
|
|
72
74
|
}
|
|
@@ -74,7 +76,7 @@ export async function withChatPage(callback) {
|
|
|
74
76
|
lastErr = e;
|
|
75
77
|
if (attempt < maxAttempts - 1 && isContextDestroyed(e)) {
|
|
76
78
|
// Boss 页面偶发跳转/重渲染会销毁执行上下文;短暂等待并重试一次即可。
|
|
77
|
-
await
|
|
79
|
+
await sleepRandom(CONTEXT_DESTROY_RETRY_MS.min, CONTEXT_DESTROY_RETRY_MS.max);
|
|
78
80
|
continue;
|
|
79
81
|
}
|
|
80
82
|
throw e;
|
package/dist/browser/chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACvG,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../src/browser/chat.ts"],"names":[],"mappings":"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"}
|