@joohw/boss-cli 0.1.3 → 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.
Files changed (77) hide show
  1. package/README.md +13 -20
  2. package/dist/browser/auth.d.ts +0 -1
  3. package/dist/browser/auth.d.ts.map +1 -1
  4. package/dist/browser/auth.js +3 -19
  5. package/dist/browser/auth.js.map +1 -1
  6. package/dist/browser/browser_session.d.ts +4 -0
  7. package/dist/browser/browser_session.d.ts.map +1 -1
  8. package/dist/browser/browser_session.js +27 -14
  9. package/dist/browser/browser_session.js.map +1 -1
  10. package/dist/browser/cdp_browser.d.ts +10 -0
  11. package/dist/browser/cdp_browser.d.ts.map +1 -1
  12. package/dist/browser/cdp_browser.js +219 -11
  13. package/dist/browser/cdp_browser.js.map +1 -1
  14. package/dist/browser/chat.d.ts.map +1 -1
  15. package/dist/browser/chat.js +5 -3
  16. package/dist/browser/chat.js.map +1 -1
  17. package/dist/browser/human_delay.d.ts +88 -0
  18. package/dist/browser/human_delay.d.ts.map +1 -0
  19. package/dist/browser/human_delay.js +52 -0
  20. package/dist/browser/human_delay.js.map +1 -0
  21. package/dist/browser/index.d.ts +3 -1
  22. package/dist/browser/index.d.ts.map +1 -1
  23. package/dist/browser/index.js +3 -1
  24. package/dist/browser/index.js.map +1 -1
  25. package/dist/browser/timing.d.ts +7 -0
  26. package/dist/browser/timing.d.ts.map +1 -0
  27. package/dist/browser/timing.js +34 -0
  28. package/dist/browser/timing.js.map +1 -0
  29. package/dist/cli/banner.d.ts.map +1 -1
  30. package/dist/cli/banner.js +43 -9
  31. package/dist/cli/banner.js.map +1 -1
  32. package/dist/cli/cliRouter.d.ts.map +1 -1
  33. package/dist/cli/cliRouter.js +83 -56
  34. package/dist/cli/cliRouter.js.map +1 -1
  35. package/dist/cli/index.js +14 -1
  36. package/dist/cli/index.js.map +1 -1
  37. package/dist/config.d.ts +9 -0
  38. package/dist/config.d.ts.map +1 -1
  39. package/dist/config.js +25 -0
  40. package/dist/config.js.map +1 -1
  41. package/dist/ocr/baidu_ocr.d.ts +11 -0
  42. package/dist/ocr/baidu_ocr.d.ts.map +1 -0
  43. package/dist/ocr/baidu_ocr.js +76 -0
  44. package/dist/ocr/baidu_ocr.js.map +1 -0
  45. package/dist/ocr/index.d.ts +3 -0
  46. package/dist/ocr/index.d.ts.map +1 -0
  47. package/dist/ocr/index.js +3 -0
  48. package/dist/ocr/index.js.map +1 -0
  49. package/dist/ocr/resume_ocr.d.ts +13 -0
  50. package/dist/ocr/resume_ocr.d.ts.map +1 -0
  51. package/dist/ocr/resume_ocr.js +35 -0
  52. package/dist/ocr/resume_ocr.js.map +1 -0
  53. package/dist/toolset/index.d.ts +12 -2
  54. package/dist/toolset/index.d.ts.map +1 -1
  55. package/dist/toolset/index.js +11 -4
  56. package/dist/toolset/index.js.map +1 -1
  57. package/dist/toolset/list_candidates.d.ts.map +1 -1
  58. package/dist/toolset/list_candidates.js +12 -19
  59. package/dist/toolset/list_candidates.js.map +1 -1
  60. package/dist/toolset/login.d.ts.map +1 -1
  61. package/dist/toolset/login.js +7 -4
  62. package/dist/toolset/login.js.map +1 -1
  63. package/dist/toolset/open_chat.d.ts +4 -1
  64. package/dist/toolset/open_chat.d.ts.map +1 -1
  65. package/dist/toolset/open_chat.js +365 -25
  66. package/dist/toolset/open_chat.js.map +1 -1
  67. package/dist/toolset/send_message.d.ts +11 -1
  68. package/dist/toolset/send_message.d.ts.map +1 -1
  69. package/dist/toolset/send_message.js +120 -21
  70. package/dist/toolset/send_message.js.map +1 -1
  71. package/dist/toolset/skill.d.ts +13 -0
  72. package/dist/toolset/skill.d.ts.map +1 -0
  73. package/dist/toolset/skill.js +85 -0
  74. package/dist/toolset/skill.js.map +1 -0
  75. package/package.json +5 -2
  76. package/skills/README.md +11 -0
  77. package/skills/boss-cli/SKILL.md +58 -0
