mirror of
https://github.com/geekgeekrun/geekgeekrun.git
synced 2026-05-25 18:20:14 +08:00
- Add recruiter-side automation core and run-core entry - Extend sqlite-plugin with candidate info + contact logs - Add UI routes/pages, IPC handlers, progress + log panel - Document current status and plans under plan/ Made-with: Cursor
215 lines
12 KiB
Markdown
215 lines
12 KiB
Markdown
# 招聘端调试工具
|
||
|
||
> **定位**:用于在沟通页手动调试简历相关操作(在线简历、附件简历、下载 PDF 等),以及 LLM 简历筛选(Rubric 评估、Rubric 生成)。与正式运行的 `bossChatPageMain` 使用完全一致的技术栈(Puppeteer + ghost-cursor + Canvas hook)。
|
||
> 最后更新:2026-03-18
|
||
|
||
---
|
||
|
||
## 1. 概述
|
||
|
||
招聘端调试工具是一套**独立于自动化主流程**的调试环境,可单独启动浏览器到 BOSS 沟通页,然后通过 GUI 按钮逐条执行调试命令,验证:
|
||
|
||
- 在线简历的打开、关闭、Canvas hook 提取
|
||
- 附件简历的请求、同意、预览与下载
|
||
- 各类弹窗的关闭(意向沟通、在线简历等)
|
||
|
||
**与正式运行的一致性**:所有页面操作均通过 `createHumanCursor`(ghost-cursor)拟人轨迹点击,与 `chat-page-processor.mjs` / `chat-page-resume.mjs` 的实现完全一致,便于在无自动化干扰下排查 DOM 选择器、时序问题。
|
||
|
||
---
|
||
|
||
## 2. 架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Renderer: BossDebugTool/index.vue │
|
||
│ - 启动浏览器 / 关闭浏览器 按钮 │
|
||
│ - Tab A「简历操作」:9 个调试命令按钮(获取姓名、在线简历、附件简历等) │
|
||
│ - Tab B「LLM 筛选」:提取简历文本 / 运行 Rubric / 生成 Rubric 按钮 │
|
||
│ - 统一操作日志区域 │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│ IPC: open-boss-chat-debug / boss-debug-command / close-boss-chat-debug
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Main: ipc/index.ts │
|
||
│ - 管理 bossChatDebugProcess(子进程) │
|
||
│ - 通过 stdio fd3/fd4 与 worker 通信(JSON 行协议) │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
│ spawn(..., --mode=bossChatDebugMain, stdio[3,4]=pipe)
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────┐
|
||
│ Worker: flow/BOSS_CHAT_DEBUG_MAIN/index.ts │
|
||
│ - Electron 子进程(app.dock?.hide()) │
|
||
│ - initPuppeteer + launch 非无头浏览器 │
|
||
│ - 注入 Cookie + localStorage,打开 BOSS_CHAT_PAGE_URL │
|
||
│ - 监听 fd3 读取命令,执行后通过 fd4 写回响应 │
|
||
└─────────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**进程路由**:`src/main/index.ts` 根据 `--mode=bossChatDebugMain` 加载 `flow/BOSS_CHAT_DEBUG_MAIN/index.ts`,调用 `waitForProcessHandShakeAndRunDebug()`。
|
||
|
||
---
|
||
|
||
## 3. 通信协议
|
||
|
||
### 3.1 进程间 stdio
|
||
|
||
主进程 spawn 时 `stdio: ['inherit','inherit','inherit','pipe','pipe']`:
|
||
|
||
| fd | 方向 | 用途 |
|
||
|----|------|------|
|
||
| fd3 | 主进程 → 子进程 | 主进程写入命令 |
|
||
| fd4 | 子进程 → 主进程 | 子进程写入 READY/响应 |
|
||
|
||
每条消息为 **一行 JSON**,以 `\n` 结尾。
|
||
|
||
### 3.2 命令格式(主 → 子)
|
||
|
||
```json
|
||
{ "type": "ping", "id": "abc123" }
|
||
{ "type": "open-online-resume", "id": "xyz789" }
|
||
```
|
||
|
||
- `type`(必填):命令类型
|
||
- `id`(必填):由主进程生成,用于匹配响应
|
||
|
||
### 3.3 响应格式(子 → 主)
|
||
|
||
**就绪通知**(子进程启动完成后发一次):
|
||
|
||
```json
|
||
{ "type": "READY", "ok": true }
|
||
{ "type": "READY", "ok": false, "error": "NO_BROWSER" }
|
||
```
|
||
|
||
**命令响应**:
|
||
|
||
```json
|
||
{ "id": "abc123", "ok": true, "result": { "name": "张三" } }
|
||
{ "id": "xyz789", "ok": false, "error": "未找到在线简历按钮" }
|
||
```
|
||
|
||
### 3.4 命令超时
|
||
|
||
主进程发命令后,若 30 秒内未收到响应,视为超时,返回 `{ ok: false, error: 'timeout' }`。
|
||
|
||
---
|
||
|
||
## 4. 支持的调试命令
|
||
|
||
### 4.1 Tab A — 简历操作命令
|
||
|
||
| type | 说明 | 成功时 result |
|
||
|------|------|---------------|
|
||
| `ping` | 探活 | `'pong'` |
|
||
| `get-panel-name` | 获取右侧面板当前候选人姓名 | `{ name: string }` |
|
||
| `dismiss-intent-dialog` | 关闭「意向沟通」弹窗 | `{ found: boolean }` |
|
||
| `close-online-resume` | 关闭在线简历弹窗 | `{ found: boolean }` |
|
||
| `open-online-resume` | 打开当前会话的在线简历 | `{ opened: boolean }` |
|
||
| `check-attach-resume` | 检查当前会话是否有「点击预览附件简历」按钮 | `{ hasAttachment: boolean }` |
|
||
| `request-attach-resume` | 请求附件简历(点击按钮 + 确认弹窗) | `{ requested: boolean, ... }` |
|
||
| `download-attach-resume` | 预览并下载当前会话已有的附件简历 | `{ clickedDownload: boolean, ... }` |
|
||
| `accept-incoming-attach-resume` | 同意对方发来的附件简历请求(仅当出现「是否同意」弹窗时) | `{ found: boolean, accepted: boolean }` |
|
||
|
||
**附件简历流程说明**(与 `plan/chat_page_resume_flow.md` 一致):
|
||
|
||
- **看在线简历**:`open-online-resume`,无需对方同意,点开即可。
|
||
- **下载 PDF**:需先 `request-attach-resume` → 对方同意 → PDF 作为新消息出现在聊天里 → `download-attach-resume`。
|
||
- **同意请求**:若对方先发起附件简历请求,会出现「对方想发送附件简历给您,您是否同意」弹窗,用 `accept-incoming-attach-resume` 同意。
|
||
|
||
### 4.2 Tab B — LLM 筛选命令
|
||
|
||
| type | 说明 | payload | 成功时 result |
|
||
|------|------|---------|---------------|
|
||
| `extract-resume-text` | 打开当前会话的在线简历并用 Canvas hook 提取纯文本 | 无 | `{ resumeText: string, charCount: number }` |
|
||
| `llm-screen-resume` | 对指定简历文本运行 Rubric 评估(使用当前职位的 `resumeLlmConfig`) | `{ resumeText: string, jobId?: string }` | `{ isPassed: boolean, totalScore: number, reason: string, rawResponse: string }` |
|
||
| `llm-generate-rubric` | 根据 JD 文本生成 Rubric 结构(不依赖浏览器,仅调 LLM API) | `{ sourceJd: string }` | `{ rubric: { knockouts: string[], dimensions: [...] } }` |
|
||
|
||
**命令使用说明:**
|
||
|
||
- `extract-resume-text`:在子进程(Worker)侧执行,需要浏览器已就绪且已手动选中一条会话。内部调用 `openOnlineResume` + Canvas hook 提取文本,提取完后**关闭简历弹窗**,将文本返回给主进程。
|
||
- `llm-screen-resume`:在**主进程**侧执行(不经过子进程),直接调用 `evaluateResumeByRubric`。`jobId` 用于从 `boss-jobs-config.json` 载入对应的 `resumeLlmConfig`;若不传 `jobId`,则 UI 侧提供手动填写 Rubric JSON 的区域,将其序列化为 payload 传入。
|
||
- `llm-generate-rubric`:同样在**主进程**侧执行,调用 `generateRubricFromJd`,读取 `boss-llm.json` 中 `rubric_generation` 用途的模型(未配置时会回退到默认/第一个启用模型)。
|
||
|
||
---
|
||
|
||
## 5. 文件与入口
|
||
|
||
| 路径 | 说明 |
|
||
|------|------|
|
||
| `packages/ui/src/main/flow/BOSS_CHAT_DEBUG_MAIN/index.ts` | Worker 入口,启动浏览器并监听 stdio 命令 |
|
||
| `packages/ui/src/renderer/src/page/MainLayout/BossDebugTool/index.vue` | GUI 页面(含 Tab A 简历操作、Tab B LLM 筛选) |
|
||
| `packages/ui/src/main/flow/OPEN_SETTING_WINDOW/ipc/index.ts` | IPC 处理器:`open-boss-chat-debug`、`boss-debug-command`、`close-boss-chat-debug` |
|
||
| `packages/ui/src/renderer/src/router/index.ts` | 路由 `BossDebugTool` |
|
||
| `packages/ui/src/renderer/src/page/MainLayout/LeftNavBar/RecruiterPart.vue` | 左侧导航「招聘端调试工具」入口 |
|
||
|
||
**依赖的核心包**(与 `bossChatPageMain` 相同):
|
||
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/index.mjs`:`initPuppeteer`
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/chat-page-resume.mjs`:`openOnlineResume`、`requestAttachmentResume`、`acceptIncomingAttachResume`、`openPreviewAndDownloadPdf` 等
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/resume-extractor.mjs`:`setupCanvasTextHook`
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/constant.mjs`:选择器常量
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/humanMouse.mjs`:`createHumanCursor`
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/runtime-file-utils.mjs`:`readStorageFile`、`ensureStorageFileExist`
|
||
- `@geekgeekrun/boss-auto-browse-and-chat/llm-rubric.mjs`:`evaluateResumeByRubric`、`generateRubricFromJd`(Tab B LLM 命令,**主进程侧调用**)
|
||
|
||
**存储**:与正式流程共用 `~/.geekgeekrun/storage/boss-cookies.json`、`boss-local-storage.json`。
|
||
|
||
---
|
||
|
||
## 6. 使用流程
|
||
|
||
### 6.1 Tab A — 简历操作
|
||
|
||
1. 打开设置窗口 → 左侧导航选择「招聘端调试工具」
|
||
2. 点击「启动浏览器」→ 主进程 spawn `bossChatDebugMain` 子进程,子进程启动 Puppeteer、注入 Cookie/localStorage、打开沟通页、发 READY
|
||
3. 在 BOSS 沟通页**手动选择一条会话**(左侧会话列表点击,右侧展示该候选人)
|
||
4. 点击调试按钮执行命令,如「打开在线简历」「检查附件简历」等
|
||
5. 查看操作日志和命令返回值
|
||
6. 测试完成后点击「关闭浏览器」,主进程 kill 子进程
|
||
|
||
**注意事项**:
|
||
|
||
- 启动前需已配置浏览器路径(与推荐页/沟通页一致,若未配置会弹窗引导)
|
||
- 子进程退出(用户关闭浏览器)时,主进程会发送 `boss-chat-debug-exited` 到 Renderer,GUI 自动将状态置为「未就绪」
|
||
|
||
### 6.2 Tab B — LLM 筛选调试
|
||
|
||
Tab B 分为三个子功能区域:
|
||
|
||
**区域 1:提取简历文本**
|
||
|
||
> 依赖浏览器已就绪,且已在 BOSS 沟通页手动选中一条会话。
|
||
|
||
1. 确认浏览器已就绪,沟通页已选中目标会话
|
||
2. 点击「📄 提取当前简历文本」
|
||
3. 主进程发送 `extract-resume-text` 命令到子进程,子进程打开在线简历 → Canvas hook 提取 → 关闭弹窗 → 返回文本
|
||
4. 提取到的文本显示在下方只读 Textarea(可手动选中复制)
|
||
5. 文本自动填入「区域 2」的输入框供后续 LLM 评估使用
|
||
|
||
**区域 2:运行 Rubric 评估**
|
||
|
||
> 不依赖浏览器,直接在主进程调用 LLM API。
|
||
|
||
- **职位选择器**:下拉选择 `boss-jobs-config.json` 中已启用 `resumeLlmEnabled` 的职位,用于自动加载其 `resumeLlmConfig`
|
||
- **或**:展开「手动填写 Rubric JSON」折叠区,直接粘贴 rubric 对象(`{ knockouts, dimensions, passThreshold }`)
|
||
- **简历文本输入框**(来自区域 1 自动填充或手动粘贴)
|
||
- 点击「🤖 运行 LLM 评估」→ 主进程调用 `llm-screen-resume` → 返回结果展示:
|
||
- **通过 / 未通过** 状态标签
|
||
- 总分(如 `78 / 100`)
|
||
- 判断理由
|
||
- 展开「原始 LLM 响应」折叠区查看 raw JSON
|
||
|
||
**区域 3:生成 Rubric**
|
||
|
||
> 不依赖浏览器,直接在主进程调用 LLM API。需已配置 `boss-llm.json`。
|
||
|
||
- **JD 输入框**(`el-input` textarea):粘贴岗位描述
|
||
- 点击「✨ 生成 Rubric」→ 主进程调用 `llm-generate-rubric` → 将生成的 Rubric JSON 格式化展示在只读文本框
|
||
- 提供「📋 复制 JSON」按钮,方便直接粘贴到 `boss-jobs-config.json` 或 BossJobConfig UI
|
||
|
||
---
|
||
|
||
## 7. 与 recruiter_architecture 的关系
|
||
|
||
招聘端调试工具**不参与** daemon/worker 调度,是主进程直接 spawn 的独立子进程,用于本地开发与问题排查。架构总览(`recruiter_architecture.md`)中未单独列出,可在此文档中查阅其设计与用法。
|