🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

B站刷榜免费模型 ShingStars/dsh-bili-free-scroll

DeepSeek Harness
ShingStars15 天前有提交已提供中文文档扫描:含敏感能力

自动刷B站日报,并用免费模型跑完流程

29.3/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add ShingStars/dsh-bili-free-scroll
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · platform
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 15 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 145 处,展示前 98 条)
  • 读取本地文件
    bili/index.js:119
    try { myVer = String(JSON.parse(readFileSync(join(pluginDir, '..', 'package.json'), 'utf8')).version || '') } catch { myVer = '' }
  • 读取本地文件
    bili/index.js:141
    if (existsSync(win)) return win
  • 读取本地文件
    bili/index.js:144
    for (const d of readdirSync(lib)) {
  • 读取本地文件
    bili/index.js:147
    if (existsSync(p)) return p
  • 读取本地文件
    bili/index.js:153
    try { return readdirSync(sitePkgs(venvRoot)).some((n) => n.startsWith(prefix)) } catch { return false }
  • 读取本地文件
    bili/index.js:160
    const venvReadyNow = () => existsSync(venvPython()) && missingVenvDeps().length === 0
  • 写入本地文件
    bili/index.js:178
    writeFileSync(overrideFile, JSON.stringify(cur, null, 2), 'utf8')
  • 写入本地文件
    bili/index.js:183
    mkdirSync(outDir, { recursive: true })
  • 写入本地文件
    bili/index.js:187
    try { appendFileSync(logFile, line + '\n', 'utf8') } catch { }
  • 写入本地文件
    bili/index.js:1005
    try { writeFileSync(file, yml.join('\n'), 'utf8'); return file } catch (e) { log(`写 overlay 失败:${e?.message ?? e}`); return null }
  • 写入本地文件
    bili/index.js:1048
    writeFileSync(f, [
  • 执行外部命令来自配置/变量
    bili/index.js:1086
    const child = spawn(dsh.command, args, {
  • 写入本地文件
    bili/index.js:1113
    try { appendFileSync(logFile, toText(buf), 'utf8') } catch { }
  • 执行外部命令固定命令
    bili/index.js:1219
    const c = spawn('uv', ['--version'], { windowsHide: true, stdio: 'ignore' })
  • 执行外部命令来自配置/变量
    bili/index.js:1233
    const c = spawn(cmd, ['--version'], { windowsHide: true, stdio: 'ignore' })
  • 执行外部命令来自配置/变量
    bili/index.js:1242
    try { c = spawn(cmd, args, { cwd: stateDir, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'], env: uvEnv() }) }
  • 删除本地文件
    bili/index.js:1295
    try { rmSync(bak, { force: true }) } catch { }
  • 执行外部命令来自配置/变量
    bili/index.js:1318
    c = spawn(cmd, args, { cwd: stateDir, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'],
  • 执行外部命令来自配置/变量
    bili/index.js:1613
    try { child = spawn(cmd, args, { detached: true, stdio: 'ignore' }) } catch (e) { resolve(String(e?.message ?? e)); return }
  • 请求外部主机registry.npmjs.org
    bili/index.js:1635
    const r = await fetch('https://registry.npmjs.org/dsh-bili-scroll/latest', { signal: ctrl.signal })
  • 发起网络请求
    bili/index.js:1635
    const r = await fetch('https://registry.npmjs.org/dsh-bili-scroll/latest', { signal: ctrl.signal })
  • 读取本地文件
    bili/lib/hostdeps.mjs:40
    for (const n of readdirSync(join(npm, '@deepseek-ai'))) {
  • 读取本地文件
    bili/lib/hostdeps.mjs:53
    for (const p of readdirSync(join(dshHome, 'profiles'))) {
  • 读取本地文件
    bili/lib/hostdeps.mjs:68
    if (!existsSync(pkgFile)) return null
  • 读取本地文件
    bili/lib/hostdeps.mjs:69
    const pkg = JSON.parse(readFileSync(pkgFile, 'utf8'))
  • 读取本地文件
    bili/lib/hostdeps.mjs:76
    return existsSync(file) ? pathToFileURL(file).href : null
  • 读取本地文件
    bili/lib/mcp.mjs:16
    const PKG = (() => { try { return JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) } catch { return {} } })()
  • 执行外部命令来自配置/变量
    bili/lib/mcp.mjs:36
    this.proc = spawn(command, args, {
  • 读取本地文件
    bili/lib/verify.mjs:44
    if (!existsSync(f)) return null
  • 读取本地文件
    bili/lib/verify.mjs:46
    const c = JSON.parse(readFileSync(f, 'utf8'))
  • 发起网络请求
    bili/lib/verify.mjs:62
    const r = await fetch(url, { headers })
  • 读取本地文件
    bili/lib/verify.mjs:120
    if (!existsSync(seenFile)) return { checked: [], skipped: 0, text: '⚠️ 判重表还没生成,没什么可复核的' }
  • 读取本地文件
    bili/lib/verify.mjs:124
    const rows = parseSeen(readFileSync(seenFile, 'utf8'))
  • 读取本地文件
    bili/lib/verify.mjs:130
    try { state = JSON.parse(readFileSync(stateFile, 'utf8')) } catch { }
  • 写入本地文件
    bili/lib/verify.mjs:152
    try { writeFileSync(stateFile, JSON.stringify(state, null, 2), 'utf8') } catch { }
  • 读取本地文件
    bili/lib/verify.mjs:168
    if (!existsSync(f)) return null
  • 写入本地文件
    bili/lib/verify.mjs:169
    writeFileSync(f, readFileSync(f, 'utf8').replace(/ *$/, '') + '\n' + text + '\n', 'utf8')
  • 写入本地文件
    bili/lib/state.mjs:50
    mkdirSync(dir, { recursive: true })
  • 读取本地文件
    bili/lib/state.mjs:55
    try { return JSON.parse(readFileSync(file, 'utf8')) } catch { return fallback }
  • 写入本地文件
    bili/lib/state.mjs:59
    writeFileSync(file, JSON.stringify(value, null, 2), 'utf8')
  • 读取本地文件
    bili/lib/state.mjs:70
    if (!existsSync(from)) { log(`缺文件:${from}`); continue }
  • 读取本地文件
    bili/lib/state.mjs:71
    if (!overwrite && existsSync(to)) continue
  • 读取本地文件
    bili/lib/state.mjs:72
    if (overwrite && existsSync(to) && readFileSync(from, 'utf8') === readFileSync(to, 'utf8')) continue
  • 读取本地文件
    bili/lib/state.mjs:72
    if (overwrite && existsSync(to) && readFileSync(from, 'utf8') === readFileSync(to, 'utf8')) continue
  • 写入本地文件
    bili/lib/state.mjs:73
    copyFileSync(from, to)
  • 读取本地文件
    bili/lib/state.mjs:85
    try { if (existsSync(home)) return home } catch { }
  • 写入本地文件
    bili/lib/state.mjs:113
    writeFileSync(home, newText, 'utf8'); writeFileSync(ledger, hShip, 'utf8')
  • 写入本地文件
    bili/lib/state.mjs:119
    if (hLast !== hShip) writeFileSync(ledger, hShip, 'utf8')
  • 写入本地文件
    bili/lib/state.mjs:124
    writeFileSync(fresh, newText, 'utf8')
  • 发起网络请求
    bili/lib/login.mjs:45
    const r = await fetch(SPI, { headers: { 'User-Agent': UA } })
  • 发起网络请求
    bili/lib/login.mjs:54
    const r = await fetch(GEN, { headers: { 'User-Agent': UA } })
  • 发起网络请求
    bili/lib/login.mjs:63
    const res = await fetch(pollUrl(key), { headers: { 'User-Agent': UA }, redirect: 'manual' })
  • 写入本地文件
    bili/lib/login.mjs:79
    mkdirSync(stateDir, { recursive: true })
  • 写入本地文件
    bili/lib/login.mjs:81
    writeFileSync(file, JSON.stringify({
  • 执行外部命令来自配置/变量
    bili/lib/login.mjs:97
    child = spawn(pythonPath || 'python', ['-c', code, url, png], { cwd: stateDir, windowsHide: true })
  • 读取本地文件
    bili/lib/login.mjs:99
    const done = () => { try { resolve(existsSync(png) ? png : null) } catch { resolve(null) } }
  • 读取本地文件
    bili/lib/uvfetch.mjs:33
    return createHash('sha256').update(readFileSync(file)).digest('hex')
  • 发起网络请求
    bili/lib/uvfetch.mjs:45
    const r = await fetch(source.url + '.sha256')
  • 读取本地文件
    bili/lib/uvfetch.mjs:55
    try { entries = readdirSync(dir, { withFileTypes: true }) } catch { return null }
  • 执行外部命令来自配置/变量
    bili/lib/uvfetch.mjs:69
    const r = spawnSync(cmd, args, { stdio: 'ignore' })
  • 读取本地文件
    bili/lib/uvfetch.mjs:83
    if (existsSync(target)) return target
  • 写入本地文件
    bili/lib/uvfetch.mjs:85
    mkdirSync(dir, { recursive: true })
  • 删除本地文件递归
    bili/lib/uvfetch.mjs:87
    rmSync(tmp, { recursive: true, force: true })
  • 写入本地文件
    bili/lib/uvfetch.mjs:88
    mkdirSync(tmp, { recursive: true })
  • 请求外部主机pypi.tuna.tsinghua.edu.cn
    bili/lib/uvfetch.mjs:100
    const r = await fetch('https://pypi.tuna.tsinghua.edu.cn/pypi/uv/json')
  • 发起网络请求
    bili/lib/uvfetch.mjs:100
    const r = await fetch('https://pypi.tuna.tsinghua.edu.cn/pypi/uv/json')
  • 发起网络请求
    bili/lib/uvfetch.mjs:124
    const res = await fetch(s.url)
  • 写入本地文件
    bili/lib/uvfetch.mjs:126
    await pipeline(Readable.fromWeb(res.body), createWriteStream(s.file))
  • 读取本地文件
    bili/lib/uvfetch.mjs:127
    const mb = (statSync(s.file).size / 1048576).toFixed(1)
  • 写入本地文件
    bili/lib/uvfetch.mjs:144
    copyFileSync(hit, target)
  • 写入本地文件
    bili/lib/uvfetch.mjs:145
    try { chmodSync(target, 0o755) } catch { }
  • 执行外部命令来自配置/变量
    bili/lib/uvfetch.mjs:147
    const r = spawnSync(target, ['--version'], { stdio: 'ignore' })
  • 删除本地文件递归
    bili/lib/uvfetch.mjs:150
    rmSync(tmp, { recursive: true, force: true })
  • 删除本地文件递归
    bili/lib/uvfetch.mjs:158
    rmSync(tmp, { recursive: true, force: true })
  • 发起网络请求
    models/src/forward.js:568
    const target = http.request({
  • 发起网络请求
    models/src/chan-relay.js:146
    const target = http.request({
  • 发起网络请求
    models/src/egress.js:106
    if (relay === null) return fetch(url, init)
  • 发起网络请求
    models/src/egress.js:114
    return fetch(`http://${RELAY_HOST}:${relay.port}${target.pathname}${target.search}`, { ...init, headers })
  • 执行外部命令来自配置/变量
    models/src/egress.js:163
    child = spawn(binary, ['-d', dir, '-f', configPath], { windowsHide: true, stdio: 'ignore' })
  • 发起网络请求
    models/src/egress.js:288
    const outgoing = http.request({
  • 发起网络请求
    models/src/egress.js:813
    const request = http.request(
  • 发起网络请求
    models/src/eac.js:86
    if (typeof lane.fetch === 'function') return lane.fetch(url, { method, headers, body, signal })
  • 发起网络请求
    models/src/eac.js:90
    const request = transport.request({
  • 发起网络请求
    models/src/eac-login.js:26
    response = await fetch(`${root}/auth/poll?link=${encodeURIComponent(link)}&retain=1`, {
  • 发起网络请求
    models/src/eac-login.js:47
    await fetch(`${credential.base.replace(/ v1 ?$/, '')}/auth/ack?link=${encodeURIComponent(link)}`, {
  • 发起网络请求
    models/src/eac-login.js:68
    const response = await fetch(`${credential.base.replace(/ v1 ?$/, '')}/auth/github/start?link=${encodeURIComponent(link)}`, {
  • 发起网络请求
    bili/client.js:42
    const jget = async (p) => asJson(await fetch(API + p, { credentials: 'same-origin' }))
  • 发起网络请求
    bili/client.js:43
    const jpost = async (p, body) => asJson(await fetch(API + p, {
  • 写入剪贴板
    bili/client.js:242
    await navigator.clipboard.writeText(v)
  • 删除本地文件递归
    bili/selfcheck.mjs:45
    try { rmSync(SANDBOX_HOME, { recursive: true, force: true }) } catch { }
  • 写入本地文件
    bili/selfcheck.mjs:46
    mkdirSync(SANDBOX_HOME, { recursive: true })
  • 读取本地文件
    bili/selfcheck.mjs:58
    const pkg = JSON.parse(readFileSync('./package.json', 'utf8'))
  • 删除本地文件递归
    bili/selfcheck.mjs:118
    try { rmSync(SANDBOX_HOME, { recursive: true, force: true }) } catch { }
  • 发起网络请求
    client.bili.js:23
    const jget = async (p) => asJson(await fetch(API + p, { credentials: 'same-origin' }))
  • 发起网络请求
    client.bili.js:24
    const jpost = async (p, body) => asJson(await fetch(API + p, {
  • 写入剪贴板
    client.bili.js:223
    await navigator.clipboard.writeText(v)
  • 发起网络请求
    models/src/sponsor.js:43
    try { return locks?.request ? await locks.request('ofm-sponsor-daily', claim) : claim() }
  • 写入剪贴板
    models/src/sponsor.js:62
    await navigator.clipboard.writeText(value)
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:registry.npmjs.org、pypi.tuna.tsinghua.edu.cn

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-commands@deepseek-ai/dsh-credentials@deepseek-ai/dsh-llm@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

已归档:并入 ShingStars/dsh-bili-models(v1.x 历史保留为标签 v1.0.0/v1.0.1)。已并入 dsh-bili-models,此仓库仅作历史参考,请勿安装。

README

由 DeepSeek 最新模型翻译生成
⚠ 已被取代:这份「两个插件合并成一个包」的方案在实测中被发现不稳(大 client bundle + 宿主半边启动路径,容易出现 web boot: entry did not activate)。现在改为在 dsh-bili-scroll 上只加模型选择,见 ShingStars/dsh-bili-models。本仓库保留作历史参考。 dsh-bili-free-scroll 一个 DSH(DeepSeek Harness)插件,把两件事装进同一个包: 1. 刷 B站 —— 每天在谷时自动开一轮:搜近期视频、读字幕、按你的口味挑几条、写一份日报,还能 @你、发私信、自动评论(这些按设置来)。 2. 免费模型通道 —— 内置四个账号渠道的登录 / 账号池 / 额度 / 每日签到:LobsterAI(有道)、Qoder 中国版、Cline、Raccoon(商汤)。登录一次,刷B站那一轮就能用它们的免费模型跑,不用再给 deepseek-official 配 API key。 默认模型:qodercn / qfmodel(Qwen3.8-Flash,免费、1M 上下文)。登录 Qoder 中国版后开箱即用。 它解决什么问题 刷B站的那一轮是另起一个 dsh 进程跑的(headless profile)。
展开完整文档(README 剩余 1 节)
⚠ 已被取代:这份「两个插件合并成一个包」的方案在实测中被发现不稳(大 client bundle + 宿主半边启动路径,容易出现 web boot: entry did not activate)。现在改为在 dsh-bili-scroll 上只加模型选择,见 ShingStars/dsh-bili-models。本仓库保留作历史参考。

dsh-bili-free-scroll

一个 DSH(DeepSeek Harness)插件,把两件事装进同一个包:

1. 刷 B站 —— 每天在谷时自动开一轮:搜近期视频、读字幕、按你的口味挑几条、写一份日报,还能 @你、发私信、自动评论(这些按设置来)。
2. 免费模型通道 —— 内置四个账号渠道的登录 / 账号池 / 额度 / 每日签到:LobsterAI(有道)、Qoder 中国版、Cline、Raccoon(商汤)。登录一次,刷B站那一轮就能用它们的免费模型跑,不用再给 deepseek-official 配 API key。

默认模型:qodercn / qfmodel(Qwen3.8-Flash,免费、1M 上下文)。登录 Qoder 中国版后开箱即用。

它解决什么问题

刷B站的那一轮是另起一个 dsh 进程跑的(headless profile)。那个 profile 默认写死 deepseek-official,没配 DEEPSEEK_API_KEY 时会直接失败:

llm-deepseek: no API key for provider route "deepseek-official"

这个插件把「模型」和「刷B站」放进同一个包:headless 那一轮加载插件时,插件会注册四个渠道的 LLM adapter,并把那一轮的默认模型改成你选的(默认 Qoder 中国版的免费模型),于是不需要任何 API key。

安装

dsh plugin add dsh-bili-free-scroll

装完在 DSH 设置页会多出两个区块:

- 刷B站(order=30):开关、每轮挑几条、谷时窗口、@ 谁、私信、日报级别、模型选择。
- 免费模型(order=35):四个渠道的登录、账号池、额度、每日签到、模型清单。

四个渠道的登录

在「免费模型 → 白嫖模型接入」里选渠道 → 点登录 → 浏览器里完成授权。凭据只存在本机的 $DSH_HOME/bili-free-scroll/models/ 下,不会上传到任何地方。

| 渠道 | 登录方式 | 每日签到 | 备注 |
| LobsterAI(有道) | 浏览器 | ✅ 自动 | 每日签到积分 |
| Qoder 中国版 | 浏览器 | ✅ 自动(每日 10:00 刷新) | 默认模型来源 |
| Cline | 浏览器 | ❌ | 只有免费额度 |
| Raccoon(商汤) | 手机号 | ❌(登录奖励一次性) | 服务端自动发额度 |

签到:插件启动后 30 秒检查一次,当天没领就领;跨天也会重排(不是只跑一次)。

设置项(刷B站)

| 键 | 默认 | 说明 |
| enabled | true | 总开关 |
| perDay | 5 | 每天挑几条 |
| peakValley / noon / night | true | 谷时窗口(避开高峰) |
| commentPerRound | 1 | 每轮发几条评论(0 = 不发) |
| replyToComments | false | 回评论 |
| mentionName / dmMode / dmUid | — | @ 谁 / 私信投递方式与收件人 |
| reportLevel | full | 日报详略(off = 不写文件) |
| modelProvider / modelName | qodercn / qfmodel | 刷B站那一轮用哪个模型 |
| modelEffort | 空 | 推理强度,留空 = 模型默认 |
| overlayModel | true | 把本插件的模型半边挂进那一轮 |

数据目录

全部在 $DSH_HOME/bili-free-scroll/ 下,不写插件包目录:

bili-free-scroll/
bili/ config.json duty.md out/YYYY-MM-DD.md duty.log bili_credential.json
models/ settings.json catalog.json session-map.json ...

插件依赖的 Python 环境:首次运行会在 bili/ 下建 .venv(uv),装 mcp、qrcode、pyyaml。
二维码、字幕、评论都走 B站 公开接口 + 本机 MCP 子进程。

已知限制

- B站账号等级:公开评论要求账号已转正,私信要求一定等级;不够时接口会返回 -107(账号未转正)或 21016(等级不够)。插件会如实写进日报,不会重试撞墙。
- 渠道账号风控:免费渠道可能限流 / 要求重新登录;额度规则由各家随时调整,插件只负责调用。
- 自更新已关闭:这份合并插件不会去上游仓库拉更新(避免把自己的代码覆盖成上游本体)。
要更新请从本仓库拉新版本。
- headless 环境:刷B站那一轮没有 webServer,所以「刷B站」的宿主半边不会激活(也不需要);只有模型半边会挂上。桌面端两个半边都激活。

开发

node tools/client-smoke.mjs # 验证 client bundle 能装载、两个 settings.section 都注册
node build/merge-client.mjs # 由 bili/client.js + models/client.js 生成根 client.js
node build/patch-channel-pack.mjs # 给 vendor/channel-pack/pack.js 打跨天签到补丁(幂等)

合并原理:一个 npm 包只能有一套 client(一个 bundle、一次 apply),所以两个设置页在 client.js 里合并成两个 settings.section;宿主半边则分 bili/ 与 models/ 两个入口,由根 index.js 用嵌套 ctx.inject 分别挂载 —— 谁缺服务谁不激活,互不拖累。

来源与许可

本插件是两份上游的合并裁剪版,均以 MIT 许可发布:

- c1overzz/dsh-bili-scroll(0.1.11)—— 刷B站的全部功能、MCP 工具、日报、设置页。
- Ebony-Vinyl/dsh-our-free-model(2.5.5)—— 渠道包、账号池、额度与登录;本仓库只保留四个渠道。
- 渠道包的原始出处:gitee.com/iJetLi/dsh-deepseek-harness-codearts(Jet,MIT)。

详见 NOTICE.md。本仓库自己的代码同样以 MIT 发布。
预览分享卡片长什么样 ↓ShingStars/dsh-bili-free-scroll
分享 · DeepSeek Harness Hub
ShingStars/dsh-bili-free-scroll

自动刷B站日报,并用免费模型跑完流程

这是你的仓库?认领条目

回到顶部