@@ -1,4 +1,74 @@
1
- import { createWaitManualLoginRequiredText, isBossChatIndexUrl, sleep, withChatPage, } from '../browser/index.js';
1
+ import { createWaitManualLoginRequiredText, isBossChatIndexUrl, randomIntInclusive, SEND_AFTER_ENTER_MS, SEND_BEFORE_RESUME_MS, SEND_INPUT_CLICK_MS, SEND_TYPING_GAP_MS, sleepRandom, typeTextWithRandomKeyDelay, withChatPage, } from '../browser/index.js';
2
+ /**
3
+ * 对方「附件简历」确认卡片上点击「同意」或「拒绝」。
4
+ * 对应按钮 disabled 时视为已处理。
5
+ */
6
+ async function runIncomingResumeCardAction(page, which) {
7
+ const currentUrl = page.url();
8
+ if (!isBossChatIndexUrl(currentUrl)) {
9
+ throw new Error('请先进入聊天列表页(/web/chat/index)并打开候选人聊天。');
10
+ }
11
+ const inCandidateChat = await page.$('.base-info-single-container');
12
+ if (!inCandidateChat) {
13
+ throw new Error('请先打开候选人聊天详情页,再操作附件简历卡片。');
14
+ }
15
+ await sleepRandom(200, 550);
16
+ const result = (await page.evaluate((w) => {
17
+ function norm(v) {
18
+ return (v ?? "").replace(/\\s+/g, " ").trim();
19
+ }
20
+ function isDisabledBtn(el) {
21
+ const cls = el.className ?? "";
22
+ if (/disabled|forbid|ban/i.test(cls))
23
+ return true;
24
+ if (el.getAttribute("disabled") !== null)
25
+ return true;
26
+ const st = window.getComputedStyle(el);
27
+ return st.pointerEvents === "none" || Number(st.opacity) < 0.35;
28
+ }
29
+ function matchesLabel(t, mode) {
30
+ if (mode === "agree") {
31
+ return t === "同意" || t.indexOf("同意") === 0;
32
+ }
33
+ return t === "拒绝" || t.indexOf("拒绝") === 0;
34
+ }
35
+ const items = Array.from(document.querySelectorAll(".chat-message-list .message-item"));
36
+ for (let i = items.length - 1; i >= 0; i--) {
37
+ const friend = items[i].querySelector(".item-friend");
38
+ if (!friend)
39
+ continue;
40
+ const title = norm(friend.querySelector(".message-card-top-title")?.textContent);
41
+ if (!title || title.indexOf("附件简历") === -1)
42
+ continue;
43
+ const buttons = friend.querySelectorAll(".message-card-buttons .card-btn");
44
+ for (let j = 0; j < buttons.length; j++) {
45
+ const btn = buttons[j];
46
+ const t = norm(btn.textContent);
47
+ if (!matchesLabel(t, w))
48
+ continue;
49
+ if (isDisabledBtn(btn)) {
50
+ return { kind: "already_handled", which: w };
51
+ }
52
+ btn.scrollIntoView({ block: "center", inline: "nearest" });
53
+ btn.click();
54
+ return { kind: "clicked", which: w };
55
+ }
56
+ }
57
+ return { kind: "not_found", which: w };
58
+ }, which));
59
+ if (result.kind === 'not_found') {
60
+ throw new Error('未找到待处理的「对方发送附件简历」确认卡片(标题需含「附件简历」)。');
61
+ }
62
+ if (result.kind === 'already_handled') {
63
+ return result.which === 'agree'
64
+ ? '对方发来的附件简历请求已处理(同意按钮已禁用)。'
65
+ : '对方发来的附件简历请求已处理(拒绝按钮已禁用)。';
66
+ }
67
+ await sleepRandom(350, 900);
68
+ return result.which === 'agree'
69
+ ? '已点击「同意」,接受对方发送的附件简历。'
70
+ : '已点击「拒绝」,拒绝接收对方附件简历。';
71
+ }
2
72
  async function runRequestOfflineResume(page) {
3
73
  try {
4
74
  const currentUrl = page.url();
@@ -31,6 +101,7 @@ async function runRequestOfflineResume(page) {
31
101
  if (!availability.found || !availability.available) {
32
102
  throw new Error('当前不可索取离线简历。通常需要双方至少各发送过一条消息后,才会变为可索取状态。');
33
103
  }
104
+ await sleepRandom(280, 720);
34
105
  const clicked = (await page.evaluate(`(() => {
35
106
  const items = Array.from(document.querySelectorAll(".operate-icon-item"));
36
107
  const target = items.find((el) => {
@@ -47,6 +118,7 @@ async function runRequestOfflineResume(page) {
47
118
  if (!clicked) {
48
119
  throw new Error('未找到“求简历”按钮,无法执行索取。');
49
120
  }
121
+ await sleepRandom(400, 980);
50
122
  const confirmed = (await page.evaluate(`(() => {
51
123
  const confirms = Array.from(document.querySelectorAll(".exchange-tooltip .boss-btn-primary.boss-btn"));
52
124
  const visible = confirms.find((el) => {
@@ -70,10 +142,12 @@ async function runRequestOfflineResume(page) {
70
142
  throw new Error(`索取离线简历失败:${message}`);
71
143
  }
72
144
  }
73
- export async function runSendChatMessage(text, alsoRequestResume = false, signal) {
74
- const messageText = text.trim();
75
- if (!messageText) {
76
- throw new Error('消息内容为空,未发送。');
145
+ export async function runSendChatMessage(options) {
146
+ const messageText = (options.text ?? '').trim();
147
+ const action = options.action;
148
+ const signal = options.signal;
149
+ if (!messageText && !action) {
150
+ throw new Error('请指定 --text 或 --action 至少其一。');
77
151
  }
78
152
  try {
79
153
  return await withChatPage(async (page) => {
@@ -81,28 +155,53 @@ export async function runSendChatMessage(text, alsoRequestResume = false, signal
81
155
  if (!isBossChatIndexUrl(currentUrl)) {
82
156
  throw new Error('请先进入聊天列表页(/web/chat/index)并打开候选人聊天。');
83
157
  }
84
- const input = await page.$('#boss-chat-editor-input');
85
- if (!input) {
86
- throw new Error('未找到聊天输入框(#boss-chat-editor-input)。');
158
+ const lines = [];
159
+ if (messageText) {
160
+ const input = await page.$('#boss-chat-editor-input');
161
+ if (!input) {
162
+ throw new Error('未找到聊天输入框(#boss-chat-editor-input)。');
163
+ }
164
+ await input.click({
165
+ delay: randomIntInclusive(SEND_INPUT_CLICK_MS.min, SEND_INPUT_CLICK_MS.max),
166
+ });
167
+ await sleepRandom(60, 220, signal);
168
+ await page.keyboard.down('Control');
169
+ await page.keyboard.press('KeyA');
170
+ await page.keyboard.up('Control');
171
+ await sleepRandom(45, 180, signal);
172
+ await page.keyboard.press('Backspace');
173
+ await sleepRandom(80, 260, signal);
174
+ await typeTextWithRandomKeyDelay(page, messageText, SEND_TYPING_GAP_MS.min, SEND_TYPING_GAP_MS.max, signal);
175
+ await sleepRandom(120, 420, signal);
176
+ await page.keyboard.press('Enter');
177
+ await sleepRandom(SEND_AFTER_ENTER_MS.min, SEND_AFTER_ENTER_MS.max, signal);
178
+ lines.push(`已发送消息:${messageText}`);
87
179
  }
88
- await input.click({ delay: 20 });
89
- await page.keyboard.down('Control');
90
- await page.keyboard.press('KeyA');
91
- await page.keyboard.up('Control');
92
- await page.keyboard.press('Backspace');
93
- await page.keyboard.type(messageText, { delay: 15 });
94
- await page.keyboard.press('Enter');
95
- if (!alsoRequestResume) {
96
- return `已发送消息:${messageText}`;
180
+ if (action) {
181
+ if (lines.length > 0) {
182
+ await sleepRandom(SEND_BEFORE_RESUME_MS.min, SEND_BEFORE_RESUME_MS.max, signal);
183
+ }
184
+ switch (action) {
185
+ case 'request-resume':
186
+ lines.push(await runRequestOfflineResume(page));
187
+ break;
188
+ case 'agree-resume':
189
+ lines.push(await runIncomingResumeCardAction(page, 'agree'));
190
+ break;
191
+ case 'confuse-resume':
192
+ lines.push(await runIncomingResumeCardAction(page, 'refuse'));
193
+ break;
194
+ default: {
195
+ const _x = action;
196
+ throw new Error(`未知的 action: ${String(_x)}`);
197
+ }
198
+ }
97
199
  }
98
- await sleep(1_500, signal);
99
- const resumeLine = await runRequestOfflineResume(page);
100
- return [`已发送消息:${messageText}`, resumeLine].filter(Boolean).join('\n\n');
200
+ return lines.join('\n\n');
101
201
  });
102
202
  }
103
203
  catch (e) {
104
204
  const message = e instanceof Error ? e.message : String(e);
105
- console.error(`[boss-cli] send_chat_message error: ${message}`);
106
205
  if (e instanceof Error) {
107
206
  if (e.message.includes('浏览器会话尚未初始化')) {
108
207
  throw new Error(createWaitManualLoginRequiredText('发送消息'));
@@ -1 +1 @@
1
- {"version":3,"file":"send_message.js","sourceRoot":"","sources":["../../src/toolset/send_message.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send_message.js","sourceRoot":"","sources":["../../src/toolset/send_message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** 包内唯一 skill 目录名(与文件夹一致) */
2
+ export declare const PACKAGE_SKILL_NAME = "boss-cli";
3
+ /** 与 `dist/toolset/skill.js` 相对:包根目录下的 `skills/` */
4
+ export declare function bundledSkillsRoot(): string;
5
+ export declare function implSkillInstall(): Promise<string>;
6
+ export declare function implSkillUninstall(): Promise<string>;
7
+ /** `boss skill`:仅输出说明,不安装。 */
8
+ export declare function implSkillDescribe(): string;
9
+ /**
10
+ * `boss skill` 仅描述;`boss skill install` / `uninstall` 才改磁盘。
11
+ */
12
+ export declare function implSkillCli(tail: string[]): Promise<string>;
13
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/toolset/skill.ts"],"names":[],"mappings":"AASA,6BAA6B;AAC7B,eAAO,MAAM,kBAAkB,aAAa,CAAC;AAE7C,oDAAoD;AACpD,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC,CAiBxD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAQ1D;AAED,8BAA8B;AAC9B,wBAAgB,iBAAiB,IAAI,MAAM,CAgB1C;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBlE"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * 本 npm 包仅含一个 Agent Skill:`skills/boss-cli/` → 安装到 ~/.agents/skills/boss-cli/
3
+ */
4
+ import { existsSync } from 'node:fs';
5
+ import { cp, rm } from 'node:fs/promises';
6
+ import { dirname, join } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { ensureAppDataLayout, getAgentSkillsDir } from '../config.js';
9
+ /** 包内唯一 skill 目录名(与文件夹一致) */
10
+ export const PACKAGE_SKILL_NAME = 'boss-cli';
11
+ /** 与 `dist/toolset/skill.js` 相对:包根目录下的 `skills/` */
12
+ export function bundledSkillsRoot() {
13
+ const here = dirname(fileURLToPath(import.meta.url));
14
+ return join(here, '..', '..', 'skills');
15
+ }
16
+ function bundledSkillSourcePath() {
17
+ return join(bundledSkillsRoot(), PACKAGE_SKILL_NAME);
18
+ }
19
+ export async function implSkillInstall() {
20
+ ensureAppDataLayout();
21
+ const skillsRoot = getAgentSkillsDir();
22
+ const src = bundledSkillSourcePath();
23
+ if (!existsSync(join(src, 'SKILL.md'))) {
24
+ throw new Error(`❌ 包内缺少 ${src}/SKILL.md(本包应自带唯一 skill)`);
25
+ }
26
+ const dest = join(skillsRoot, PACKAGE_SKILL_NAME);
27
+ await rm(dest, { recursive: true, force: true }).catch(() => { });
28
+ await cp(src, dest, { recursive: true });
29
+ return [
30
+ `已安装 Agent Skill「${PACKAGE_SKILL_NAME}」`,
31
+ `目录: ${dest}`,
32
+ '',
33
+ '多数客户端已将 ~/.agents/skills 列为默认扫描路径;若未识别,请在该应用的 Skills 设置中指向上述目录。',
34
+ ].join('\n');
35
+ }
36
+ export async function implSkillUninstall() {
37
+ ensureAppDataLayout();
38
+ const dest = join(getAgentSkillsDir(), PACKAGE_SKILL_NAME);
39
+ if (!existsSync(dest)) {
40
+ throw new Error(`❌ 未安装「${PACKAGE_SKILL_NAME}」:${dest}`);
41
+ }
42
+ await rm(dest, { recursive: true, force: true });
43
+ return `已移除「${PACKAGE_SKILL_NAME}」\n${dest}`;
44
+ }
45
+ /** `boss skill`:仅输出说明,不安装。 */
46
+ export function implSkillDescribe() {
47
+ const dest = join(getAgentSkillsDir(), PACKAGE_SKILL_NAME);
48
+ return [
49
+ 'boss-cli Agent Skill(本 npm 包唯一公开 Skill)',
50
+ '',
51
+ '用途:为 Claude / Cursor 等 Agent 提供说明,指导如何配合 `boss` CLI 操作 Boss 直聘(本机 Chrome/Edge + CDP、聊天、在线简历截图、可选百度 OCR 等)。目录结构与 Anthropic Agent Skills 一致(SKILL.md)。',
52
+ '',
53
+ `安装后的目标路径: ${dest}`,
54
+ '',
55
+ '命令:',
56
+ ' boss skill 显示本说明(不写入磁盘)',
57
+ ' boss skill install 将包内 skills/boss-cli/ 复制到上述路径',
58
+ ' boss skill uninstall 删除该路径',
59
+ '',
60
+ '安装根目录默认 ~/.agents/skills,可用 BOSS_AGENT_SKILLS_DIR 设为绝对路径覆盖。',
61
+ ].join('\n');
62
+ }
63
+ /**
64
+ * `boss skill` 仅描述;`boss skill install` / `uninstall` 才改磁盘。
65
+ */
66
+ export async function implSkillCli(tail) {
67
+ if (tail.length === 0) {
68
+ return implSkillDescribe();
69
+ }
70
+ const first = tail[0]?.trim().toLowerCase() ?? '';
71
+ if (first === 'install') {
72
+ if (tail.length > 1) {
73
+ throw new Error('❌ 本包仅提供一个 skill,用法: boss skill install(不要附加参数)');
74
+ }
75
+ return implSkillInstall();
76
+ }
77
+ if (first === 'uninstall') {
78
+ if (tail.length > 1) {
79
+ throw new Error('❌ 用法: boss skill uninstall(不要附加参数)');
80
+ }
81
+ return implSkillUninstall();
82
+ }
83
+ throw new Error('❌ 用法: boss skill | boss skill install | boss skill uninstall');
84
+ }
85
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/toolset/skill.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@joohw/boss-cli",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Boss 直聘浏览器自动化 CLI(CDP + Puppeteer),供 Agent 运行时调用",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",
@@ -10,15 +10,18 @@
10
10
  },
11
11
  "files": [
12
12
  "dist",
13
+ "skills",
13
14
  "README.md",
14
15
  "AGENTS.md",
15
16
  "LICENSE"
16
17
  ],
17
18
  "scripts": {
18
19
  "build": "tsc",
19
- "dev": "npm run build && node dist/cli/index.js"
20
+ "dev": "npm run build && node dist/cli/index.js",
21
+ "test:baidu": "node --env-file=.env scripts/test-baidu-ocr.mjs"
20
22
  },
21
23
  "dependencies": {
24
+ "dotenv": "^17.4.2",
22
25
  "puppeteer-core": "^24.29.1"
23
26
  },
24
27
  "devDependencies": {
@@ -0,0 +1,11 @@
1
+ # 公开 Agent Skill(本包唯一)
2
+
3
+ 本目录仅含 **`boss-cli/`** 一处,与 [Anthropic Agent Skills](https://github.com/anthropics/skills) 格式一致,随 npm 包发布。
4
+
5
+ ```bash
6
+ boss skill # 仅打印 Skill 说明(不安装)
7
+ boss skill install # 安装到 ~/.agents/skills/boss-cli/
8
+ boss skill uninstall # 移除该目录
9
+ ```
10
+
11
+ 可用环境变量 **`BOSS_AGENT_SKILLS_DIR`** 指定安装根目录(默认为用户目录下的 `.agents/skills`)。
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: boss-cli
3
+ description: >-
4
+ Automates Boss 直聘 (zhipin.com) in a real Chrome/Edge via Puppeteer and CDP:
5
+ login, chat list, open candidate chat, online resume screenshot, and optional
6
+ Baidu OCR. Use when the user mentions boss-cli, Boss 直聘 automation, 招聘
7
+ 聊天, 候选人, 在线简历截图, or running the `boss` CLI.
8
+ ---
9
+
10
+ # Boss 直聘 CLI (`boss-cli`)
11
+
12
+ ## What this is
13
+
14
+ - **Repository**: local Node/TypeScript CLI (`boss` binary) that drives **already installed** Chrome or Edge with **puppeteer-core** (no bundled browser).
15
+ - **Not** a hosted API: the agent runs `boss` in a terminal with network access; the user must be logged in (or use `login`).
16
+
17
+ ## Alignment with Anthropic “Agent Skills”
18
+
19
+ Anthropic’s open repo [anthropics/skills](https://github.com/anthropics/skills) defines skills as **folders with `SKILL.md`** (YAML frontmatter + instructions). The cross-tool spec lives at [agentskills.io](https://agentskills.io). This file follows the same **frontmatter + body** pattern so it can be reused in Cursor, Claude Code plugins, or other Agent Skills hosts.
20
+
21
+ ## Agent Skill 安装路径
22
+
23
+ - **`boss skill`** 仅输出 Skill 说明,不安装;**`boss skill install`**(无附加参数)才复制到 **`~/.agents/skills/boss-cli/`**(Windows:`%USERPROFILE%\.agents\skills\boss-cli`)。**`boss skill uninstall`** 移除该目录。根目录可用 `BOSS_AGENT_SKILLS_DIR` 覆盖。
24
+
25
+ ## Prerequisites
26
+
27
+ - **Build**: `npm install` then `npm run build`; entry is `dist/cli/index.js` (see `package.json` `bin`).
28
+ - **Chrome/Edge path**: set `CHROME_PATH` or `PUPPETEER_EXECUTABLE_PATH` if auto-detection fails (Windows common paths are tried).
29
+ - **Credentials**: never commit secrets. Config goes to **`%USERPROFILE%\.boss-cli\.env`** and/or **cwd `.env`** (loaded in that order; cwd overrides). Baidu OCR needs `API_KEY` + `SECRET_KEY` when `BOSS_RESUME_OCR` is enabled.
30
+
31
+ ## How to run
32
+
33
+ - **Interactive REPL** (default): run `node dist/cli/index.js` or `boss` **with no arguments** → `boss> ` prompt.
34
+ - **One-shot**: `boss <subcommand> ...` (non-interactive; exits after the command).
35
+
36
+ ## Subcommands (normalize short names)
37
+
38
+ | Intent | Example |
39
+ |--------|---------|
40
+ | Login | `login` |
41
+ | List candidates | `list` |
42
+ | Open chat with candidate | `chat <name>` |
43
+ | Send message / resume actions | `send ...` |
44
+ | List JD / positions | `jd` |
45
+
46
+ Exact flags and `--action` values are defined in `src/cli/cliRouter.ts` and `help` output.
47
+
48
+ ## Automation notes for the agent
49
+
50
+ 1. Prefer **documented env vars** over hardcoding paths; read `src/config.ts` and `src/browser/cdp_browser.ts` for directories and viewport defaults.
51
+ 2. **Online resume + OCR**: flow lives in `src/toolset/open_chat.ts` and `src/ocr/`; failures should surface real errors (Baidu quota, missing keys, network).
52
+ 3. **Puppeteer `evaluate`**: this project prefers **string scripts** for `page.evaluate` / `waitForFunction` to avoid build artifacts like `__name is not defined` in the browser context (see `AGENTS.md`).
53
+ 4. Do not add silent fallbacks; match project rules in `AGENTS.md`.
54
+
55
+ ## When not to use this skill
56
+
57
+ - Tasks that only need public web scraping without a logged-in Boss account.
58
+ - Headless-only sandboxes where Chrome cannot run or CDP cannot attach (unless the user explicitly uses headless and accepts limits).