@reconcrap/boss-recommend-mcp 1.3.38 → 2.0.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.
Files changed (85) hide show
  1. package/README.md +53 -33
  2. package/package.json +61 -9
  3. package/skills/boss-recommend-pipeline/SKILL.md +4 -0
  4. package/src/chat-mcp.js +1333 -0
  5. package/src/chat-runtime-config.js +559 -0
  6. package/src/cli.js +1095 -196
  7. package/src/core/browser/index.js +378 -0
  8. package/src/core/capture/index.js +298 -0
  9. package/src/core/cv-acquisition/index.js +219 -0
  10. package/src/core/greet-quota/index.js +54 -0
  11. package/src/core/infinite-list/index.js +459 -0
  12. package/src/core/reporting/legacy-csv.js +332 -0
  13. package/src/core/run/index.js +286 -0
  14. package/src/core/screening/index.js +1166 -0
  15. package/src/core/self-heal/index.js +848 -0
  16. package/src/domains/chat/cards.js +129 -0
  17. package/src/domains/chat/constants.js +183 -0
  18. package/src/domains/chat/detail.js +1369 -0
  19. package/src/domains/chat/index.js +7 -0
  20. package/src/domains/chat/jobs.js +334 -0
  21. package/src/domains/chat/page-guard.js +88 -0
  22. package/src/domains/chat/roots.js +56 -0
  23. package/src/domains/chat/run-service.js +1101 -0
  24. package/src/domains/recommend/actions.js +457 -0
  25. package/src/domains/recommend/cards.js +228 -0
  26. package/src/domains/recommend/constants.js +141 -0
  27. package/src/domains/recommend/detail.js +341 -0
  28. package/src/domains/recommend/filters.js +581 -0
  29. package/src/domains/recommend/index.js +10 -0
  30. package/src/domains/recommend/jobs.js +232 -0
  31. package/src/domains/recommend/refresh.js +204 -0
  32. package/src/domains/recommend/roots.js +78 -0
  33. package/src/domains/recommend/run-service.js +903 -0
  34. package/src/domains/recommend/scopes.js +245 -0
  35. package/src/domains/recruit/actions.js +277 -0
  36. package/src/domains/recruit/cards.js +67 -0
  37. package/src/domains/recruit/constants.js +130 -0
  38. package/src/domains/recruit/detail.js +414 -0
  39. package/src/domains/recruit/index.js +9 -0
  40. package/src/domains/recruit/instruction-parser.js +451 -0
  41. package/src/domains/recruit/refresh.js +40 -0
  42. package/src/domains/recruit/roots.js +68 -0
  43. package/src/domains/recruit/run-service.js +580 -0
  44. package/src/domains/recruit/search.js +1149 -0
  45. package/src/index.js +578 -419
  46. package/src/recommend-mcp.js +1257 -0
  47. package/src/recruit-mcp.js +1035 -0
  48. package/src/adapters.js +0 -3079
  49. package/src/boss-chat.js +0 -1037
  50. package/src/pipeline.js +0 -2249
  51. package/src/recommend-healing-config.js +0 -131
  52. package/src/recommend-healing-rules.json +0 -261
  53. package/src/self-heal.js +0 -2237
  54. package/src/test-adapters-runtime.js +0 -628
  55. package/src/test-boss-chat.js +0 -3196
  56. package/src/test-index-async.js +0 -498
  57. package/src/test-parser.js +0 -742
  58. package/src/test-pipeline.js +0 -2703
  59. package/src/test-run-state.js +0 -152
  60. package/src/test-self-heal.js +0 -224
  61. package/vendor/boss-chat-cli/README.md +0 -134
  62. package/vendor/boss-chat-cli/package.json +0 -53
  63. package/vendor/boss-chat-cli/src/app.js +0 -1501
  64. package/vendor/boss-chat-cli/src/browser/chat-page.js +0 -3562
  65. package/vendor/boss-chat-cli/src/cli.js +0 -1713
  66. package/vendor/boss-chat-cli/src/mcp/server.js +0 -149
  67. package/vendor/boss-chat-cli/src/mcp/tool-runtime.js +0 -193
  68. package/vendor/boss-chat-cli/src/runtime/async-run-state.js +0 -260
  69. package/vendor/boss-chat-cli/src/runtime/interaction.js +0 -102
  70. package/vendor/boss-chat-cli/src/runtime/run-control.js +0 -102
  71. package/vendor/boss-chat-cli/src/services/chrome-client.js +0 -107
  72. package/vendor/boss-chat-cli/src/services/llm.js +0 -1292
  73. package/vendor/boss-chat-cli/src/services/llm.test.js +0 -326
  74. package/vendor/boss-chat-cli/src/services/profile-store.js +0 -173
  75. package/vendor/boss-chat-cli/src/services/report-store.js +0 -317
  76. package/vendor/boss-chat-cli/src/services/resume-capture.js +0 -469
  77. package/vendor/boss-chat-cli/src/services/resume-network.js +0 -727
  78. package/vendor/boss-chat-cli/src/services/state-store.js +0 -90
  79. package/vendor/boss-chat-cli/src/utils/customer-key.js +0 -82
  80. package/vendor/boss-recommend-screen-cli/boss-recommend-screen-cli.cjs +0 -6927
  81. package/vendor/boss-recommend-screen-cli/scripts/capture-full-resume-canvas.cjs +0 -817
  82. package/vendor/boss-recommend-screen-cli/scripts/stitch_resume_chunks.py +0 -141
  83. package/vendor/boss-recommend-screen-cli/test-recoverable-resume-failures.cjs +0 -2294
  84. package/vendor/boss-recommend-search-cli/src/cli.js +0 -1698
  85. package/vendor/boss-recommend-search-cli/src/test-job-selection.js +0 -211
