@viyzhu/boss-cli-fork 0.6.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/AGENTS.md +30 -0
- package/LICENSE +674 -0
- package/README.md +223 -0
- package/dist/browser/browser_session.d.ts +27 -0
- package/dist/browser/browser_session.d.ts.map +1 -0
- package/dist/browser/browser_session.js +246 -0
- package/dist/browser/browser_session.js.map +1 -0
- package/dist/browser/cdp_browser.d.ts +50 -0
- package/dist/browser/cdp_browser.d.ts.map +1 -0
- package/dist/browser/cdp_browser.js +315 -0
- package/dist/browser/cdp_browser.js.map +1 -0
- package/dist/browser/human_delay.d.ts +117 -0
- package/dist/browser/human_delay.d.ts.map +1 -0
- package/dist/browser/human_delay.js +71 -0
- package/dist/browser/human_delay.js.map +1 -0
- package/dist/browser/index.d.ts +9 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +9 -0
- package/dist/browser/index.js.map +1 -0
- 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/browser/viewport_temp.d.ts +15 -0
- package/dist/browser/viewport_temp.d.ts.map +1 -0
- package/dist/browser/viewport_temp.js +78 -0
- package/dist/browser/viewport_temp.js.map +1 -0
- package/dist/cli/banner.d.ts +2 -0
- package/dist/cli/banner.d.ts.map +1 -0
- package/dist/cli/banner.js +69 -0
- package/dist/cli/banner.js.map +1 -0
- package/dist/cli/cliRouter.d.ts +9 -0
- package/dist/cli/cliRouter.d.ts.map +1 -0
- package/dist/cli/cliRouter.js +604 -0
- package/dist/cli/cliRouter.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +34 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/version.d.ts +29 -0
- package/dist/cli/version.d.ts.map +1 -0
- package/dist/cli/version.js +180 -0
- package/dist/cli/version.js.map +1 -0
- package/dist/common/auth.d.ts +44 -0
- package/dist/common/auth.d.ts.map +1 -0
- package/dist/common/auth.js +168 -0
- package/dist/common/auth.js.map +1 -0
- package/dist/common/baidu_user_env.d.ts +7 -0
- package/dist/common/baidu_user_env.d.ts.map +1 -0
- package/dist/common/baidu_user_env.js +56 -0
- package/dist/common/baidu_user_env.js.map +1 -0
- package/dist/common/boss_availability.d.ts +5 -0
- package/dist/common/boss_availability.d.ts.map +1 -0
- package/dist/common/boss_availability.js +245 -0
- package/dist/common/boss_availability.js.map +1 -0
- package/dist/common/boss_modal.d.ts +14 -0
- package/dist/common/boss_modal.d.ts.map +1 -0
- package/dist/common/boss_modal.js +81 -0
- package/dist/common/boss_modal.js.map +1 -0
- package/dist/common/boss_page_guards.d.ts +14 -0
- package/dist/common/boss_page_guards.d.ts.map +1 -0
- package/dist/common/boss_page_guards.js +596 -0
- package/dist/common/boss_page_guards.js.map +1 -0
- package/dist/common/boss_paywall_popup.d.ts +28 -0
- package/dist/common/boss_paywall_popup.d.ts.map +1 -0
- package/dist/common/boss_paywall_popup.js +158 -0
- package/dist/common/boss_paywall_popup.js.map +1 -0
- package/dist/common/boss_session_lock.d.ts +2 -0
- package/dist/common/boss_session_lock.d.ts.map +1 -0
- package/dist/common/boss_session_lock.js +127 -0
- package/dist/common/boss_session_lock.js.map +1 -0
- package/dist/common/boss_session_page.d.ts +27 -0
- package/dist/common/boss_session_page.d.ts.map +1 -0
- package/dist/common/boss_session_page.js +173 -0
- package/dist/common/boss_session_page.js.map +1 -0
- package/dist/common/boss_sidebar_nav.d.ts +7 -0
- package/dist/common/boss_sidebar_nav.d.ts.map +1 -0
- package/dist/common/boss_sidebar_nav.js +53 -0
- package/dist/common/boss_sidebar_nav.js.map +1 -0
- package/dist/common/c_resume_capture.d.ts +19 -0
- package/dist/common/c_resume_capture.d.ts.map +1 -0
- package/dist/common/c_resume_capture.js +185 -0
- package/dist/common/c_resume_capture.js.map +1 -0
- package/dist/common/ensure_page.d.ts +9 -0
- package/dist/common/ensure_page.d.ts.map +1 -0
- package/dist/common/ensure_page.js +14 -0
- package/dist/common/ensure_page.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +57 -0
- package/dist/config.js.map +1 -0
- package/dist/ocr/baidu_ocr.d.ts +13 -0
- package/dist/ocr/baidu_ocr.d.ts.map +1 -0
- package/dist/ocr/baidu_ocr.js +80 -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 +38 -0
- package/dist/ocr/resume_ocr.js.map +1 -0
- package/dist/toolset/action.d.ts +12 -0
- package/dist/toolset/action.d.ts.map +1 -0
- package/dist/toolset/action.js +521 -0
- package/dist/toolset/action.js.map +1 -0
- package/dist/toolset/baidu_credentials.d.ts +5 -0
- package/dist/toolset/baidu_credentials.d.ts.map +1 -0
- package/dist/toolset/baidu_credentials.js +24 -0
- package/dist/toolset/baidu_credentials.js.map +1 -0
- package/dist/toolset/chat.d.ts +10 -0
- package/dist/toolset/chat.d.ts.map +1 -0
- package/dist/toolset/chat.js +763 -0
- package/dist/toolset/chat.js.map +1 -0
- package/dist/toolset/deep-search.d.ts +35 -0
- package/dist/toolset/deep-search.d.ts.map +1 -0
- package/dist/toolset/deep-search.js +1505 -0
- package/dist/toolset/deep-search.js.map +1 -0
- package/dist/toolset/greet.d.ts +6 -0
- package/dist/toolset/greet.d.ts.map +1 -0
- package/dist/toolset/greet.js +81 -0
- package/dist/toolset/greet.js.map +1 -0
- package/dist/toolset/index.d.ts +48 -0
- package/dist/toolset/index.d.ts.map +1 -0
- package/dist/toolset/index.js +71 -0
- package/dist/toolset/index.js.map +1 -0
- package/dist/toolset/jd.d.ts +10 -0
- package/dist/toolset/jd.d.ts.map +1 -0
- package/dist/toolset/jd.js +406 -0
- package/dist/toolset/jd.js.map +1 -0
- package/dist/toolset/list.d.ts +6 -0
- package/dist/toolset/list.d.ts.map +1 -0
- package/dist/toolset/list.js +146 -0
- package/dist/toolset/list.js.map +1 -0
- package/dist/toolset/login.d.ts +6 -0
- package/dist/toolset/login.d.ts.map +1 -0
- package/dist/toolset/login.js +76 -0
- package/dist/toolset/login.js.map +1 -0
- package/dist/toolset/normal-search.d.ts +12 -0
- package/dist/toolset/normal-search.d.ts.map +1 -0
- package/dist/toolset/normal-search.js +301 -0
- package/dist/toolset/normal-search.js.map +1 -0
- package/dist/toolset/preview.d.ts +5 -0
- package/dist/toolset/preview.d.ts.map +1 -0
- package/dist/toolset/preview.js +100 -0
- package/dist/toolset/preview.js.map +1 -0
- package/dist/toolset/recommend.d.ts +36 -0
- package/dist/toolset/recommend.d.ts.map +1 -0
- package/dist/toolset/recommend.js +428 -0
- package/dist/toolset/recommend.js.map +1 -0
- package/dist/toolset/send.d.ts +7 -0
- package/dist/toolset/send.d.ts.map +1 -0
- package/dist/toolset/send.js +52 -0
- package/dist/toolset/send.js.map +1 -0
- package/package.json +69 -0
- package/skills/boss-frontend-analysis/SKILL.md +58 -0
- package/skills/boss-frontend-analysis/agents/openai.yaml +4 -0
- package/skills/boss-frontend-analysis/scripts/capture_boss_frontend.mjs +604 -0
package/README.md
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# boss-cli — Boss直聘自动化 CLI | 批量发消息 · 自动打招呼 · AI Agent 招聘工具
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@joohw/boss-cli)
|
|
4
|
+
[](https://www.npmjs.com/package/@joohw/boss-cli)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](https://github.com/joohw/boss-cli)
|
|
7
|
+
|
|
8
|
+
官网主页:[boss-cli.com](https://boss-cli.com)
|
|
9
|
+
|
|
10
|
+
**boss-cli**(`@joohw/boss-cli`)是开源的 **Boss直聘自动化命令行工具**。基于 Puppeteer / CDP 协议驱动本机 Chrome,无需 Selenium,把 Boss直聘 B 端的核心 HR 操作搬进终端:**候选人列表**、**批量发消息**、**自动打招呼**、**在线简历预览**、**深度搜索**、**职位管理**。
|
|
11
|
+
|
|
12
|
+
适合 HR 日常提效,也适合 Claude / GPT / Gemini 等 **AI Agent** 通过子进程调用,搭建全自动化招聘流水线。
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g @joohw/boss-cli@latest
|
|
16
|
+
boss login
|
|
17
|
+
boss help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
> 纯 CLI,不内置对话式 Agent。每条命令输出结构化纯文本,Agent 可直接解析并编排多步流程。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 为什么选择 boss-cli?
|
|
25
|
+
|
|
26
|
+
| 场景 | 命令 |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Boss直聘批量发消息 | `boss send --text "..."` 配合脚本循环 |
|
|
29
|
+
| Boss直聘自动打招呼 | `boss greet <姓名> [--job <岗位>]` |
|
|
30
|
+
| Boss直聘候选人筛选 | `boss list` / `boss list --unread` |
|
|
31
|
+
| Boss直聘脚本自动化 | 本机 Chrome + CDP,Cookie 本地存储 |
|
|
32
|
+
| AI 招聘 Agent | 子进程调用,输出 Agent 友好 |
|
|
33
|
+
| 数据隐私 | 不经过第三方服务器,数据在 `~/.boss-cli/` |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 安装
|
|
38
|
+
|
|
39
|
+
**要求**:Node.js ≥ 20,本机已安装 Chrome / Chromium。
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install -g @joohw/boss-cli@latest
|
|
43
|
+
boss help
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 安装本 fork(含尚未进入上游的修复)
|
|
47
|
+
|
|
48
|
+
本仓库是 [`joohw/boss-cli`](https://github.com/joohw/boss-cli) 的 fork,包含风控页反弹熔断等
|
|
49
|
+
上游尚未发布的修复,以 `@viyzhu/boss-cli-fork` 单独发布:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm install -g @viyzhu/boss-cli-fork@latest
|
|
53
|
+
boss version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
两个包提供同名的 `boss` 命令,**不要同时装**;换装前先 `npm uninstall -g @joohw/boss-cli`。
|
|
57
|
+
也可以直接装仓库 tarball(等价于 main 最新提交):
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install -g https://github.com/Viy1204/boss-cli/archive/refs/heads/main.tar.gz
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
> 别用 `npm i -g github:Viy1204/boss-cli`:npm 会把全局包链到 npm cache 里的临时 clone,
|
|
64
|
+
> 缓存清理后 `boss` 直接 `Cannot find module`。
|
|
65
|
+
|
|
66
|
+
如果你觉得 boss-cli 好用,欢迎给本仓库一个 Star;使用中遇到问题请提交 Issue,新功能或改进也欢迎提交 PR。
|
|
67
|
+
|
|
68
|
+
> **macOS / Linux 权限问题**:系统 Node 默认全局前缀在 `/usr/local`,当前账户无写权限。建议先把全局前缀挪到用户目录(一次性配置):
|
|
69
|
+
>
|
|
70
|
+
> ```bash
|
|
71
|
+
> mkdir -p ~/.npm-global
|
|
72
|
+
> npm config set prefix ~/.npm-global
|
|
73
|
+
> echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.zshrc # bash 用 ~/.bash_profile
|
|
74
|
+
> source ~/.zshrc
|
|
75
|
+
> ```
|
|
76
|
+
>
|
|
77
|
+
> 使用 `fnm` / `nvm` / `volta` 的用户可跳过此步。Windows 用户无需此步。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 命令一览
|
|
82
|
+
|
|
83
|
+
| 命令 | 说明 |
|
|
84
|
+
| --- | --- |
|
|
85
|
+
| `boss login` | 打开 Boss直聘登录页(扫码/验证后手动完成) |
|
|
86
|
+
| `boss update` | 通过 npm 安装最新版 boss-cli |
|
|
87
|
+
| `boss list [--unread]` | 读取聊天列表;`--unread` 仅未读 |
|
|
88
|
+
| `boss chat <姓名> [--strict]` | 打开指定候选人会话 |
|
|
89
|
+
| `boss chat [姓名] --index <序号> [--unread] [--strict]` | 按 `boss list` 输出序号打开会话;同名候选人建议用序号 |
|
|
90
|
+
| `boss send [--text <内容>]` | 向当前会话发送消息 |
|
|
91
|
+
| `boss action <操作>` | 索要简历 / 不合适 / 备注 / 交换微信等 |
|
|
92
|
+
| `boss recommend [岗位关键字]` | 读取推荐候选人列表 |
|
|
93
|
+
| `boss search [关键词]` | 常规搜索牛人列表 |
|
|
94
|
+
| `boss greet <姓名> [--job <岗位>]` | 在当前推荐/深度搜索页对候选人打招呼(不会自动跳转) |
|
|
95
|
+
| `boss preview <姓名>` | 在线简历预览(每日次数有限) |
|
|
96
|
+
| `boss deep-search [岗位关键字] [--core <要求>] [--bonus <加分项>] [--clear-core] [--clear-bonus] [--match]` | 深度搜索表单状态;`--core` / `--bonus` 可重复,并按传入列表同步分组;`--clear-*` 清空分组;默认不输出候选列表,`--match` 输出最新 20 条 |
|
|
97
|
+
| `boss positions` | 读取职位列表 |
|
|
98
|
+
| `boss jd <名称>` | 抓取职位 JD 缓存到本地 |
|
|
99
|
+
|
|
100
|
+
完整用法:`boss help`
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 快速上手
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# 1. 登录
|
|
108
|
+
boss login
|
|
109
|
+
|
|
110
|
+
# 2. 查看未读候选人
|
|
111
|
+
boss list --unread
|
|
112
|
+
|
|
113
|
+
# 3. 打开会话并发送消息
|
|
114
|
+
boss chat 张三
|
|
115
|
+
boss send --text "您好,请问方便发一下简历吗?"
|
|
116
|
+
|
|
117
|
+
# 同名或姓名定位失败时,按 list 序号打开;--unread 对应 list --unread 的序号
|
|
118
|
+
boss chat --index 2 --unread
|
|
119
|
+
boss chat 张三 --index 2 --unread --strict
|
|
120
|
+
|
|
121
|
+
# 4. 先进入推荐页,再在当前页打招呼
|
|
122
|
+
boss recommend 前端工程师
|
|
123
|
+
boss greet 张三 --job 前端工程师
|
|
124
|
+
|
|
125
|
+
# 5. 常规搜索牛人
|
|
126
|
+
boss search "langgraph"
|
|
127
|
+
|
|
128
|
+
# 6. 深度搜索:按传入列表同步分组条件,但不消耗匹配次数
|
|
129
|
+
boss deep-search --core "AI产品经理" --core "做过 RAG 或 Agent 产品落地" --bonus "有 ToB 平台经验"
|
|
130
|
+
|
|
131
|
+
# 只有明确添加 --match 才会点击「立即匹配」,会消耗今日匹配次数,并只输出最新 20 条
|
|
132
|
+
boss deep-search --match
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 与 AI Agent 集成
|
|
138
|
+
|
|
139
|
+
boss-cli 每条命令输出纯文本,适合 LLM 通过子进程编排:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
1. boss list --unread → 获取未读候选人
|
|
143
|
+
2. boss chat <姓名> → 打开会话
|
|
144
|
+
同名时用 boss chat [姓名] --index <序号> [--unread]
|
|
145
|
+
3. boss action resume → 索要简历
|
|
146
|
+
4. boss send -t "..." → 发送消息
|
|
147
|
+
5. boss recommend → 读取推荐列表
|
|
148
|
+
6. boss search <关键词> → 读取常规搜索列表
|
|
149
|
+
7. boss greet <姓名> → 批量打招呼
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
详见 [AGENTS.md](./AGENTS.md)。
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## 常见问题
|
|
157
|
+
|
|
158
|
+
**boss-cli 是什么?**
|
|
159
|
+
开源 Boss直聘自动化 CLI,用终端命令代替手动操作 Boss直聘网页,支持 AI Agent 编排。
|
|
160
|
+
|
|
161
|
+
**和 Selenium / Playwright 有什么区别?**
|
|
162
|
+
boss-cli 基于 CDP 连接本机 Chrome,复用已有登录态,针对 Boss直聘 B 端页面做了专用封装,开箱即用。
|
|
163
|
+
|
|
164
|
+
**需要额外下载浏览器吗?**
|
|
165
|
+
不需要。使用本机已安装的 Chrome / Chromium,通过 CDP 协议连接。
|
|
166
|
+
|
|
167
|
+
**数据会上传到服务器吗?**
|
|
168
|
+
不会。Cookie 和缓存仅存储在本地 `~/.boss-cli/`,CLI 不经过任何第三方服务器。
|
|
169
|
+
|
|
170
|
+
**如何无头模式运行?**
|
|
171
|
+
设置环境变量 `BOSS_BROWSER_HEADLESS=true`(默认 headful,便于扫码登录)。
|
|
172
|
+
|
|
173
|
+
**如何自定义操作蒙层品牌?**
|
|
174
|
+
设置环境变量 `BOSS_CLI_AGENT_BRAND=你的品牌名`。
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 数据目录
|
|
179
|
+
|
|
180
|
+
| 路径 | 内容 |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| `~/.boss-cli/.cache/` | Cookie、浏览器用户数据 |
|
|
183
|
+
| `~/.boss-cli/jd/` | `boss jd` 缓存的岗位描述 |
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 开发
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
npm run build # 编译到 dist/
|
|
191
|
+
npm run dev # build + 交互模式
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 发布
|
|
197
|
+
|
|
198
|
+
仓库通过 GitHub Actions 自动发布,工作流文件是 `.github/workflows/tag-publish.yml`。
|
|
199
|
+
|
|
200
|
+
发布新版本时,本地只需要更新 `package.json` 版本号、提交代码、创建并推送 `v*` tag:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
git tag -a v0.6.0 -m "v0.6.0"
|
|
204
|
+
git push origin main
|
|
205
|
+
git push origin v0.6.0
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
tag 推送后,workflow 会自动安装依赖、构建、检查 npm 版本、发布 `@joohw/boss-cli`、更新 `latest` dist-tag,并创建或更新 GitHub Release。npm 发布依赖仓库 Secret `NPM_TOKEN`,本地不需要手动执行 `npm publish`。
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## 许可
|
|
213
|
+
|
|
214
|
+
[GPL-3.0](./LICENSE)
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## 相关链接
|
|
219
|
+
|
|
220
|
+
- 官网:[boss-cli.com](https://boss-cli.com)
|
|
221
|
+
- npm:[@joohw/boss-cli](https://www.npmjs.com/package/@joohw/boss-cli)
|
|
222
|
+
- GitHub:[joohw/boss-cli](https://github.com/joohw/boss-cli)
|
|
223
|
+
- 问题反馈:[Issues](https://github.com/joohw/boss-cli/issues)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Browser, Page } from 'puppeteer-core';
|
|
2
|
+
/**
|
|
3
|
+
* 在 {@link ensureBrowserSession} 之后返回当前已连接的 Browser;
|
|
4
|
+
* 用于工具内单次获取句柄,避免与异步 ensure 不同步的 `getBrowser()` 竞态。
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureAndGetBrowser(): Promise<Browser | null>;
|
|
7
|
+
export declare function ensureBrowserSession(): Promise<void>;
|
|
8
|
+
export declare function getBrowserRef(): Browser | null;
|
|
9
|
+
export declare function getPageRef(): Page | null;
|
|
10
|
+
/**
|
|
11
|
+
* 将当前会话的主操作页设为 `page`(须属于已连接的 `browserRef`)。
|
|
12
|
+
* 供“导航/打开页面”类流程在新建或选中标签后同步,便于其它工具通过 `getPageRef` 复用。
|
|
13
|
+
*/
|
|
14
|
+
export declare function setSessionPage(page: Page): void;
|
|
15
|
+
/** 进程退出时断开 CDP,避免残留子进程 */
|
|
16
|
+
export declare function disconnectBrowserSession(): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* 仅断开与浏览器的 CDP 连接,但不主动关闭浏览器进程。
|
|
19
|
+
* 用于 `boss login` 这类“需要用户继续在浏览器里操作”的场景:
|
|
20
|
+
* CLI 可以立刻退出,而浏览器窗口仍保留给用户完成登录。
|
|
21
|
+
*
|
|
22
|
+
* 必须在 disconnect 后对 Chrome 子进程 `unref`,否则 Node 会因子进程仍存活而无法退出。
|
|
23
|
+
*
|
|
24
|
+
* 注意:**绝不调用 `browser.close()`**——历史上在 disconnect 抛错时误走 close 会导致退出 CLI 时浏览器被关掉。
|
|
25
|
+
*/
|
|
26
|
+
export declare function detachBrowserSession(): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=browser_session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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;AAwHpD;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAGnE;AAED,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwC1D;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"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { clearSpawnedChromeProcessRef, connectBrowser } from './cdp_browser.js';
|
|
2
|
+
import { installBossBrowserPageGuards, installBossPageGuards } from '../common/boss_page_guards.js';
|
|
3
|
+
let browserRef = null;
|
|
4
|
+
let pageRef = null;
|
|
5
|
+
let connectPromise = null;
|
|
6
|
+
function attachDisconnectedHandler(b) {
|
|
7
|
+
b.once('disconnected', () => {
|
|
8
|
+
if (browserRef === b) {
|
|
9
|
+
browserRef = null;
|
|
10
|
+
pageRef = null;
|
|
11
|
+
console.error('[boss-cli] 与浏览器断开连接(窗口关闭或进程退出);下次使用工具时会自动重连。');
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 选一个「主」标签:避免始终把 `pages()[0]` 当主页——用户常在第二个及以后的 Boss 标签上操作,
|
|
17
|
+
* 而第一个是 `about:blank` 或残留空页时,错误地读到 blank 会让登录/页面检查类操作误判。
|
|
18
|
+
*/
|
|
19
|
+
async function pickOrCreatePage(b) {
|
|
20
|
+
const pages = (await b.pages()).filter((p) => !p.isClosed());
|
|
21
|
+
if (pages.length === 0) {
|
|
22
|
+
return b.newPage();
|
|
23
|
+
}
|
|
24
|
+
const urls = await Promise.all(pages.map((p) => {
|
|
25
|
+
try {
|
|
26
|
+
return p.url();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
const zhipin = pages.find((p, i) => {
|
|
33
|
+
const u = urls[i] ?? '';
|
|
34
|
+
return u.length > 0 && u !== 'about:blank' && u.includes('zhipin.com');
|
|
35
|
+
});
|
|
36
|
+
if (zhipin) {
|
|
37
|
+
return zhipin;
|
|
38
|
+
}
|
|
39
|
+
const nonBlank = pages.find((p, i) => {
|
|
40
|
+
const u = urls[i] ?? '';
|
|
41
|
+
return u.length > 0 && u !== 'about:blank';
|
|
42
|
+
});
|
|
43
|
+
if (nonBlank) {
|
|
44
|
+
return nonBlank;
|
|
45
|
+
}
|
|
46
|
+
return pages[0];
|
|
47
|
+
}
|
|
48
|
+
async function closeRedundantBlankPages(b, keep) {
|
|
49
|
+
const pages = (await b.pages()).filter((p) => !p.isClosed());
|
|
50
|
+
if (pages.length <= 1)
|
|
51
|
+
return;
|
|
52
|
+
const urls = await Promise.all(pages.map((p) => {
|
|
53
|
+
try {
|
|
54
|
+
return p.url();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return '';
|
|
58
|
+
}
|
|
59
|
+
}));
|
|
60
|
+
const blankPages = pages.filter((_, i) => {
|
|
61
|
+
const u = urls[i] ?? '';
|
|
62
|
+
return u === '' || u === 'about:blank';
|
|
63
|
+
});
|
|
64
|
+
if (blankPages.length === 0)
|
|
65
|
+
return;
|
|
66
|
+
const hasNonBlank = pages.some((_, i) => {
|
|
67
|
+
const u = urls[i] ?? '';
|
|
68
|
+
return u !== '' && u !== 'about:blank';
|
|
69
|
+
});
|
|
70
|
+
for (const p of blankPages) {
|
|
71
|
+
if (p === keep)
|
|
72
|
+
continue;
|
|
73
|
+
if (!hasNonBlank && p === blankPages[0])
|
|
74
|
+
continue;
|
|
75
|
+
try {
|
|
76
|
+
await p.close({ runBeforeUnload: false });
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* ignore */
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function isSessionHealthy() {
|
|
84
|
+
return !!(browserRef?.connected && pageRef && !pageRef.isClosed());
|
|
85
|
+
}
|
|
86
|
+
async function establishSession() {
|
|
87
|
+
const prev = browserRef;
|
|
88
|
+
if (prev) {
|
|
89
|
+
try {
|
|
90
|
+
prev.removeAllListeners('disconnected');
|
|
91
|
+
await prev.close();
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
/* 已断开时忽略 */
|
|
95
|
+
}
|
|
96
|
+
browserRef = null;
|
|
97
|
+
pageRef = null;
|
|
98
|
+
}
|
|
99
|
+
const b = await connectBrowser();
|
|
100
|
+
browserRef = b;
|
|
101
|
+
attachDisconnectedHandler(b);
|
|
102
|
+
await installBossBrowserPageGuards(b);
|
|
103
|
+
pageRef = await pickOrCreatePage(b);
|
|
104
|
+
await installBossPageGuards(pageRef);
|
|
105
|
+
await closeRedundantBlankPages(b, pageRef);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 在 {@link ensureBrowserSession} 之后返回当前已连接的 Browser;
|
|
109
|
+
* 用于工具内单次获取句柄,避免与异步 ensure 不同步的 `getBrowser()` 竞态。
|
|
110
|
+
*/
|
|
111
|
+
export async function ensureAndGetBrowser() {
|
|
112
|
+
await ensureBrowserSession();
|
|
113
|
+
return getBrowserRef();
|
|
114
|
+
}
|
|
115
|
+
export async function ensureBrowserSession() {
|
|
116
|
+
if (browserRef?.connected) {
|
|
117
|
+
await installBossBrowserPageGuards(browserRef);
|
|
118
|
+
if (pageRef && !pageRef.isClosed()) {
|
|
119
|
+
try {
|
|
120
|
+
const u = pageRef.url();
|
|
121
|
+
if (u === 'about:blank' || u === '') {
|
|
122
|
+
const preferred = await pickOrCreatePage(browserRef);
|
|
123
|
+
if (preferred !== pageRef && !(preferred.url() === 'about:blank')) {
|
|
124
|
+
pageRef = preferred;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
await closeRedundantBlankPages(browserRef, pageRef);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* ignore */
|
|
131
|
+
}
|
|
132
|
+
await installBossPageGuards(pageRef);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
pageRef = await pickOrCreatePage(browserRef);
|
|
136
|
+
await installBossPageGuards(pageRef);
|
|
137
|
+
await closeRedundantBlankPages(browserRef, pageRef);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (connectPromise) {
|
|
141
|
+
await connectPromise;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
connectPromise = (async () => {
|
|
145
|
+
if (isSessionHealthy())
|
|
146
|
+
return;
|
|
147
|
+
await establishSession();
|
|
148
|
+
})();
|
|
149
|
+
try {
|
|
150
|
+
await connectPromise;
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
connectPromise = null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
export function getBrowserRef() {
|
|
157
|
+
return browserRef?.connected ? browserRef : null;
|
|
158
|
+
}
|
|
159
|
+
export function getPageRef() {
|
|
160
|
+
if (!pageRef || pageRef.isClosed())
|
|
161
|
+
return null;
|
|
162
|
+
if (!browserRef?.connected)
|
|
163
|
+
return null;
|
|
164
|
+
return pageRef;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 将当前会话的主操作页设为 `page`(须属于已连接的 `browserRef`)。
|
|
168
|
+
* 供“导航/打开页面”类流程在新建或选中标签后同步,便于其它工具通过 `getPageRef` 复用。
|
|
169
|
+
*/
|
|
170
|
+
export function setSessionPage(page) {
|
|
171
|
+
if (!browserRef?.connected)
|
|
172
|
+
return;
|
|
173
|
+
try {
|
|
174
|
+
if (page.browser() !== browserRef)
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (page.isClosed())
|
|
181
|
+
return;
|
|
182
|
+
pageRef = page;
|
|
183
|
+
}
|
|
184
|
+
/** 进程退出时断开 CDP,避免残留子进程 */
|
|
185
|
+
export async function disconnectBrowserSession() {
|
|
186
|
+
const b = browserRef;
|
|
187
|
+
if (!b)
|
|
188
|
+
return;
|
|
189
|
+
try {
|
|
190
|
+
b.removeAllListeners('disconnected');
|
|
191
|
+
await b.close();
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
/* ignore */
|
|
195
|
+
}
|
|
196
|
+
browserRef = null;
|
|
197
|
+
pageRef = null;
|
|
198
|
+
clearSpawnedChromeProcessRef();
|
|
199
|
+
}
|
|
200
|
+
function unrefBrowserChildProcess(proc) {
|
|
201
|
+
if (!proc)
|
|
202
|
+
return;
|
|
203
|
+
try {
|
|
204
|
+
proc.unref();
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
/* ignore */
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* 仅断开与浏览器的 CDP 连接,但不主动关闭浏览器进程。
|
|
212
|
+
* 用于 `boss login` 这类“需要用户继续在浏览器里操作”的场景:
|
|
213
|
+
* CLI 可以立刻退出,而浏览器窗口仍保留给用户完成登录。
|
|
214
|
+
*
|
|
215
|
+
* 必须在 disconnect 后对 Chrome 子进程 `unref`,否则 Node 会因子进程仍存活而无法退出。
|
|
216
|
+
*
|
|
217
|
+
* 注意:**绝不调用 `browser.close()`**——历史上在 disconnect 抛错时误走 close 会导致退出 CLI 时浏览器被关掉。
|
|
218
|
+
*/
|
|
219
|
+
export async function detachBrowserSession() {
|
|
220
|
+
const b = browserRef;
|
|
221
|
+
if (!b)
|
|
222
|
+
return;
|
|
223
|
+
let proc;
|
|
224
|
+
try {
|
|
225
|
+
proc = typeof b.process === 'function' ? b.process() : undefined;
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
proc = undefined;
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
b.removeAllListeners('disconnected');
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
233
|
+
const anyB = b;
|
|
234
|
+
if (typeof anyB.disconnect === 'function') {
|
|
235
|
+
await Promise.resolve(anyB.disconnect());
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
/* 仍不 close;仅断开失败时依赖下方 unref 与进程退出行为 */
|
|
240
|
+
}
|
|
241
|
+
unrefBrowserChildProcess(proc ?? null);
|
|
242
|
+
clearSpawnedChromeProcessRef();
|
|
243
|
+
browserRef = null;
|
|
244
|
+
pageRef = null;
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=browser_session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser_session.js","sourceRoot":"","sources":["../../src/browser/browser_session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type Browser, type CDPSession, type Page } from 'puppeteer-core';
|
|
2
|
+
/**
|
|
3
|
+
* 固定的远程调试端口:boss-cli 使用独立的 user-data-dir,因此可以稳定占用一个端口,
|
|
4
|
+
* 让多个命令直接通过 `http://127.0.0.1:<port>/json/version` 复用同一只浏览器。
|
|
5
|
+
* 可用 `BOSS_BROWSER_REMOTE_DEBUGGING_PORT` 覆盖。
|
|
6
|
+
*/
|
|
7
|
+
export declare const REMOTE_DEBUGGING_PORT: number;
|
|
8
|
+
export declare function clearSpawnedChromeProcessRef(): void;
|
|
9
|
+
/** 最近一次启动是否为无头(仅本进程内、与当前会话一致时有效)。 */
|
|
10
|
+
export declare function wasLastChromeLaunchHeadless(): boolean;
|
|
11
|
+
/** 减轻「正受到自动测试软件的控制」提示与常见自动化特征(非万能,站点仍可能用其它方式检测)。手动开 Chrome 并接 CDP 时可复用。 */
|
|
12
|
+
export declare const LAUNCH_ARGS_LESS_AUTOMATION: readonly ["--disable-infobars"];
|
|
13
|
+
/** 仅用于本地调试:尽量放宽同源/CORS 限制,便于跨域 iframe/canvas 处理。 */
|
|
14
|
+
export declare const LAUNCH_ARGS_ALLOW_ALL_CORS: readonly ["--disable-web-security", "--allow-running-insecure-content"];
|
|
15
|
+
export type ConnectBrowserOptions = {
|
|
16
|
+
/** 用于启动本机 Chrome/Edge */
|
|
17
|
+
executablePath?: string;
|
|
18
|
+
/** 启动浏览器时复用的用户数据目录(登录态/缓存等) */
|
|
19
|
+
userDataDir?: string;
|
|
20
|
+
/** 启动浏览器时指定 profile(如 `Default` / `Profile 1`) */
|
|
21
|
+
profileDirectory?: string;
|
|
22
|
+
/** 默认 `false`(有界面)。也可用环境变量 `BOSS_BROWSER_HEADLESS=true` 开无头。 */
|
|
23
|
+
headless?: boolean;
|
|
24
|
+
/** 仅本地调试用:放宽同源/CORS 策略(高风险,默认关闭)。 */
|
|
25
|
+
allowAllCors?: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* 启动本机浏览器(puppeteer-core 底层为 Chrome DevTools Protocol)。
|
|
29
|
+
*
|
|
30
|
+
* 环境变量(可选):
|
|
31
|
+
* - `CHROME_PATH` / `PUPPETEER_EXECUTABLE_PATH` — 启动本机浏览器可执行文件路径(高于自动探测)
|
|
32
|
+
* - `BOSS_BROWSER_USER_DATA_DIR` — 启动浏览器时复用的用户数据目录;未设置时默认 `~/.boss-cli/.cache/browser-data`
|
|
33
|
+
* - `BOSS_BROWSER_PROFILE_DIRECTORY` — 启动浏览器时指定 profile(如 `Default`)
|
|
34
|
+
* - `BOSS_BROWSER_REMOTE_DEBUGGING_PORT` — 远程调试端口(默认 53470);同一 user-data-dir 跨命令复用该端口
|
|
35
|
+
* - `BOSS_BROWSER_ALLOW_ALL_CORS` — 设为 `true` 时附加放宽同源/CORS 的启动参数(仅调试)
|
|
36
|
+
* - `BOSS_BROWSER_DISABLE_GPU` — 设为 `true` 时附加 `--disable-gpu`
|
|
37
|
+
*
|
|
38
|
+
* 若以上均未设置,会按系统尝试常见 Chrome / Edge / Chromium 安装路径。
|
|
39
|
+
* - `BOSS_BROWSER_HEADLESS` — 设为 `true` 时启用无头;默认**有界面**。
|
|
40
|
+
* - `BOSS_BROWSER_VIEWPORT_WIDTH` / `BOSS_BROWSER_VIEWPORT_HEIGHT` — 启动时显式指定视口;未设置时不覆盖浏览器窗口尺寸
|
|
41
|
+
*/
|
|
42
|
+
/** 启动浏览器时的默认视口(与环境变量一致);截图恢复时 `viewport()` 为 null 也可用其兜底。 */
|
|
43
|
+
export declare function defaultViewportFromEnv(): {
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
};
|
|
47
|
+
export declare function connectBrowser(options?: ConnectBrowserOptions): Promise<Browser>;
|
|
48
|
+
/** 对某一页创建原生 CDP Session(需要低层域如 `Network.*`、`Fetch.*` 时使用)。 */
|
|
49
|
+
export declare function createPageCDPSession(page: Page): Promise<CDPSession>;
|
|
50
|
+
//# sourceMappingURL=cdp_browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cdp_browser.d.ts","sourceRoot":"","sources":["../../src/browser/cdp_browser.ts"],"names":[],"mappings":"AAIA,OAAkB,EAAE,KAAK,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAQrF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAOhC,CAAC;AAML,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD;AAED,qCAAqC;AACrC,wBAAgB,2BAA2B,IAAI,OAAO,CAErD;AAwJD,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,iCAE9B,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;AAYD,wBAAsB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,CA2H1F;AAED,8DAA8D;AAC9D,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAE1E"}
|