本地归档岗位 JD,匹配简历并预填官网投递表单
29/100
综合分
3
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
该插件未发布到 npm,按作者文档从 GitHub 源安装即可(静态检查只覆盖 npm 路径,不代表插件不可用)。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ZeroMadLife/boss-watch-agent该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · browser
装得上吗
作者未把包发布到 npm,只能用源码安装
插件本身没问题,是分发方式不同
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 74 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包boss-watch-agent(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/23 05:52:17
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 96 处,展示前 89 条)
- 发起网络请求extension/src/api.ts:73
return this.request("/api/v1/health", { authenticated: false }); - 发起网络请求extension/src/api.ts:77
return this.request("/api/v1/pair", { method: "POST", body: { code }, authenticated: false }); - 发起网络请求extension/src/api.ts:84
return this.request("/api/v1/applications"); - 发起网络请求extension/src/api.ts:90
return this.request(path, { method: "POST", body: snapshot }); - 发起网络请求extension/src/api.ts:98
return this.request("/api/v1/analyses/conversation", { - 发起网络请求extension/src/api.ts:105
return this.request(`/api/v1/applications/${encodeURIComponent(applicationId)}`); - 写入本地文件packages/dsh-plugin/src/application-batch.ts:122
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/application-follow-up.ts:52
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/ats-autofill-profile.ts:101
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 读取密钥环境变量packages/dsh-plugin/src/browser-controller-client.ts:28
tokenPath = process.env.BOSS_WATCH_SERVICE_TOKEN_PATH - 读取本地文件packages/dsh-plugin/src/browser-controller-client.ts:107
token = (await readFile(this.#tokenPath, 'utf8')).trim() - 发起网络请求packages/dsh-plugin/src/browser-controller-client.ts:114
response = await fetch(`${this.#origin}${path}`, { - 写入本地文件packages/dsh-plugin/src/candidate-profile.ts:77
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/feishu-projection.ts:101
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/gate-a.ts:38
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 读取本地文件packages/dsh-plugin/src/index.ts:60
const databaseReady = existsSync(databasePath) - 读取密钥环境变量packages/dsh-plugin/src/index.ts:172
const gankToken = process.env.GANKINTERVIEW_API_KEY?.trim() - 读取密钥环境变量packages/dsh-plugin/src/interview-note-client.ts:42
tokenPath = process.env.BOSS_WATCH_SERVICE_TOKEN_PATH - 读取本地文件packages/dsh-plugin/src/interview-note-client.ts:79
token = (await readFile(this.#tokenPath, 'utf8')).trim() - 发起网络请求packages/dsh-plugin/src/interview-note-client.ts:86
response = await fetch(`${this.#origin}${path}`, { - 写入本地文件packages/dsh-plugin/src/interview-note-knowledge.ts:90
await mkdir(resolve(target, '..'), { recursive: true }) - 读取本地文件packages/dsh-plugin/src/interview-note-knowledge.ts:93
const existing = await readFile(target, 'utf8') - 写入本地文件packages/dsh-plugin/src/interview-note-knowledge.ts:102
await writeFile(temporary, markdown, { encoding: 'utf8', mode: 0o600 }) - 写入本地文件packages/dsh-plugin/src/interview-note-knowledge.ts:103
await rename(temporary, target) - 写入本地文件packages/dsh-plugin/src/job-lead.ts:204
mkdirSync(dirname(path), { recursive: true }) - 发起网络请求packages/dsh-plugin/src/job-lead.ts:691
const response = await this.#fetch(url, { - 写入本地文件packages/dsh-plugin/src/job-source-import.ts:169
mkdirSync(this.#importRoot, { recursive: true }) - 读取本地文件packages/dsh-plugin/src/job-source-import.ts:260
const file = await readFile(filePath) - 写入本地文件packages/dsh-plugin/src/job-source-import.ts:371
mkdirSync(this.#importRoot, { recursive: true }) - 读取剪贴板packages/dsh-plugin/src/job-source-import.ts:379
const clipboard = await this.#readClipboard() - 写入本地文件packages/dsh-plugin/src/job-source-import.ts:386
await writeFile(filePath, clipboard, { mode: 0o600 }) - 读取剪贴板packages/dsh-plugin/src/job-source-import.ts:416
const currentClipboard = await this.#readClipboard() - 读取本地文件packages/dsh-plugin/src/job-source-import.ts:469
realpath(importRoot), - 读取本地文件packages/dsh-plugin/src/job-source-import.ts:470
realpath(filePath).catch(() => undefined), - 读取本地文件packages/dsh-plugin/src/job-source-import.ts:474
const metadata = await stat(filePath).catch(() => undefined) - 删除本地文件packages/dsh-plugin/src/job-source-import.ts:645
await unlink(filePath).catch(() => undefined) - 写入本地文件packages/dsh-plugin/src/job-watch.ts:124
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 读取本地文件packages/dsh-plugin/src/knowledge-growth.ts:52
try { entries = await readdir(directory, { withFileTypes: true }) } catch { return } - 读取密钥环境变量packages/dsh-plugin/src/local-api-client.ts:26
tokenPath = process.env.BOSS_WATCH_SERVICE_TOKEN_PATH - 发起网络请求packages/dsh-plugin/src/local-api-client.ts:41
response = await fetch(`${this.#origin}/api/v1/health`, { signal: AbortSignal.timeout(3_000) }) - 读取本地文件packages/dsh-plugin/src/local-api-client.ts:73
token = (await readFile(this.#tokenPath, 'utf8')).trim() - 发起网络请求packages/dsh-plugin/src/local-api-client.ts:80
response = await fetch(`${this.#origin}${path}`, { - 读取密钥环境变量packages/dsh-plugin/src/progress-signal-client.ts:63
tokenPath = process.env.BOSS_WATCH_SERVICE_TOKEN_PATH - 读取本地文件packages/dsh-plugin/src/progress-signal-client.ts:94
token = (await readFile(this.#tokenPath, 'utf8')).trim() - 发起网络请求packages/dsh-plugin/src/progress-signal-client.ts:101
response = await fetch(`${this.#origin}${path}`, { - 写入本地文件packages/dsh-plugin/src/recruitment-source.ts:147
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/resume-matching.ts:110
if (path !== ':memory:') mkdirSync(dirname(path), { recursive: true }) - 写入本地文件packages/dsh-plugin/src/resume-version.ts:127
if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true }); - 写入本地文件packages/dsh-plugin/src/resume-version.ts:271
mkdirSync(this.#resumeRoot, { recursive: true }); - 写入本地文件packages/dsh-plugin/src/resume-version.ts:272
mkdirSync(this.#artifactRoot, { recursive: true, mode: 0o700 }); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:330
const bytes = await readFile(current.filePath); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:381
const bytes = await readFile(artifactPath); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:400
const bytes = await readFile(artifactPath); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:409
const bytes = await readFile(filePath); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:424
info = await lstat(filePath); - 读取本地文件packages/dsh-plugin/src/resume-version.ts:433
const bytes = await readFile(filePath); - 写入本地文件packages/dsh-plugin/src/resume-version.ts:460
await writeFile(artifactPath, bytes, { flag: "wx", mode: 0o600 }); - 读取本地文件packages/dsh-plugin/src/sqlite-source.ts:177
if (!existsSync(this.#databasePath)) throw new Error('source_unavailable') - 发起网络请求src/browser/bosshunter-runtime-client.ts:26
const response = await fetch(`${this.#baseUrl}/health`, { signal: AbortSignal.timeout(3_000) }); - 发起网络请求src/browser/bosshunter-runtime-client.ts:64
const response = await fetch(`${this.#baseUrl}/eval?target=${encodeURIComponent(targetId)}`, { - 发起网络请求src/browser/bosshunter-runtime-client.ts:85
const response = await fetch(`${this.#baseUrl}/new?url=${encodeURIComponent(targetUrl.toString())}`, { - 发起网络请求src/browser/bosshunter-runtime-client.ts:95
const response = await fetch(`${this.#baseUrl}/close?target=${encodeURIComponent(targetId)}`, { - 发起网络请求src/browser/bosshunter-runtime-client.ts:105
const response = await fetch(`${this.#baseUrl}/setFiles?target=${encodeURIComponent(targetId)}`, { - 发起网络请求src/browser/bosshunter-runtime-client.ts:133
const response = await fetch(`${this.#baseUrl}${path}`, { - 读取本地文件src/browser/browser-run-controller.ts:1107
const info = await lstat(input.resumeUpload.filePath); - 读取本地文件src/browser/browser-run-controller.ts:1110
const bytes = await readFile(input.resumeUpload.filePath); - 读取本地文件src/cli.ts:41
databaseStats = await stat(databasePath); - 读取本地文件src/demo.ts:6
readFileSync(new URL("../test/fixtures/resume-request.json", import.meta.url), "utf8"), - 写入本地文件src/export/application-export.ts:141
await mkdir(dirname(outputPath), { recursive: true }); - 写入本地文件src/export/application-export.ts:144
await writeFile(temporaryPath, content, { encoding: "utf8", flag: "wx", mode: 0o600 }); - 写入本地文件src/export/application-export.ts:146
await rename(temporaryPath, outputPath); - 删除本地文件src/export/application-export.ts:156
await unlink(temporaryPath).catch(() => undefined); - 读取本地文件src/server/capture-api.ts:1059
const info = await lstat(target); - 读取本地文件src/server/capture-api.ts:1063
bytes = await readFile(target); - 写入本地文件src/server/local-api-server.ts:758
await mkdir(root, { recursive: true, mode: 0o700 }); - 写入本地文件src/server/local-api-server.ts:763
await writeFile(target, bytes, { flag: "wx", mode: 0o600 }); - 读取本地文件src/server/local-api-server.ts:766
const info = await lstat(target); - 读取本地文件src/server/local-api-server.ts:768
const existing = await readFile(target); - 写入本地文件src/server/local-api-server.ts:798
await mkdir(root, { recursive: true, mode: 0o700 }); - 写入本地文件src/server/local-api-server.ts:803
await writeFile(target, bytes, { flag: "wx", mode: 0o600 }); - 读取本地文件src/server/local-api-server.ts:806
const info = await lstat(target); - 读取本地文件src/server/local-api-server.ts:810
const existing = await readFile(target); - 写入本地文件src/server/service-token.ts:8
await mkdir(dirname(path), { recursive: true }); - 读取本地文件src/server/service-token.ts:10
const existing = (await readFile(path, "utf8")).trim(); - 写入本地文件src/server/service-token.ts:12
await chmod(path, 0o600); - 写入本地文件src/server/service-token.ts:19
await writeFile(path, token, { encoding: "utf8", mode: 0o600, flag: "wx" }); - 读取本地文件src/server/service-token.ts:22
const existing = (await readFile(path, "utf8")).trim(); - 写入本地文件src/server/service-token.ts:24
await chmod(path, 0o600); - 写入本地文件src/storage/sqlite-application-store.ts:59
if (path !== ":memory:") mkdirSync(dirname(path), { recursive: true });
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 本地归档岗位JD
- 匹配简历
- 预填官网投递表单
带审批门控的本地求职智能体,也是 DeepSeek Harness 插件,用 SQLite 跟踪,浏览器观察有边界,还能投影到飞书。
README
由 DeepSeek 最新模型翻译生成Boss Watch Agent
CI
License: MIT
一个运行在本机、集成到 DeepSeek Harness 的求职 Agent。
它把岗位收集、JD 归档、简历匹配、官网表单预填、投递记录和后续跟进放进同一条可审计流程。SQLite 保存本地事实,DSH 负责对话和工作台;登录、验证码、风控提示与最终提交始终交给用户。
当前是面向个人求职流程的早期版本,优先支持 macOS 本地开发与测试账号。它不是无人值守爬虫,也不会绕过招聘平台的安全机制。
它解决什么
招聘信源 / BOSS 当前搜索页 / 用户粘贴的内推链接 ↓ 候选岗位池与完整 JD ↓ 本地简历匹配与投递决策 ↓ 官网 ATS 预填或 BOSS 沟通准备 ↓ 用户检查并完成最终提交 ↓ SQLite 工作台 → 飞书多维表格 → 跟进提醒
日常使用不需要记工具名。可以直接在 DSH 中说:
- “开始找工作,先看今天最值得处理的岗位。”
- “这是安克创新的内推链接和内推码,先保存来源。”
- “搜索上海的 Agent 校招岗位,最多看 5 个。”
- “用最新版简历评估这个 JD,值得投就加入待投递。”
- “官网已经打开,填当前页。”
- “这家公司今天通知笔试了,记录并同步飞书。
展开完整文档(README 剩余 1 节)
Boss Watch Agent CI License: MIT 一个运行在本机、集成到 DeepSeek Harness 的求职 Agent。 它把岗位收集、JD 归档、简历匹配、官网表单预填、投递记录和后续跟进放进同一条可审计流程。SQLite 保存本地事实,DSH 负责对话和工作台;登录、验证码、风控提示与最终提交始终交给用户。 当前是面向个人求职流程的早期版本,优先支持 macOS 本地开发与测试账号。它不是无人值守爬虫,也不会绕过招聘平台的安全机制。 它解决什么 招聘信源 / BOSS 当前搜索页 / 用户粘贴的内推链接 ↓ 候选岗位池与完整 JD ↓ 本地简历匹配与投递决策 ↓ 官网 ATS 预填或 BOSS 沟通准备 ↓ 用户检查并完成最终提交 ↓ SQLite 工作台 → 飞书多维表格 → 跟进提醒 日常使用不需要记工具名。可以直接在 DSH 中说: - “开始找工作,先看今天最值得处理的岗位。” - “这是安克创新的内推链接和内推码,先保存来源。” - “搜索上海的 Agent 校招岗位,最多看 5 个。” - “用最新版简历评估这个 JD,值得投就加入待投递。” - “官网已经打开,填当前页。” - “这家公司今天通知笔试了,记录并同步飞书。” 当前能力 | 环节 | 已实现 | 边界 | | 招聘信源 | 可选校招接口请求时搜索;CSV/XLSX、剪贴板、截图和手工内推链接导入 | 不后台抓取私有文档,不把来源摘要冒充完整 JD | | BOSS 岗位 | 读取当前搜索/推荐页,低频串行打开详情并保存 JD | 依赖用户已登录的浏览器;遇验证或风控立即停止 | | 岗位工作台 | 岗位筛选、匹配证据、待办、进度、分页和批量加入待投递 | 工作台展示事实与建议,不自动执行外部动作 | | 简历 | 导入 PDF/DOCX/Markdown/TXT,保存不可变版本并在本机解析 | 原文不写入 DSH Transcript,不上传外部模型 | | 人岗匹配 | 本地规则生成技能、经历、届别、地点偏好和缺口证据 | 分数是决策辅助,不是录用概率 | | 官网 ATS | 用户打开已核验页面后,一次填写文本、下拉并上传绑定简历 | 多页表单逐页继续;协议、验证码和最终提交由用户完成 | | 投递跟踪 | SQLite 追加式时间线、状态确认、跟进提醒 | 不从官网匿名推断“通过/淘汰” | | 飞书同步 | 预览后幂等写入多维表格 | 本地事实为主,外部写入需要明确确认 | 完整工具契约和状态机见 Job Search Agent Spec。 为什么保留人工接管 招聘网站的登录态、验证码和风险控制不适合由 Agent 猜测处理。Boss Watch 把自动化停在可检查的位置: 1. 来源和 JD 先形成带哈希的本地事实。 2. 简历匹配只批准进入材料准备,不等于授权投递。 3. “填当前页”只授权当前 ATS 页的一次预填。 4. 用户检查页面并点击最终提交。 5. 投递、笔试、面试、Offer 等状态由用户确认后写入时间线。 页面文本、模型回答和旧授权都不能自行扩大权限。 架构 flowchart LR U[用户] --> D[DSH Web + 求职工作台] D --> P[Boss Watch DSH Plugin] P --> C[本机 Controller :4318] P --> S[(SQLite 事实库)] C --> B[受控 Browser Runtime] B --> W[BOSS / 招聘官网] P --> F[飞书多维表格] - packages/dsh-plugin:DSH 工具、求职 Skill、工作台和 ATS 流程。 - src/browser:固定页面动作、风险检测与浏览器接管边界。 - src/server:只监听 loopback 的 Controller 与短期上传会话。 - SQLite:岗位、JD Artifact、简历版本、匹配、审批和进度的本地事实账本。 - deepseek-harness:保持为独立的官方 clone,本仓库不复制或修改其上游源码。 本地启动 前置条件 - macOS(当前主要验证环境) - Node.js >=22.19.0 - Corepack - 一个独立的 deepseek-harness checkout,并按上游说明安装依赖 - 如需 BOSS 读取:可用的 BossHunter Browser Runtime 和人工登录状态 建议目录结构: ~/workspace/ ├─ boss-watch-agent/ └─ deepseek-harness/ 安装 git clone git@github.com:ZeroMadLife/boss-watch-agent.git cd boss-watch-agent npm install npm run dsh:plugin:install npm run build npm run dsh:plugin:build 把本地插件安装到 DSH 的 web profile: export BOSS_WATCH_DIR=/absolute/path/to/boss-watch-agent export DSH_SOURCE_DIR=/absolute/path/to/deepseek-harness cd "$DSH_SOURCE_DIR" DSH_HOME="$HOME/Library/Application Support/BossWatchAgent/dsh" \ node --import tsx/esm apps/cli/src/bin.ts \ plugin --profile web add "$BOSS_WATCH_DIR/packages/dsh-plugin" 运行 开两个终端: Terminal 1: 本机 Controller 与 SQLite cd "$BOSS_WATCH_DIR" npm run serve Terminal 2: DSH Web cd "$BOSS_WATCH_DIR" npm run dsh:dev 默认地址为 http://127.0.0.1:3080/,求职工作台位于 /boss-watch/。如果端口已占用,请明确换端口: DSH_WEB_PORT=3090 npm run dsh:dev 启动脚本默认不会自动打开新的浏览器窗口;需要显式打开时设置 DSH_OPEN_BROWSER=1。也可以直接访问终端打印的本地地址。 重新构建业务代码后必须重启 npm run serve;不要在端口占用时直接结束来源不明的进程。完整配置、插件安装和 Browser Runtime 启动方式见 DSH 本地开发 与测试账号试用手册。 数据与隐私 默认数据目录: ~/Library/Application Support/BossWatchAgent/ 其中包含 SQLite、内容寻址的简历工件和本机服务凭据。它们被排除在 Git 之外,不应复制到 Issue、日志或 DSH 上游仓库。测试和文档只使用虚构或脱敏数据。 可显式导出本地记录: npm run export -- \ --db "$HOME/Library/Application Support/BossWatchAgent/boss-watch.sqlite3" \ --out ./exports/applications.json \ --format json 导出不会自动上传或覆盖已有文件。 开发验证 npm test npm run check npm run build npm run dsh:plugin:test npm run dsh:plugin:check npm run dsh:plugin:build CI 使用固定的 DSH commit 做兼容验证;本地跟随上游新版本不代表已经兼容。升级步骤见 DSH 插件架构。 项目状态 当前重点是打通个人用户的完整求职闭环,而不是扩大无人值守自动化: - 完善不同 ATS 的字段识别、多页续填和失败 handoff; - 提升岗位去重、完整 JD 获取与匹配解释; - 收敛工作台的信息密度和批量待投递体验; - 保持 BOSS 访问低频、可中断、可审计。 问题反馈请附上脱敏后的错误码、页面类型和复现步骤,不要上传真实简历、Cookie、手机号或招聘聊天截图。 文档 - 产品与闭环规格 - DSH 本地开发 - 插件架构与页面支持 - 本地存储与飞书投影 - 测试账号试用手册 - 安全策略 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
ZeroMadLife/boss-watch-agent
本地归档岗位 JD,匹配简历并预填官网投递表单
相关插件 · 浏览器
智能体插件框架deepseek-ai/deepseek-harness
DeepSeek Harnessdsh是由 DeepSeek AI 开发的开源 agent harness智能体框架。
★ 270,422已汉化DSH
71.9
多设备 Agent 看板YaoApp/yao
✨ 所有 Agent 和工作区集中管理,覆盖你的每一台设备。任务看板追踪进度,桌面端、移动端、浏览器、API…
★ 8,147已汉化DSH
71.2
可扩展侧边栏工作台omdsh-dev/DSH-better-sidebar
DSH 的双工作台:原生右侧栏 + 自绘底部面板,并把 ctx.betterSidebar 服务开放给所有插件
★ 4,761已汉化DSH
71.1
浏览器自动化桥Tencent/BrowserSkill
你的 Agent。你的浏览器。连接,就能协作。
★ 9,967已汉化DSH
71
AI 小说创作工作台EthanYoQ/AI-Novel-Writer
AI 小说作家 / AI Novel Writer
★ 1,591已汉化DSH
70.7
智能体浏览器引擎platonai/Browser4
DeepSeek Harness 集成
★ 1,175已汉化DSH
70.4
这是你的仓库?认领条目