@@ -1,152 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import {
6
- RUN_MODE_ASYNC,
7
- RUN_STATE_PAUSED,
8
- RUN_STAGE_SCREEN,
9
- RUN_STATE_COMPLETED,
10
- RUN_STATE_QUEUED,
11
- RUN_STATE_RUNNING,
12
- cleanupExpiredRuns,
13
- createRunId,
14
- createRunStateSnapshot,
15
- getRunsDir,
16
- readRunState,
17
- touchRunHeartbeat,
18
- updateRunProgress,
19
- updateRunState,
20
- writeRunState
21
- } from "./run-state.js";
22
-
23
- function withTempHome(testFn) {
24
- const previous = process.env.BOSS_RECOMMEND_HOME;
25
- const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "boss-recommend-run-state-"));
26
- process.env.BOSS_RECOMMEND_HOME = tempHome;
27
- try {
28
- testFn(tempHome);
29
- } finally {
30
- if (previous === undefined) {
31
- delete process.env.BOSS_RECOMMEND_HOME;
32
- } else {
33
- process.env.BOSS_RECOMMEND_HOME = previous;
34
- }
35
- fs.rmSync(tempHome, { recursive: true, force: true });
36
- }
37
- }
38
-
39
- function testRunStateLifecycle() {
40
- withTempHome(() => {
41
- const runId = createRunId();
42
- const queued = writeRunState(createRunStateSnapshot({
43
- runId,
44
- mode: RUN_MODE_ASYNC,
45
- state: RUN_STATE_QUEUED,
46
- stage: "preflight",
47
- context: {
48
- workspace_root: "C:/workspace",
49
- instruction: "筛选有 MCP 经验候选人",
50
- confirmation: {
51
- final_confirmed: true
52
- }
53
- },
54
- control: {
55
- pause_requested: false
56
- },
57
- resume: {
58
- checkpoint_path: `C:/workspace/.state/${runId}.checkpoint.json`,
59
- pause_control_path: `C:/workspace/.state/${runId}.json`,
60
- output_csv: "C:/workspace/result.csv"
61
- }
62
- }));
63
- assert.equal(queued.run_id, runId);
64
- assert.equal(queued.state, RUN_STATE_QUEUED);
65
- assert.equal(queued.context.workspace_root, "C:/workspace");
66
- assert.equal(queued.resume.output_csv, "C:/workspace/result.csv");
67
- assert.equal(queued.control.cancel_requested, false);
68
-
69
- const running = updateRunState(runId, {
70
- state: RUN_STATE_RUNNING,
71
- stage: RUN_STAGE_SCREEN,
72
- last_message: "screening in progress"
73
- });
74
- assert.equal(running.state, RUN_STATE_RUNNING);
75
- assert.equal(running.stage, RUN_STAGE_SCREEN);
76
- const heartbeatBeforeProgress = running.heartbeat_at;
77
-
78
- const progressed = updateRunProgress(runId, {
79
- processed: 7,
80
- passed: 2,
81
- skipped: 5,
82
- greet_count: 1
83
- });
84
- assert.equal(progressed.progress.processed, 7);
85
- assert.equal(progressed.progress.passed, 2);
86
- assert.equal(progressed.progress.skipped, 5);
87
- assert.equal(progressed.progress.greet_count, 1);
88
- assert.equal(progressed.heartbeat_at, heartbeatBeforeProgress);
89
-
90
- const paused = updateRunState(runId, {
91
- state: RUN_STATE_PAUSED,
92
- control: {
93
- pause_requested: true,
94
- pause_requested_at: "2026-01-01T00:00:00.000Z",
95
- pause_requested_by: "pause_recommend_pipeline_run",
96
- cancel_requested: true
97
- },
98
- resume: {
99
- output_csv: "C:/workspace/result-partial.csv",
100
- last_paused_at: "2026-01-01T00:00:01.000Z"
101
- }
102
- });
103
- assert.equal(paused.state, RUN_STATE_PAUSED);
104
- assert.equal(paused.control.pause_requested, true);
105
- assert.equal(paused.control.pause_requested_by, "pause_recommend_pipeline_run");
106
- assert.equal(paused.control.cancel_requested, true);
107
- assert.equal(paused.resume.output_csv, "C:/workspace/result-partial.csv");
108
-
109
- const heartbeated = touchRunHeartbeat(runId, "still running");
110
- assert.equal(heartbeated.last_message, "still running");
111
- assert.equal(Date.parse(heartbeated.heartbeat_at) >= Date.parse(heartbeatBeforeProgress), true);
112
-
113
- const completed = updateRunState(runId, {
114
- state: RUN_STATE_COMPLETED,
115
- stage: "finalize",
116
- result: {
117
- status: "COMPLETED",
118
- result: {
119
- processed_count: 7
120
- }
121
- }
122
- });
123
- assert.equal(completed.state, RUN_STATE_COMPLETED);
124
- assert.equal(completed.result.status, "COMPLETED");
125
-
126
- const reloaded = readRunState(runId);
127
- assert.equal(reloaded.state, RUN_STATE_COMPLETED);
128
- assert.equal(reloaded.progress.processed, 7);
129
- });
130
- }
131
-
132
- function testRunStateCleanup() {
133
- withTempHome(() => {
134
- const runId = createRunId();
135
- writeRunState(createRunStateSnapshot({ runId, mode: RUN_MODE_ASYNC }));
136
- const runFile = path.join(getRunsDir(), `${runId}.json`);
137
- const oldSeconds = Math.floor((Date.now() - 3 * 24 * 60 * 60 * 1000) / 1000);
138
- fs.utimesSync(runFile, oldSeconds, oldSeconds);
139
-
140
- const cleaned = cleanupExpiredRuns(1000);
141
- assert.equal(cleaned.removed.some((item) => item.endsWith(`${runId}.json`)), true);
142
- assert.equal(fs.existsSync(runFile), false);
143
- });
144
- }
145
-
146
- function main() {
147
- testRunStateLifecycle();
148
- testRunStateCleanup();
149
- console.log("run-state tests passed");
150
- }
151
-
152
- main();
@@ -1,224 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import fs from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import { __testables as indexTestables } from "./index.js";
6
- import { runRecommendSelfHeal, __testables as selfHealTestables } from "./self-heal.js";
7
-
8
- const {
9
- handleRequest,
10
- setRunSelfHealImplForTests
11
- } = indexTestables;
12
-
13
- const TOOL_RUN_RECOMMEND_SELF_HEAL = "run_recommend_self_heal";
14
-
15
- function makeToolCall(id, name, args = {}) {
16
- return {
17
- jsonrpc: "2.0",
18
- id,
19
- method: "tools/call",
20
- params: {
21
- name,
22
- arguments: args
23
- }
24
- };
25
- }
26
-
27
- async function readToolPayload(response) {
28
- return response?.result?.structuredContent;
29
- }
30
-
31
- async function callTool(name, args, id = 1) {
32
- const response = await handleRequest(makeToolCall(id, name, args), process.cwd());
33
- return {
34
- payload: await readToolPayload(response),
35
- response
36
- };
37
- }
38
-
39
- async function testToolsListShouldIncludeSelfHeal() {
40
- const response = await handleRequest({ jsonrpc: "2.0", id: 1, method: "tools/list", params: {} }, process.cwd());
41
- const tools = response?.result?.tools || [];
42
- assert.equal(tools.some((tool) => tool?.name === TOOL_RUN_RECOMMEND_SELF_HEAL), true);
43
- }
44
-
45
- async function testIndexShouldRouteSelfHealTool() {
46
- setRunSelfHealImplForTests(async () => ({ status: "HEALTHY", message: "ok" }));
47
- try {
48
- const { payload } = await callTool(TOOL_RUN_RECOMMEND_SELF_HEAL, {}, 2);
49
- assert.equal(payload?.status, "HEALTHY");
50
- } finally {
51
- setRunSelfHealImplForTests(null);
52
- }
53
- }
54
-
55
- async function testScanShouldCreateRepairSession() {
56
- const previousHome = process.env.BOSS_RECOMMEND_HOME;
57
- const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "boss-recommend-self-heal-home-"));
58
- process.env.BOSS_RECOMMEND_HOME = tempHome;
59
- try {
60
- const result = await runRecommendSelfHeal(
61
- { workspaceRoot: process.cwd(), args: { mode: "scan" } },
62
- {
63
- scanRuntimeSurface: async () => ({
64
- selector_checks: [
65
- {
66
- rule_id: "filter_trigger",
67
- path: ["frame", "filter_trigger"],
68
- root: "frame",
69
- matches: [
70
- { selector: ".filter-label-wrap", index: 0, count: 0 },
71
- { selector: ".recommend-filter.op-filter", index: 1, count: 1 }
72
- ]
73
- }
74
- ],
75
- network_checks: [],
76
- side_effect_summary: { opened_candidate_detail: false }
77
- })
78
- }
79
- );
80
- assert.equal(result.status, "NEED_CONFIRMATION");
81
- assert.equal(typeof result.repair_session_id, "string");
82
- assert.equal(result.proposed_repairs.length, 1);
83
- const sessionPath = path.join(selfHealTestables.getSelfHealSessionsDir(), `${result.repair_session_id}.json`);
84
- assert.equal(fs.existsSync(sessionPath), true);
85
- } finally {
86
- if (previousHome === undefined) {
87
- delete process.env.BOSS_RECOMMEND_HOME;
88
- } else {
89
- process.env.BOSS_RECOMMEND_HOME = previousHome;
90
- }
91
- fs.rmSync(tempHome, { recursive: true, force: true });
92
- }
93
- }
94
-
95
- async function testOptionalSelectorMissShouldNotBecomeDrift() {
96
- const drifts = selfHealTestables.analyzeSelectorChecks([
97
- {
98
- rule_id: "featured_cards",
99
- path: ["frame", "featured_cards"],
100
- root: "frame",
101
- required: false,
102
- report_on_no_match: false,
103
- skipped: false,
104
- matches: [
105
- { selector: "li.geek-info-card", index: 0, count: 0 }
106
- ]
107
- }
108
- ]);
109
- assert.equal(drifts.length, 0);
110
- }
111
-
112
- async function testApplyShouldRequireConfirmation() {
113
- const previousHome = process.env.BOSS_RECOMMEND_HOME;
114
- const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "boss-recommend-self-heal-apply-home-"));
115
- process.env.BOSS_RECOMMEND_HOME = tempHome;
116
- try {
117
- const scanResult = await runRecommendSelfHeal(
118
- { workspaceRoot: process.cwd(), args: { mode: "scan" } },
119
- {
120
- scanRuntimeSurface: async () => ({
121
- selector_checks: [
122
- {
123
- rule_id: "filter_trigger",
124
- path: ["frame", "filter_trigger"],
125
- root: "frame",
126
- matches: [
127
- { selector: ".filter-label-wrap", index: 0, count: 0 },
128
- { selector: ".recommend-filter.op-filter", index: 1, count: 1 }
129
- ]
130
- }
131
- ],
132
- network_checks: [],
133
- side_effect_summary: null
134
- })
135
- }
136
- );
137
- const result = await runRecommendSelfHeal({
138
- workspaceRoot: process.cwd(),
139
- args: {
140
- mode: "apply",
141
- repair_session_id: scanResult.repair_session_id
142
- }
143
- });
144
- assert.equal(result.status, "FAILED");
145
- assert.equal(result.error?.code, "SELF_HEAL_CONFIRMATION_REQUIRED");
146
- } finally {
147
- if (previousHome === undefined) {
148
- delete process.env.BOSS_RECOMMEND_HOME;
149
- } else {
150
- process.env.BOSS_RECOMMEND_HOME = previousHome;
151
- }
152
- fs.rmSync(tempHome, { recursive: true, force: true });
153
- }
154
- }
155
-
156
- async function testApplyShouldUpdateRulesFile() {
157
- const previousHome = process.env.BOSS_RECOMMEND_HOME;
158
- const previousRulesPath = process.env.BOSS_RECOMMEND_HEALING_RULES_FILE;
159
- const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "boss-recommend-self-heal-rules-home-"));
160
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "boss-recommend-self-heal-rules-"));
161
- const rulesSourcePath = path.join(process.cwd(), "src", "recommend-healing-rules.json");
162
- const tempRulesPath = path.join(tempDir, "recommend-healing-rules.json");
163
- fs.copyFileSync(rulesSourcePath, tempRulesPath);
164
- process.env.BOSS_RECOMMEND_HOME = tempHome;
165
- process.env.BOSS_RECOMMEND_HEALING_RULES_FILE = tempRulesPath;
166
- try {
167
- const scanResult = await runRecommendSelfHeal(
168
- { workspaceRoot: process.cwd(), args: { mode: "scan" } },
169
- {
170
- scanRuntimeSurface: async () => ({
171
- selector_checks: [
172
- {
173
- rule_id: "filter_trigger",
174
- path: ["frame", "filter_trigger"],
175
- root: "frame",
176
- matches: [
177
- { selector: ".filter-label-wrap", index: 0, count: 0 },
178
- { selector: ".recommend-filter.op-filter", index: 1, count: 1 }
179
- ]
180
- }
181
- ],
182
- network_checks: [],
183
- side_effect_summary: null
184
- })
185
- }
186
- );
187
- const result = await runRecommendSelfHeal({
188
- workspaceRoot: process.cwd(),
189
- args: {
190
- mode: "apply",
191
- repair_session_id: scanResult.repair_session_id,
192
- confirm_apply: true
193
- }
194
- });
195
- assert.equal(result.status, "REPAIRED");
196
- const updatedRules = JSON.parse(fs.readFileSync(tempRulesPath, "utf8"));
197
- assert.equal(updatedRules.selectors.frame.filter_trigger[0], ".recommend-filter.op-filter");
198
- } finally {
199
- if (previousHome === undefined) {
200
- delete process.env.BOSS_RECOMMEND_HOME;
201
- } else {
202
- process.env.BOSS_RECOMMEND_HOME = previousHome;
203
- }
204
- if (previousRulesPath === undefined) {
205
- delete process.env.BOSS_RECOMMEND_HEALING_RULES_FILE;
206
- } else {
207
- process.env.BOSS_RECOMMEND_HEALING_RULES_FILE = previousRulesPath;
208
- }
209
- fs.rmSync(tempHome, { recursive: true, force: true });
210
- fs.rmSync(tempDir, { recursive: true, force: true });
211
- }
212
- }
213
-
214
- async function main() {
215
- await testToolsListShouldIncludeSelfHeal();
216
- await testIndexShouldRouteSelfHealTool();
217
- await testScanShouldCreateRepairSession();
218
- await testOptionalSelectorMissShouldNotBecomeDrift();
219
- await testApplyShouldRequireConfirmation();
220
- await testApplyShouldUpdateRulesFile();
221
- console.log("self-heal tests passed");
222
- }
223
-
224
- await main();
@@ -1,134 +0,0 @@
1
- # boss-chat
2
-
3
- 基于 Chrome DevTools Protocol 和 OpenAI 兼容 LLM 的 Boss 直聘聊天页教育筛选与自动沟通 CLI。
4
-
5
- ## 功能
6
-
7
- - 连接已登录、已打开聊天页的 Chrome
8
- - 遍历聊天列表客户卡片,读取教育信息
9
- - 用自定义 `baseUrl + apiKey + model` 调用大模型判断是否符合教育要求
10
- - 命中时自动生成简短话术并写入聊天框,随后发送
11
- - 默认记录已处理客户,避免重复触达
12
- - 支持选择从`未读`或`全部`列表开始处理
13
- - 支持 `--dry-run` 先验证页面稳定性和命中效果
14
-
15
- ## 依赖
16
-
17
- - Node.js(建议 18+)
18
- - Google Chrome(需开启远程调试端口)
19
- - npm 包依赖:
20
- - `chrome-remote-interface@^0.33.3`
21
-
22
- ## 使用前准备
23
-
24
- 1. 用远程调试模式启动 Chrome:
25
-
26
- ```powershell
27
- chrome.exe --remote-debugging-port=9222
28
- ```
29
-
30
- 2. 登录 Boss 直聘并打开聊天页:
31
-
32
- ```text
33
- https://www.zhipin.com/web/chat/index
34
- ```
35
-
36
- 3. 全局安装:
37
-
38
- ```powershell
39
- npm install -g @reconcrap/boss-chat-cli
40
- ```
41
-
42
- 也可以直接用 `npx`(适合 agent 平台托管 MCP 时):
43
-
44
- ```powershell
45
- npx -y -p @reconcrap/boss-chat-cli@latest boss-chat-mcp
46
- ```
47
-
48
- ## 运行
49
-
50
- 首次运行会交互式询问教育要求、话术样例、LLM 参数等配置;每次运行也可选择从`未读`或`全部`开始:
51
-
52
- ```powershell
53
- boss-chat run
54
- ```
55
-
56
- 建议先用 dry-run:
57
-
58
- ```powershell
59
- boss-chat run --dry-run --targetCount 3
60
- ```
61
-
62
- ## MCP Agent 集成(openclaw / codex / trae-cn)
63
-
64
- 包内已内置 MCP stdio server,可直接被三类平台调用:
65
-
66
- - `openclaw-boss-chat-mcp`
67
- - `codex-boss-chat-mcp`
68
- - `trae-cn-boss-chat-mcp`
69
- - 通用入口:`boss-chat-mcp`
70
-
71
- ### 工具列表
72
-
73
- - `health_check`: 检查服务是否可用
74
- - `start_run`: 启动异步任务,返回 `run_id`
75
- - `get_run`: 查询任务状态
76
- - `pause_run`: 暂停任务
77
- - `resume_run`: 继续任务
78
- - `cancel_run`: 取消任务
79
-
80
- ### 平台配置示例
81
-
82
- 项目里提供了三份可直接复制的模板:
83
-
84
- - `configs/mcp/openclaw.json`
85
- - `configs/mcp/codex.json`
86
- - `configs/mcp/trae-cn.json`
87
-
88
- 三份配置都通过 `npx` 拉取最新包并启动对应 MCP 入口,例如:
89
-
90
- ```json
91
- {
92
- "mcpServers": {
93
- "boss-chat": {
94
- "command": "npx",
95
- "args": ["-y", "-p", "@reconcrap/boss-chat-cli@latest", "boss-chat-mcp"]
96
- }
97
- }
98
- }
99
- ```
100
-
101
- > 不同平台的 MCP 配置文件路径可能不同,但 `command + args` 可直接复用。
102
-
103
- ## 运行中控制
104
-
105
- 程序运行时可以直接用键盘控制:
106
-
107
- - `p`: 暂停;再次按 `p` 或按 `r` 继续
108
- - `r`: 继续运行
109
- - `q`: 请求停止,当前步骤结束后安全退出
110
- - `Ctrl+C`: 请求停止,当前步骤结束后安全退出
111
-
112
- 停止后仍会写入本次运行报告,已记录的客户状态也会保留。
113
-
114
- ## 常用参数
115
-
116
- - `--profile <name>`: 使用指定 profile
117
- - `--dry-run`: 只检查和生成文案,不实际发送
118
- - `--no-state`: 不记录已处理客户
119
- - `--targetCount <n>`: 覆盖本次检查人数
120
- - `--educationRequirement <text>`: 覆盖教育要求
121
- - `--messageSample <text>`: 覆盖话术样例
122
- - `--start-from <unread|all>`: 本次从未读或全部列表开始
123
- - `--baseurl <url>`: 覆盖 LLM base URL
124
- - `--apikey <key>`: 覆盖 LLM API key
125
- - `--model <name>`: 覆盖 LLM 模型
126
- - `--port <n>`: 覆盖 Chrome 远程调试端口
127
-
128
- ## 数据目录
129
-
130
- 运行产生的数据默认保存在项目下的 `.boss-chat/`:
131
-
132
- - `profiles/`: 保存 profile 配置
133
- - `state/`: 保存已处理客户状态
134
- - `reports/`: 保存每次运行的 JSON 报告
@@ -1,53 +0,0 @@
1
- {
2
- "name": "@reconcrap/boss-chat-cli",
3
- "version": "1.1.0",
4
- "description": "Boss chat education screening and outreach CLI with MCP agent bridge",
5
- "type": "module",
6
- "bin": {
7
- "boss-chat": "src/cli.js",
8
- "boss-chat-mcp": "src/mcp/server.js",
9
- "openclaw-boss-chat-mcp": "src/mcp/server.js",
10
- "codex-boss-chat-mcp": "src/mcp/server.js",
11
- "trae-cn-boss-chat-mcp": "src/mcp/server.js"
12
- },
13
- "main": "./src/cli.js",
14
- "files": [
15
- "src/",
16
- "configs/",
17
- "README.md"
18
- ],
19
- "scripts": {
20
- "start": "node ./src/cli.js run",
21
- "start:mcp": "node ./src/mcp/server.js",
22
- "test": "node --test"
23
- },
24
- "keywords": [
25
- "boss",
26
- "zhipin",
27
- "chrome-devtools",
28
- "cli",
29
- "automation",
30
- "mcp",
31
- "openclaw",
32
- "codex",
33
- "trae-cn"
34
- ],
35
- "author": "",
36
- "license": "MIT",
37
- "engines": {
38
- "node": ">=18.0.0"
39
- },
40
- "publishConfig": {
41
- "access": "public"
42
- },
43
- "repository": {
44
- "type": "git",
45
- "url": ""
46
- },
47
- "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.18.1",
49
- "chrome-remote-interface": "^0.33.3",
50
- "sharp": "^0.34.5",
51
- "zod": "^4.1.12"
52
- }
53
- }