dsh-bili-scroll 2.1.0 → 2.2.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.
- package/CHANGELOG.md +710 -0
- package/client.js +2 -2
- package/index.js +99 -14
- package/lib/diagnose.mjs +95 -0
- package/package.json +3 -2
- package/prompts/duty.md +17 -2
- package/vendor/bilibili-mcp/mcp_server.py +185 -0
- package/LICENSE.bak-20261020 +0 -31
- package/vendor/bilibili-mcp/__pycache__/mcp_server.cpython-314.pyc +0 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,710 @@
|
|
|
1
|
+
## 2.2.0 — 2026-10-25
|
|
2
|
+
|
|
3
|
+
**两件事:看得更广,说得更像人。**
|
|
4
|
+
|
|
5
|
+
**① 不填关键词 = 刷首页推荐流**
|
|
6
|
+
|
|
7
|
+
以前留空就用内置那几组词(DeepSeek Harness / DSH 插件 …)⇒ **所有装了插件的人刷的是同一批视频**,
|
|
8
|
+
评论区就堆成一片"同款插件互相报到"。现在留空 ⇒ 用 `bili_recommend` 刷**这个账号的首页推荐流**,
|
|
9
|
+
按各自画像推,天然散开。填了关键词就照旧搜索。
|
|
10
|
+
|
|
11
|
+
- 新工具 `bili_recommend(ps)`:走 B站 首页接口(带登录凭证=这个账号的推荐),自动过滤直播 / 番剧 / 广告卡片
|
|
12
|
+
- 章程第 1 条重写:留空 ⇒ 刷推荐流、**随机挑几条**(别固定取前 N);填了 ⇒ 搜索
|
|
13
|
+
- ⚠️ **行为变化**:以前没填关键词的用户,升级后刷的东西会变(这正是目的)
|
|
14
|
+
|
|
15
|
+
**② 评论不再"每条一个味"**
|
|
16
|
+
|
|
17
|
+
八股不是靠"别写八股"治好的 —— 得给范例、还得拦。
|
|
18
|
+
|
|
19
|
+
- **评论台账**:每发一条评论,就记进 `<家>/comments.md`;下一轮开场把**最近 5 条自己发过的**喂给它,
|
|
20
|
+
并要求**别用相同开头、别套同一句式** ⇒ 它会慢慢长出自己的口癖,而不是模板
|
|
21
|
+
- ⭐ **发之前拦一道**(在 `bili_reply` 函数里,不是靠自觉):
|
|
22
|
+
· 开头八股黑名单("这条我认""值得一看""不得不说"…)
|
|
23
|
+
· 跟**自己以前发过的**太像(bigram 相似度 ≥0.55)
|
|
24
|
+
· 跟**这条视频现有热评**太像(≥0.5)—— 治撞车
|
|
25
|
+
⇒ 撞了就不发,把"为什么"和"怎么改"返回给模型;**改写一次仍撞就不发**,报告里记一行
|
|
26
|
+
· 想关掉:环境变量 `BILI_STYLE_OFF=1`
|
|
27
|
+
- 设置页人设框的说明改成"留空也能用":默认口语、短句、必带一个只有看了那条视频才说得出的细节
|
|
28
|
+
|
|
29
|
+
**修复**
|
|
30
|
+
|
|
31
|
+
- **失败不再是一句 `code=1`**:占位报告会认已知失败形态(模型提供方没注册驱动 / 没有凭据 / 找不到 dsh /
|
|
32
|
+
提示词变量没值),把"是什么 + 怎么办"写进报告顶部;认不出来仍走原来的兜底(行为不变)
|
|
33
|
+
- **同一台机器开两个宿主时,一轮只会跑一次**:新增 `run-lock.json`(pid + 时间,10 分钟自动过期,
|
|
34
|
+
写不了锁时照常跑)—— 以前网页版和桌面版同分钟到点,会把同一条视频推两遍
|
|
35
|
+
- 判重表读接口 `duty_seen_recent` 补进白名单(章程让它先查再判)
|
|
36
|
+
|
|
37
|
+
**说明**
|
|
38
|
+
|
|
39
|
+
- 这一版把 2.1.0 之后攒的改动一起带上了(推荐流 + 语感闸门 + 失败诊断 + 运行锁)。
|
|
40
|
+
- 升级后**重启一次 dsh**;家目录里的运行时脚本会按版本自动覆盖(旧的那份会备份成 `.bak-<时间戳>`)。
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2.1.0 — 2026-10-24
|
|
45
|
+
|
|
46
|
+
**能「看」视频了**:新增两个只读工具,把封面和画面帧作为图片交给模型。
|
|
47
|
+
|
|
48
|
+
字幕告诉你说了什么,画面告诉你拍了什么。对演示类 / 实操类视频(游戏、手工、教程),
|
|
49
|
+
只读字幕等于没看 —— 这一版补上这条路。
|
|
50
|
+
|
|
51
|
+
另一件事更重:**值班轮不再拥有整台电脑**。它以前跑在 stock 的 headless profile 上,
|
|
52
|
+
带文件系统、命令、联网、子代理 —— 一个没人看着的 agent,能读到本机全部会话记录。这一版把那些全关了。
|
|
53
|
+
|
|
54
|
+
**新增**
|
|
55
|
+
- `bili_cover`:取封面(等比缩到 512px 宽)。不引 Pillow、不调 ffmpeg,缩图交给 B 站图片 CDN。
|
|
56
|
+
- `bili_frames`:从 B 站自带的故事板裁 1–6 帧(每帧 480×270),可传 `at` 指定秒。
|
|
57
|
+
- 值班章程写明「什么时候该看画面」,并把**档位与证据挂钩**:写「值得看」必须读过字幕或看过画面。
|
|
58
|
+
- 白名单放行这两只(只读,不碰账号)。
|
|
59
|
+
|
|
60
|
+
**看画面这块的修复**
|
|
61
|
+
- 封面走明文 HTTP 且带 SESSDATA ⇒ 统一强制 https,图床请求不再带 Cookie。
|
|
62
|
+
- 长视频时间单位被误判成毫秒(6 小时以上的视频三帧全塌成同一张)⇒ 只按时长判断。
|
|
63
|
+
- 分P 视频只采第 1P 却报全片总时长 ⇒ 按故事板实测覆盖取帧,返回里写 `covered_sec` / `pages`。
|
|
64
|
+
- 故事板 `index` 偶发返回空(实测约 25%)⇒ 用同响应的 `pvdata` 二进制时间表兜底。
|
|
65
|
+
- 无效 BV / 格式错误的 BV 会抛原始异常 ⇒ 统一收成 `ok: false`。
|
|
66
|
+
|
|
67
|
+
### 🔴 安全:值班轮拿到了一个"没有边界"的进程(issue #96)
|
|
68
|
+
|
|
69
|
+
以前那一轮用 `--profile headless` —— 那个 profile 只关了热重载和凭证,**工具一个没动**:
|
|
70
|
+
文件读写、命令行、抓任意网页、子代理全在。而 DSH 的沙箱**只限制写、不限制读**,
|
|
71
|
+
所以它能读 `~/.dsh/sessions/**`(你的全部对话)和凭证,B站 MCP 又在沙箱外 ⇒ "读到 → 发出去"这条链是通的。
|
|
72
|
+
|
|
73
|
+
现在:
|
|
74
|
+
|
|
75
|
+
- 新建一个专用 profile **`bili-duty`**(= dsh-base + dsh-headless + 一层 patch),关掉
|
|
76
|
+
`tool-fs` / `tool-fs-search` / `tool-pwsh` / `tool-bash` / `tool-web` / `web-fetch-http` /
|
|
77
|
+
`web-search-deepseek` / subagent 全家 / workflow / skill 全家 / `agent-instructions` /
|
|
78
|
+
`plugin-manager` / `hmr` / goal 全家 / `plan-mode` / `tool-todo` / `mcp-resources`。
|
|
79
|
+
- 它还是得写日报、判重表、归档,还得转写 ⇒ 这几件事改成**固定路径的窄口 MCP 工具**:
|
|
80
|
+
`duty_paths` / `duty_report_append` / `duty_seen_append` / `duty_seen_recent` /
|
|
81
|
+
`duty_digest_append` / `bili_transcribe`(**不接受路径参数**,想写别处也写不了)。
|
|
82
|
+
- 插件启动时把 profile 模板铺到 `<DSH_HOME>/profiles/bili-duty/`;铺不上会**明确退回 headless 并写日志**(不静默降级)。
|
|
83
|
+
- 同源检查**改成比端口**:以前只比 hostname,本机上另一个端口的页面(dev server / 有 XSS 的本地页)也能驱动写接口。
|
|
84
|
+
- 一并采纳社区 PR #94 的契约细节:`connection.requestRejection` 按 `{ headers }` 传参。
|
|
85
|
+
|
|
86
|
+
> 思路来自 issue #96 / PR #97(@LUOXI23333)与 PR #94(@Anguis-L),这一版是按思路独立实现的;
|
|
87
|
+
> 细节与取舍写在 #96 的回复里。
|
|
88
|
+
|
|
89
|
+
### 修复(其它)
|
|
90
|
+
|
|
91
|
+
- **私信回复以前没有上下文**:每条私信都是一次全新会话 ⇒ 它永远"初次见面"。现在固定续同一个会话
|
|
92
|
+
(`headless --session-id`,id 记在 `dm-session.json`),会话失效会自动丢 id 重开,不会卡死。
|
|
93
|
+
- **人设超长被静默截断**:以前保存截 8000、送进提示词截 6000,超了**一声不响** —— 用户以为规则生效了,
|
|
94
|
+
其实后半段从没送出去。现在保存上限 60000、送提示词 40000,**超限会写日志**(一共多少 / 上限 / 截掉多少),
|
|
95
|
+
设置页也会显示字数。
|
|
96
|
+
- **一键升级把 profile 写死成 `web`**:桌面版用户的 profile 是 `desktop` ⇒ 升级失败,还会把旧版装进 web 里。
|
|
97
|
+
现在从插件自身路径识别 profile 名,认不出才退回 `web`。
|
|
98
|
+
- **升级后家目录里的运行时脚本不更新**:`mcp_server.py` / `asr.py` / `favops.py` 以前是"内容不一样就当成用户改过 ⇒ 跳过"
|
|
99
|
+
⇒ 宿主更新了、Python 侧还是旧的,新工具根本不出现。现在**先备份 `.bak-<时间戳>` 再覆盖**。
|
|
100
|
+
- **判重表读不到时会重复推送**:窄口工具补上 `duty_seen_recent`,章程要求先查再判。
|
|
101
|
+
|
|
102
|
+
### 其它
|
|
103
|
+
|
|
104
|
+
- 评论语气默认改成**中性**(口语、短、必须有具体细节),"大肥鱼"人设做成**可选** —— 公开评论用的是你的号,
|
|
105
|
+
默认不该替你扮演角色。人格放在私信和报告里。
|
|
106
|
+
- 章程新增两节:「说话的样子」(禁八股句式、梗的规矩)与「什么时候该看画面」(含"一轮最多抽 3 条")。
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
## 2.0.4 — 2026-10-23
|
|
110
|
+
|
|
111
|
+
**这一版一次修完:两处安全、六条 bug。有人把源码读了一遍,逐条核实、逐条修。**
|
|
112
|
+
|
|
113
|
+
### 🔴 安全 ①:它有可能把"别人"当成你
|
|
114
|
+
判断"谁是主人"时,以前会退到「@ 谁」那个框的昵称去查 UID —— 如果那里填的是别人,
|
|
115
|
+
**那个人的私信就会被当成你发来的**,插件还会用你的号回他。
|
|
116
|
+
|
|
117
|
+
现在只认两个来源:**你明确填的「只回谁的私信」(我自己的 B站 UID)**,或**登录的这个账号自己**。
|
|
118
|
+
(用小号登录、大号跟它聊的:请在 设置 → 刷B站 → 高级 里填你自己的 UID。)
|
|
119
|
+
|
|
120
|
+
### 🔴 安全 ②:不再把提示词交给 shell 执行
|
|
121
|
+
找不到 dsh 时,以前会走 `shell: true` 并把提示词当一个参数塞进去 —— cmd 会解析 `&`、`|`、`^`,
|
|
122
|
+
配置里的关键词一旦带这些字符就是命令注入面。现在先在 PATH 里解析出**绝对路径**,用 `shell: false` 执行。
|
|
123
|
+
|
|
124
|
+
### 🔴 安全 ③:overlay 里的路径按 YAML 规则转义
|
|
125
|
+
`pythonPath` 等路径以前直接塞进单引号里,路径带单引号会把 overlay 拼坏(甚至多出键)。
|
|
126
|
+
|
|
127
|
+
### 🔴 安全 ④:控制接口只接受本机同源请求
|
|
128
|
+
`/api/bili-duty/*` 以前谁都能打(浏览器里任意网页也能打到 127.0.0.1)。现在校验 Host 必须是本机、
|
|
129
|
+
Origin/Referer 必须同源,否则直接 403。
|
|
130
|
+
|
|
131
|
+
### 🔴 安全 ⑥:把用不到的"高危工具"整个删掉
|
|
132
|
+
内置的那个 Python MCP 原来有 27 个工具,其中 **上传视频 / 上传多P / 发动态 / 发专栏** 这四只,
|
|
133
|
+
刷B站一次都用不到 —— 但它们的代码留在那里,就可能被绕过闸门调用(白名单只管"注册",不管"直接调函数")。
|
|
134
|
+
现在**四只已经删掉**,另外给 `bili_reply` / `bili_send_message` 加了**函数级校验**:不在白名单里就直接返回,什么都不做。
|
|
135
|
+
### 🔴 安全 ⑤:凭证文件权限收紧
|
|
136
|
+
`bili_credential.json` 以前是默认权限(Linux 上别的用户可读)。现在保存时立刻收紧:
|
|
137
|
+
Windows 用 `icacls` 断继承(只留当前用户),Linux/macOS 用 `chmod 600`。
|
|
138
|
+
|
|
139
|
+
### 🐞 ⑦ 又一串 issue 一起修(2.0.4 里一起发)
|
|
140
|
+
|
|
141
|
+
- **#36** 章程里的 `<家目录>` 替换原来是空操作(替换的是**路径字符串**)⇒ 值班轮猜错转写路径。已修(读文件内容再替换)。
|
|
142
|
+
- **#74** 私信回复**不按人设**说话,还爱带 markdown 和"(28 字…)"尾巴 ⇒ 现在带上人设,并明确禁止 markdown 与这类尾巴。
|
|
143
|
+
- **#35** 发私信只看"没抛异常",不看投递回执 ⇒ 现在校验 `code` 与 `msg_key`:**没有回执就算没送到**,如实报错(常见原因:对方不收陌生人私信/被风控)。
|
|
144
|
+
- **#83** 设置会**自己变空**(前端某次自动保存推了空值)⇒ 服务端加空值保护:**空值不覆盖已有值**,要清空得显式带 `clear`。
|
|
145
|
+
- **#80**「不写日报」那档 `perDay` 完全失效(一天挑到 10 条)⇒ 该档改成数 `seen.md` 里当天的"挑中"行。
|
|
146
|
+
- **#30** uv 缓存目录打不开时,提示却在说"venv 里没有 qrcode",误导 ⇒ 现在按日志内容自己判断,直接给该做的那一步。
|
|
147
|
+
- **#27** 装转写依赖原来只走单个镜像,撞 403 就整轮失败 ⇒ 已并入镜像轮换(这条之前已修,顺便确认)。
|
|
148
|
+
### 🐞 ① 私信额度用完,那条消息会被"吞掉"
|
|
149
|
+
以前先记成"已处理"、再判今天还能不能回 ⇒ 额度满了就既没回、以后也不会补。
|
|
150
|
+
现在**先判额度再记账**:满了就留着,第二天自动补发。
|
|
151
|
+
|
|
152
|
+
### 🐞 ② 可能同时跑好几轮,而且关不掉
|
|
153
|
+
加了并发锁(同一时间只允许一轮);那个子进程现在**登记在插件里**,卸载/退出时一起收掉。
|
|
154
|
+
|
|
155
|
+
### 🐞 ③ 「只发私信」却可能还在公开评论
|
|
156
|
+
判断以前只看"自动评论开关",而它在切到"只私信"之后还留在配置里。
|
|
157
|
+
现在**只要投递方式是"只私信",评论工具直接不下发** —— 模型手里没有那只工具,想发也发不了。
|
|
158
|
+
|
|
159
|
+
### 🐞 ④ 升级会把你自己关掉的私信监听重新打开
|
|
160
|
+
2.0.0 的迁移判据是"三项都还是旧默认",而「你主动关掉、其它项没动」跟「从没设置过」长得一样。
|
|
161
|
+
现在迁移**只改间隔和条数,绝不碰开关**。
|
|
162
|
+
|
|
163
|
+
### 🐞 ⑤ 「复制诊断信息」脱敏不彻底
|
|
164
|
+
以前只遮了收件人 UID,人设全文 / 昵称 / 工作区路径都还在,日志尾部还带着私信原文。
|
|
165
|
+
现在按字段遮(显示成"已填 N 字"),日志里「收到新消息 —— …」那行**整行略去**。
|
|
166
|
+
|
|
167
|
+
### 🐞 ⑥ 「测一下」以前只检查"凭证文件在不在"
|
|
168
|
+
登录过期了它照样报"已登录"。现在**真的带 cookie 问一次 B站**,失效就直接报不 OK,并显示昵称和 UID。
|
|
169
|
+
|
|
170
|
+
> 谢谢把这个插件当正经项目审的人:读源码找问题的那位 UP,以及提 issue 的各位。
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
## 2.0.2 — 2026-10-22
|
|
174
|
+
|
|
175
|
+
**这一版全是修,六个坑。**
|
|
176
|
+
|
|
177
|
+
### ⭐ 人设提示词写了保存不上(有用户报的)
|
|
178
|
+
保存接口那边有个字段白名单,`personaPrompt` 漏在里面 ⇒ 前端传上来直接被丢掉,看着就是"点了保存没反应"。
|
|
179
|
+
已用真实保存请求验证:写进去 → 存到 `config.json` → 再读回来,都对。
|
|
180
|
+
顺带补上同样漏掉的四项:**私信监听开关 / 查私信间隔 / 每天最多回几条 / 只回谁**。
|
|
181
|
+
|
|
182
|
+
### 「它刷过的视频」读不到记录
|
|
183
|
+
- 日期允许带时间:以前只认 `2026-10-22`,写成 `2026-10-22 18:51` 的行会被整行丢掉。
|
|
184
|
+
- BV 号改成扫描整行去找:不再假设它在第 2 列,标题里带竖线也不会错位。
|
|
185
|
+
- 「发给你了」不再只看状态文字:评论记录表里有 rpid 的直接算发过。
|
|
186
|
+
|
|
187
|
+
### 一键升级:没有 git 也能升了
|
|
188
|
+
以前从 GitHub 升级走的是 `add github:…`,而 pnpm 会去调 `git ls-remote` —— 没装 git 的机器**必失败**。
|
|
189
|
+
现在改成取 Release 里的 **tgz 直链**(https 下载,不需要 git),取不到才退回老办法。
|
|
190
|
+
|
|
191
|
+
### 「重装主依赖」会自己处理 Python 版本过高
|
|
192
|
+
以前钉 `--python 3.12` 失败会退回 "uv 默认",可能建出 3.14/3.15 的环境 —— 而 `brotli` / `pyyaml` 在那里没有现成的包,装依赖必然失败;
|
|
193
|
+
更糟的是环境一旦建好就不再重建,用户只能自己删目录。
|
|
194
|
+
现在点「装主依赖」会先看现役环境是哪个版本,**≥3.14 就改名重建成 3.12**(旧的那个留着,方便回滚)。
|
|
195
|
+
|
|
196
|
+
### 家目录里的 `mcp_server.py` 改过就保留
|
|
197
|
+
以前它每次启动都被 vendor 那份覆盖(用户改了白改),而章程 `duty.md` 却是"改过就保留" —— 同一个插件两套规矩。
|
|
198
|
+
现在统一:记住上次发出去的指纹,**你改过就不覆盖**,新版写到 `mcp_server.py.new` 并在日志里说一句。
|
|
199
|
+
|
|
200
|
+
### 判重表按月归档
|
|
201
|
+
`seen.md` 会越滚越大,而每轮模型都要通读一遍 ⇒ 越跑越贵。
|
|
202
|
+
现在 30 天前的表格行自动挪进 `seen/YYYY-MM.md`(纯宿主代码、零 token),主表恒定为最近一个月。
|
|
203
|
+
|
|
204
|
+
> 谢谢报问题、还自己找到根因的几位:@Shimakoshi、@俺爱啃猪蹄子。
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
## 2.0.1 — 2026-10-22
|
|
208
|
+
|
|
209
|
+
**修「它刷过的视频」读不到记录**(有用户面板显示 0 条,其实那轮跑得好好的,报告、评论都发了)。
|
|
210
|
+
|
|
211
|
+
- 日期允许带时间:以前只认 `2026-10-22`,写成 `2026-10-22 18:51` 的行会被整行丢掉。
|
|
212
|
+
- BV 号改成「扫描整行去找」:不再假设它在第 2 列,标题里带竖线也不会错位。
|
|
213
|
+
- 「发给你了」不再只看状态文字:评论记录表里有 rpid 的,直接算发过一遍(状态写「收(值得看)」也认)。
|
|
214
|
+
|
|
215
|
+
**另外**:设置页现在会明确写出「还缺这几项:qrcode」—— 出不了登录二维码多半就是缺它,点一次「重装主依赖」即可。
|
|
216
|
+
|
|
217
|
+
> 感谢用户 **Shimakoshi** 那边的小鲸定位到前两条(它翻了 `seen.md` 和日志,比我们看得细)。
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## 2.0.0 — 2026-10-21
|
|
222
|
+
|
|
223
|
+
**这一版从"修 bug"变成"加功能",四项新东西 + 一整轮界面重做。**
|
|
224
|
+
|
|
225
|
+
### 一、私信投递成为默认(不再往别人视频底下写字)
|
|
226
|
+
|
|
227
|
+
- 默认改成**只私信**:跑完把结果发到你的 B站 私信里,**公开评论区一条都不发**。
|
|
228
|
+
- 没填 UID 也能用:会用你填的「@ 谁」的**昵称自动查一次 UID**(结果缓存,不会反复请求);查不到就**自动降级成只发评论**并在日志里说明——宁可发出去,也不会安静地一条都不送。
|
|
229
|
+
- 想改回去:设置 → 互动 → 投递方式(只发评论 / 只私信 / 两边都发)。
|
|
230
|
+
|
|
231
|
+
### 二、私信双向(新)
|
|
232
|
+
|
|
233
|
+
- 在 B站 私信里跟它说话,它会看见并回你一句。
|
|
234
|
+
- **默认关**(开了才会花 token);打开后宿主每 5 分钟(可调,最小 3)**纯代码**查一次私信——**这一步不花 token**,只有真收到新消息才去回。
|
|
235
|
+
- 只认**你本人**发来的消息;每天最多回 3 条(可调,0 = 只读不回);回复限 200 字,不承诺功能、不透露配置。
|
|
236
|
+
|
|
237
|
+
### 三、「它刷过的视频」列表
|
|
238
|
+
|
|
239
|
+
- 设置页与**会话头第三个 tab**(对话 / 轨迹 / 刷过的视频)都能看。
|
|
240
|
+
- 卡片墙、封面走宿主代理(不把你的 IP 交给 B站 图床)、窗口变宽自动加列。
|
|
241
|
+
- **筛档位**:值得看 / 可以看 / 不值当(由它读完视频后自己标,不是打分);**筛状态**:挑了 / 跳过 / 评论过;支持分页。
|
|
242
|
+
- 每条带两行「为什么值得」。
|
|
243
|
+
|
|
244
|
+
### 四、其他
|
|
245
|
+
|
|
246
|
+
- **人设提示词框**:想让它怎么说话,直接写在设置页(不再需要填"工作区"这种概念);老用户可一键从工作区的 `AGENTS.md` 导入。
|
|
247
|
+
- **复制诊断信息 / 环境自检**:出问题时点一下,前者把环境+日志拼成一段(自动复制),后者逐项告诉你哪一步不通、该怎么办。
|
|
248
|
+
- **每条视频一份笔记**:`reports/<BV>-<日期>.md`(宿主从日报里拆出来,不额外花 token)。
|
|
249
|
+
- 设置页重做成**四页签**:日常 / 偏好 / 互动 / 高级。
|
|
250
|
+
- 撤掉「有 N 项没能同步到 DSH 原生设置」那条提示(根因早已修好,留着只会让人困惑)。
|
|
251
|
+
|
|
252
|
+
### 修掉的
|
|
253
|
+
|
|
254
|
+
- `bili_send_message` 以前只在「填了 UID」时才进工具白名单 ⇒ 靠昵称查 UID 的场景下,私信**永远发不出去**。
|
|
255
|
+
- 会话头 tab 里的文字颜色:以前用了一套不存在的主题变量,浅色主题下会变成黑底黑字。
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## 0.2.3 — 2026-10-21
|
|
260
|
+
|
|
261
|
+
- 修:会话头 tab 里**标题看不见** —— 原来颜色靠继承,会话页那层继承到的是深色字压在深色卡片上。现在显式取主题变量 `--dsw-alias-label-primary` / `--dsw-alias-label-tertiary`(浅色主题下自动变深色字,不会反过来)。
|
|
262
|
+
- 顺带把条目、标题、副标题三层的颜色都钉死,不再依赖继承。
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
## 0.2.2 — 2026-10-21
|
|
266
|
+
|
|
267
|
+
**会话头 tab 修体验(实验成功:只注册槽位就能出 tab)**
|
|
268
|
+
|
|
269
|
+
- ✅ 桌面版 2.0.18(内核 0.2.1)上 **「刷过的视频」真的出现在对话页第三个 tab** ⇒ 不需要额外的 view 定义 / 快照构建器。
|
|
270
|
+
- 修:**加封面后点标题不跳转** ⇒ 改成**整行可点**,走宿主的新接口 `POST /open {what:'url', u}`(桌面版里 `<a target=_blank>` 不一定会交给系统浏览器)。
|
|
271
|
+
- 修:项里标题**换行显示**(之前被压成一行、还压掉了点击区)、tab 里列表**撑满可用高度**、封面加大到 112×63、hover 高亮。
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
## 0.2.1 — 2026-10-20(实验版)
|
|
275
|
+
|
|
276
|
+
**实验:会话头第三个 tab「刷过的视频」**
|
|
277
|
+
|
|
278
|
+
- 注册到 `conversation.view` 槽位(0.2.1 里「轨迹」那个 tab 就是用它注册的),内容与设置页那块同源(`GET /watched` + 封面代理)。
|
|
279
|
+
- ⚠️ **这是实验**:只注册了 tab 的 UI,**没有**注册 view 定义 / 快照构建器——要验证"只给 slot 会不会被显示成 tab"。
|
|
280
|
+
· 如果桌面版里出现了第三个 tab ⇒ 最小方案成立,收工;
|
|
281
|
+
· 如果没有 ⇒ 照轨迹包那样补 `ctx.uiConversation.views.register({ target, create })`。
|
|
282
|
+
- 老版本(0.1.7 等没有这个槽位)静默跳过,不影响设置页。
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
## 0.2.0 — 2026-10-20
|
|
286
|
+
|
|
287
|
+
**新功能:「它刷过的视频」(0.2.0 的第一步)**
|
|
288
|
+
|
|
289
|
+
- 设置页多一节「**它刷过的视频**」:点开读判重表 `seen.md`,按天倒序列出刷过/挑过的视频(标题可点开、日期 · UP · 挑了还是跳过 · 有没有评论过);
|
|
290
|
+
可切「只看挑中的」,封面走**宿主代理**(浏览器不直连 `i0.hdslb.com`,既不撞防盗链也不把使用者 IP 交出去),前 40 条懒加载。
|
|
291
|
+
- 接口:`GET /api/bili-duty/watched`(`?picked=1`、`?limit=`、`?offset=`)+ `GET /api/bili-duty/cover?bv=`。
|
|
292
|
+
- 实测:本机判重表 **124 条 / 51 条挑中的**,解析与渲染都验过(真渲染探针 99 次元素创建、无抛错)。
|
|
293
|
+
|
|
294
|
+
**说明**:0.1.19 那个包**不含**这个功能(它是打包之后才做的)——要看列表请用 **0.2.0**。
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
## 0.1.19 — 2026-10-20
|
|
298
|
+
|
|
299
|
+
**新功能:自动收藏(思路来自社区 PR #63 / `HebPRo`,判据自己实现)**
|
|
300
|
+
|
|
301
|
+
- 设置页多一项「**自动收藏到**」:选一个收藏夹,**每轮跑完**就把这一轮挑中的视频存进去(0 = 不收藏)。
|
|
302
|
+
另加一个「**补收藏今天的**」按钮,当天漏了可以补。
|
|
303
|
+
- ⭐ **刻意放在宿主侧,不给模型一只工具**:① 收藏是"写动作",给模型等于多一只可能被误用的手(我们连评论都收着给);
|
|
304
|
+
② 挑中哪几条,宿主自己从报告里数(行首的 `### BV号`)就够了,不必再花 token 问模型。
|
|
305
|
+
- 实现:`lib/favops.py`(收藏边车,宿主 `spawn` 调用;凭证优先找 **cwd=插件家**里那份)+ `Config.favFolderId`
|
|
306
|
+
+ `GET /fav-folders`、`POST /fav-today`;跑完一轮 `code===0 && favFolderId>0` 时后台自动收藏。
|
|
307
|
+
- 实测:`favops.py folders` 真连上了账号,返回 `默认收藏夹(1 条)`。
|
|
308
|
+
|
|
309
|
+
**修**
|
|
310
|
+
|
|
311
|
+
- 版本比较把 **`-rc.x` 这类预发布算更旧**(以前只比三段数字 ⇒ `0.2.0-rc.1` 会被判成比 `0.2.0` 新,会误导用户升预发布版)。
|
|
312
|
+
|
|
313
|
+
**自查修掉两处(都会真炸,已验)**
|
|
314
|
+
|
|
315
|
+
- **收藏夹的 `useEffect` 插错了作用域**:它落进了 `useStatus()` 里,那个作用域没有 `favFolders`/`alive` ⇒ 一渲染就 `ReferenceError`,设置页会整片崩。已挪到 `Panel()` 里(`}, [cfg])` 之后)。
|
|
316
|
+
- **两个新路由插进了 `/install-asr` 的 `if` 块里、在 `return` 之后** ⇒ 永远走不到(探针里报 `unknown GET /api/bili-duty/fav-folders`)。已挪到「复核评论」那段之前,跟其它路由并列。
|
|
317
|
+
- 复验:`GET /fav-folders` 能走到逻辑(返回 `spawn EPERM` 是探针环境没有 python,属预期)、`POST /fav-today` 正确回「还没选收藏夹」、`/status` 正常;报告解析器从 10/19 的报告里正确抠出 5 个 BV。
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
## 0.1.18 — 2026-10-20
|
|
321
|
+
|
|
322
|
+
**采纳社区 PR 的两处修法(都自己实现了,没整包合)**
|
|
323
|
+
|
|
324
|
+
- ⭐⭐ **overlay 补 `agent-default-model`**(来源:PR #50 / `Rookiexg`,DSH 0.2.1-rc.2 桌面版实测):
|
|
325
|
+
之前 0.1.8 只是把 `credentials` / `authorization` / `deepseek-account` 三个服务放行,**还不够** ——
|
|
326
|
+
仍然会报 `MISSING_CREDENTIAL: llm-deepseek: no API key for provider route "deepseek-official"`,
|
|
327
|
+
因为 headless 的 `agent-default-model` 默认解析到 `deepseek-official`(要 API key),而"账号登录"的机器没有 key;
|
|
328
|
+
桌面版是靠 profile 那层 patch 把路由指到 `deepseek-account` 的,**我们这一轮的一次性 overlay 没有那一层**。
|
|
329
|
+
→ 现在 overlay 里补 `agent-default-model`,**优先跟随用户当前选的模型**(`ctx.get('agentDefaultModel')`),拿不到就不写。
|
|
330
|
+
- ⭐ **`lib/asr.py` 的 yt-dlp 加 `noprogress`**(来源:PR #23 / `383891598` 的审计):
|
|
331
|
+
进度条默认打到 stdout ⇒ 调用方"stdout 非空 = 成功"恒真(实测前 1KB 全是 `[download] xx%`)⇒ 关掉进度,别污染输出。
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
## 0.1.17 — 2026-10-20
|
|
335
|
+
|
|
336
|
+
**修(两条社区 issue,都是真 bug)**
|
|
337
|
+
|
|
338
|
+
- ⭐ **issue #36:章程里的 `<家目录>` 替换一直是空操作** —— 以前 `duty` 是**章程的路径**,我们却在**路径字符串**上
|
|
339
|
+
`split('<家目录>')`,等于什么都没替换;而章程内容还是让那一轮自己去读,里面 5 处占位符原样进了模型的眼睛(它读成 `~`)
|
|
340
|
+
⇒ 转写/判重表路径猜错。现在:**宿主读章程内容 → 换成真路径 → 内联进提示词**(顺带省掉它一次读文件)。
|
|
341
|
+
- ⭐ **issue #27:装"本地转写"依赖只走单个镜像** —— 撞上清华 403 就整轮失败(主环境早就有镜像轮换,ASR 那条漏了)。
|
|
342
|
+
现在同样轮换三个镜像(清华 → 中科大 → 阿里),每个镜像先 `uv pip`、失败再退回 `python -m pip`。
|
|
343
|
+
|
|
344
|
+
**补(README)**
|
|
345
|
+
|
|
346
|
+
- 顶部加了「演示视频 · 交流群(QQ 1128547307)」一行;末尾新增「交流与反馈」一节:
|
|
347
|
+
先引导进群、真 bug 走 issue(写清要带哪些信息)、PR 请一件事一个、二次分发按 MIT 的规矩、以及"别去打扰素材作者"。
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
## 0.1.16 — 2026-10-20
|
|
351
|
+
|
|
352
|
+
**修(GitHub 认不出协议:MIT 被判成 "Other")**
|
|
353
|
+
|
|
354
|
+
- 有位同学来问"能不能授权二次分发,你仓库没标开源协议" —— 协议其实一直在,但 `LICENSE` 里被我追加了第三方声明说明,
|
|
355
|
+
**破坏了标准 MIT 模板的匹配** ⇒ GitHub 侧栏显示 `Other / NOASSERTION`,看着就像"没标"。
|
|
356
|
+
- 现在拆开:`LICENSE` 只放**标准 MIT 正文**(署名改成 `c1overzz`),第三方声明与署名说明挪到 **`NOTICE.md`**,并加进发布清单。
|
|
357
|
+
- 预期:GitHub 重新识别后侧栏会显示 **MIT license**。
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
## 0.1.15 — 2026-10-19
|
|
361
|
+
|
|
362
|
+
**修(两条社区 PR #33 / #37 里已经写好的真 bug,作者是 `wotorrrrr`)**
|
|
363
|
+
|
|
364
|
+
- ⭐ **私信永远发不出去**(issue #25 / #16):`mcpWhitelist()` 里压根没有 `bili_send_message`
|
|
365
|
+
⇒ 私信开关打开、那一轮也跑了,模型手里却没有这只工具 ⇒ 一次都没发出去过。
|
|
366
|
+
现在 `dmMode` 不是 `off` **且**填了 `dmUid` 才把它放进白名单(关着就不给,白名单别松)。
|
|
367
|
+
- ⭐ **`uv venv` 要钉 Python 3.10–3.13**(issue #15):不给 `--python` 时 uv 拿"最新 CPython"(有人建出 3.15),
|
|
368
|
+
而 `av` / `ctranslate2` / `aiohttp` 在 3.14+ 没有 wheel ⇒ 转写依赖直接 ResolutionImpossible、主依赖卡在 cffi。
|
|
369
|
+
现在先 `--python 3.12`(可用 `BILI_DUTY_VENV_PYTHON` 覆盖),失败再退回 uv 默认。
|
|
370
|
+
- 数据来源:这两条都是社区 `wotorrrrr` 的 PR(#33 / #37)先说清的,我们按他的判据自己实现(不整包合)。
|
|
371
|
+
|
|
372
|
+
**待做(他另外两点先记下来)**
|
|
373
|
+
|
|
374
|
+
- 老环境"Python 3.14+ 建的"要能识别并改名重建(他写了 `pyVerOfVenv` + `rebuildIfTooNew`)。
|
|
375
|
+
- 数组类设置(keywords / 私信名单)不能用 `!==` 比较默认值 —— 两个空数组永远不等,会把 config.json 里的值盖成 `[]`。
|
|
376
|
+
我们判"非默认值"用的是 `JSON.stringify` 比较,暂时安全;但写新比较时别再犯。
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
## 0.1.14 — 2026-10-19
|
|
380
|
+
|
|
381
|
+
**修(桌面版上"开关还是自己弹回去"的最后一个缝)**
|
|
382
|
+
|
|
383
|
+
- 一位用户的 dsh 分析出来的关键事实:**桌面版 0.2.x 里,写进 `cordis.patch.yml` 的设置不会热刷新到正在运行的实例**
|
|
384
|
+
⇒ 插件从 ctx 读到的那份 `config` 一直是挂载时的旧默认值(`false` / `"python"`)。
|
|
385
|
+
- 我们 0.1.11 起的判据是"用户在插件面板保存过的键以插件为准",其余仍听宿主的 ⇒ 在桌面版上,**那些没被记进 `_set`、
|
|
386
|
+
但 config.json 里明明不是默认值的键**(更早版本写进去的)会被那份旧默认值压回,用户看到的就是"开关自己弹回去"。
|
|
387
|
+
- 修复:**只要某个键 `config.json` 里的值与默认值不同,就算作"有人显式设过",一律以本地为准**;
|
|
388
|
+
与 `_set`、`local-override`、`pythonPath` 三个来源合并判断。
|
|
389
|
+
- 验证:三条场景探针(面板存过 / 老用户升级 / 只在原生页改过)全过;预检两个半端正常。
|
|
390
|
+
|
|
391
|
+
**修(读不到配置时不再干瞪眼)**
|
|
392
|
+
|
|
393
|
+
- 用户报"设置里没有开关这一项,只能让 dsh 帮我开" —— 实际是 `/status` 拿不到数据,界面只显示"读设置中…",
|
|
394
|
+
谁都不知道发生了什么。现在连续失败 3 次后会写明原因(多半是 0.1.11/0.1.12 的旧版、或装完没重启),
|
|
395
|
+
6 次后给出升级命令和 `duty.log` 的位置。
|
|
396
|
+
|
|
397
|
+
**清理(顺手把"以后可能咬人"的东西收了)**
|
|
398
|
+
|
|
399
|
+
- `dsh.missing` 那两处保护分支一度变成**死代码**(`resolveDsh` 已经不会返回 missing)⇒ 现在补了 `hasDshOnPath()`:
|
|
400
|
+
PATH 里真没有 `dsh` 才返回 missing(停下来说清楚),有才走"最后一招"。**两条保护重新可达**,不留不可达分支。
|
|
401
|
+
- 仓库清点过:`git ls-files` 里没有日志 / 备份 / 探针脚本(`.gitignore` 已排除 `*.log`、`*.bak*`、`*.cmd`),发布包按 `files` 白名单只有 20 个文件。
|
|
402
|
+
|
|
403
|
+
- ⭐ **再采纳一位用户 dsh 的分析**:宿主基准别用闭包里的 `config`(那是挂载时快照),改用 `describe()` 这一行里的 **`row.value`**(当前 patch 解析的现值),拿不到才退回 `config` ⇒ 连"桌面版不热刷新"都不用绕了。
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
## 0.1.13 — 2026-10-19
|
|
407
|
+
|
|
408
|
+
**修(严重:设置页停在"读设置中…",0.1.11 / 0.1.12 都带这个 bug)**
|
|
409
|
+
|
|
410
|
+
- 现象:装 0.1.11 / 0.1.12 后,设置 → 刷B站 里永远显示"读设置中…";有的机器整片设置页空白。
|
|
411
|
+
- 根因:0.1.11 加"记录哪几项以插件为准"那段时,用了 `hostDiff` / `lastDiffSig` 两个变量**却没声明**。
|
|
412
|
+
ESM 是严格模式 ⇒ 赋值未声明变量直接抛 `ReferenceError` ⇒ `loadCfg()` 挂 ⇒ `/status` 500
|
|
413
|
+
⇒ 前端每 5 秒拿到一次失败,`st` 永远是 null ⇒ 卡在"读设置中…"。
|
|
414
|
+
- 修复:补上 `let hostDiff = []` / `let lastDiffSig = ''`。
|
|
415
|
+
- 验证:`/status` 与 `/update` 都能正常返回(status 里 `dshCli` 已能解析出自己的 dsh 路径),预检两个半端全过。
|
|
416
|
+
- 教训:**只跑 `node --check` 和"半端能加载"是不够的** —— 那条路径要真的调一次(`loadCfg` 是几乎每个入口都会走的地方)。
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
## 0.1.12 — 2026-10-19
|
|
420
|
+
|
|
421
|
+
**新(「检查更新」现在也看 GitHub —— npm 发不上去的时候,用户也能拿到新版)**
|
|
422
|
+
|
|
423
|
+
- 起因:npm 账号被暂停,线上 `latest` 停在 0.1.7;而「检查更新」只问 npm ⇒ 用户按了也只会被告知"已是最新"
|
|
424
|
+
- 改成**两条源都问**:先 npm(不依赖加速器、快),再 GitHub(读 `api.github.com` 上 `package.json` 的 version);
|
|
425
|
+
谁给的版本号更新就用谁 ⇒ 返回里带 `source`(npm / github)
|
|
426
|
+
- 「一键升级」跟着来源走:`source=github` 时跑 `add github:c1overzz/dsh-bili-scroll`,否则跑 `add dsh-bili-scroll`
|
|
427
|
+
- 设置页把来源说出来("npm 上还没发上去,这个版本来自 GitHub");GitHub 不通时**静默跳过**,不打扰用户
|
|
428
|
+
- 两条源都查不到时明确回 `ok:false`,而不是假装"已是最新"
|
|
429
|
+
|
|
430
|
+
---## 0.1.11 — 2026-10-19
|
|
431
|
+
|
|
432
|
+
**修(0.1.10 的"无条件本地优先"其实没真做到,回弹还在)**
|
|
433
|
+
|
|
434
|
+
- 0.1.10 的代码其实还留着尾巴:只有 `local-override.json` 里记过的键才本地优先,其余仍然"DSH 原生设置里有值就以宿主为准"。
|
|
435
|
+
而 `local-override.json` 只记**用户点保存那一刻**的键 ——
|
|
436
|
+
· 老用户升级上来时这个文件还不存在;
|
|
437
|
+
· 保存时若宿主"写入没报错"(但实际没生效),这些键还会被从 override 里删掉;
|
|
438
|
+
⇒ **所以还是会弹回**(用户:装了新版,开关照样几秒复位)。
|
|
439
|
+
- ✅ 换个更硬的判据:**记住"用户在插件面板里保存过哪些键"**(写进 `config.json` 的 `_set`),
|
|
440
|
+
这些键读配置时**一律以插件这份为准**,不再问宿主。
|
|
441
|
+
· 没在插件面板存过、但 DSH 原生设置里有值的键 ⇒ 仍然听宿主的(原生页还是正当入口)
|
|
442
|
+
· 老版本没有 `_set` ⇒ 第一次跑时按"和默认值不一样"反推一遍,老用户升级也不会被弹回
|
|
443
|
+
- 已验证(三场景探针):插件面板存过 → 本地赢;老用户升级 → 本地赢;只在原生页改过 → 宿主赢。
|
|
444
|
+
|
|
445
|
+
**修("装转写依赖"直接 exit 2:uv 的缓存目录没权限)**
|
|
446
|
+
|
|
447
|
+
- ⭐ 用户截图里的原文:`uv venv --seed …` ⇒ `error: Could not acquire lock` / `failed to open file C:\Users\AP\AppData\Local\uv\cache\.lock: 拒绝访问 (os error 5)` ⇒ `exit 2`
|
|
448
|
+
—— ⭐ **uv 默认把缓存放 `%LOCALAPPDATA%\uv\cache`**,那地方一旦没权限(企业策略 / 杀软 / 别的用户建过)就彻底装不动 ✗,而这是**环境差异,不该让用户碰** ✓
|
|
449
|
+
- ✅ 所有 uv 调用统一走 `uvEnv()`:`UV_CACHE_DIR` / `UV_TOOL_DIR` / `UV_PYTHON_INSTALL_DIR` 全部钉在插件家
|
|
450
|
+
(`<家>\uv-cache` 等)—— 那儿一定有写权限 ✓(和当年 `HF_HOME` 那次是同一类)
|
|
451
|
+
- ✅ 那条误导人的"先点上面的「装依赖」"改成两条具体原因:缓存没权限 / 机器上没有 uv 或 Python
|
|
452
|
+
- 提醒:老用户装过一堆缓存的话,`%LOCALAPPDATA%\uv` 可以自己删掉,不再需要
|
|
453
|
+
|
|
454
|
+
**修("让他的 dsh 自己弄好" —— 桌面版不用再手填 dshBin)**
|
|
455
|
+
|
|
456
|
+
- ⭐ `resolveDsh()` 重写成**自动找**:①用户填的 → ②`createRequire` 解析 `@deepseek-ai/dsh` → ③npm 全局 / Program Files / POSIX 常见位置 →
|
|
457
|
+
④**在 Electron 的 resources 目录里做有界递归搜索**(深度 ≤7、最多翻 4000 个目录,只认 `dsh/lib/bin.js`)
|
|
458
|
+
⇒ 桌面版多半能自己找到,用户不用去翻 bin.js 路径
|
|
459
|
+
- ⭐ 结果进了 `/status` 和 `bili_status` 的 `dshCli` 字段(**空字符串 = 没找到**,那一轮根本跑不起来)—— 以后排查只看这一个字段
|
|
460
|
+
- 顺手加了 60 秒缓存:设置页每 5 秒拉一次 `/status`,不能让"找不到时的递归搜索"每 5 秒跑一遍
|
|
461
|
+
- ⚠️ 一度写成"找不到就直接停下",后来改回**保留最后一招**:仍然用 PATH 里的 `dsh` 试一次(日志说明白)——
|
|
462
|
+
否则那些手动配过 PATH、原本能跑的人,会因为我们"判死"而跑不了 ✗
|
|
463
|
+
- 验证:本机(npm 全局)能找到;把 APPDATA 指空、造一个假的 Electron 应用目录,靠递归也能找到
|
|
464
|
+
|
|
465
|
+
**修(同一批用户日志里翻出来的两条)**
|
|
466
|
+
|
|
467
|
+
- ⭐ **找不到 dsh 时别再硬跑**:以前
|
|
468
|
+
日志只留一句 code=1 和一段 'dsh' 不是内部或外部命令 的**乱码**,用户完全不知道该怎么办。
|
|
469
|
+
现在直接**停下来说清楚**("这一轮没跑:找不到 dsh,请在设置里把「dsh 路径」指到 …"),并照常补一份占位报告;
|
|
470
|
+
「一键升级」同样处理。
|
|
471
|
+
- ⭐ **子进程输出不再乱码**:cmd.exe 自己吐的错误信息是 GBK,按 UTF-8 写进 duty.log 就成了方块
|
|
472
|
+
⇒ 先按 UTF-8 解,出现替换符就回退 GBK。
|
|
473
|
+
- ⭐ **复核日志不再刷屏**:没有可核的评论时那句「判重表里还没有…」会在每轮 90 秒后的自动复核里重复出现
|
|
474
|
+
(用户截图看到连了 4 行,像在报错)⇒ 文案改成"还没发过评论,暂时不用核",并且只在有记录时才逐条记日志。
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
## 0.1.10 — 2026-10-18
|
|
478
|
+
|
|
479
|
+
**修(0.1.9 没修好:开关还是弹回)**
|
|
480
|
+
|
|
481
|
+
- 0.1.9 只在"往 DSH 写设置报错"时才切成本地优先,但用户实测:**不报错、界面也没有"没同步"提示,开关照样弹回** ——
|
|
482
|
+
说明写入没抛异常、回读也看不出差别,可**生效值仍然是旧的**(多半是 profile 层压过了 user 层)。
|
|
483
|
+
- ✅ 改成**无条件本地优先**:只要是从插件设置页保存的键,读配置时一律以 `config.json` 那份为准,
|
|
484
|
+
不再指望 DSH 原生设置那边同步。代价是同名项若在 DSH 自带设置页改,以插件面板为准(插件页才是正式的家)。
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
## 0.1.9 — 2026-10-18
|
|
488
|
+
|
|
489
|
+
**修(DSH 0.2.1 上「设置保存了又被弹回去」)**
|
|
490
|
+
|
|
491
|
+
- ⭐ 两位用户先后反馈:设置页里**开一个开关,另一个像被关掉了**。
|
|
492
|
+
实查:`client.js` 里每个开关都绑自己的字段,不存在互斥逻辑 ✗ —— 真因是**写不进 DSH 原生设置**
|
|
493
|
+
(`profile reload requires the root Include entry`,DSH 0.2.1 某些启动方式下会拒写)⇒
|
|
494
|
+
`loadCfg` 的"宿主有值就以宿主为准"把刚改的值压回原状 ⇒ 每个开关都亮一下就被复位,看着像互相排斥。
|
|
495
|
+
- ✅ 修法:**本地优先** —— 宿主同步失败时,把这几项记进 `local-override.json`,读配置时以插件自己的值为准;
|
|
496
|
+
哪天宿主同步成功了再删掉、恢复正常对账。正常环境下行为不变。
|
|
497
|
+
- ✅ 并且**失败要说**:设置页顶部会显示"有 N 项没能同步到 DSH 原生设置(列出名字),插件会以这里的设置为准"。
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
## 0.1.8 — 2026-10-18
|
|
501
|
+
|
|
502
|
+
**修(DSH 0.2.1 上跑不通的那颗)**
|
|
503
|
+
|
|
504
|
+
- ⭐ **DSH 0.2.1-rc.2 上「跑一轮」调不通模型**(用户 `Elec-Tron-lc` 递来完整报告,逐条核过):
|
|
505
|
+
新版的 `headless` profile 自带一份 patch,把 `credentials` / `authorization` / `deepseek-account`
|
|
506
|
+
三个服务关掉了 ⇒ 那一轮既用不了账号模型、也读不到凭证库里的 key,报 `ACCOUNT_SIGN_IN_REQUIRED`
|
|
507
|
+
或 `NO_ADAPTER: buddy`。现在插件生成的 overlay 会把这三项**重新打开**
|
|
508
|
+
(overlay 是最后叠加的一层,能覆盖),**用户什么都不用配**。
|
|
509
|
+
- ⚠️ 这条**没有在 0.2.1 上实测**(本机是 0.1.7-rc.2,没有那三条禁用)—— 真实验收靠 0.2.1 用户跑一轮确认。
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
# 更新日志
|
|
513
|
+
|
|
514
|
+
这个文件记的是**每个版本改了什么**,用人话写 —— 面向使用者,不是开发笔记。
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## 0.1.7 — 2026-10-17
|
|
519
|
+
|
|
520
|
+
**修(用户反馈,都是 issue #8 里那几条"白花钱"的)**
|
|
521
|
+
|
|
522
|
+
- **主环境建的时候补上 `--seed`**(只有转写那个环境带了):uv 建的 venv 默认不含 pip,一旦镜像失败要回退 `python -m pip`,就是一句 `No module named pip` —— 连补救的路都没有。
|
|
523
|
+
- ⭐ **装依赖失败会自动换下一个镜像**:清华对部分 IP 会整站回 403,而 pip 的报错写成"这个包不存在",很误导;现在一个不通就换 USTC、再换阿里云。
|
|
524
|
+
- **章程里的 `<家目录>` 占位符改成真实绝对路径**:模型会把它读成 `~`,实测会让整轮转写白跑。
|
|
525
|
+
- **硬字幕**(画面里烧着字、但没有字幕轨也没有人声)现在会在报告里写明「可能是画面里的硬字幕,读不到」,不再跟"这条视频没内容"混在一起。
|
|
526
|
+
|
|
527
|
+
**另外并入了 PR #9 里的三个提交(@me1dlinger,按提交单独摘的)**
|
|
528
|
+
|
|
529
|
+
- ⭐ **新增「私信投递」**:设置页多两项 —— **投递方式**(关 / 只私信 / 私信和评论都发)和 **收信人 UID**。
|
|
530
|
+
⚠️ **默认是"关"**,行为跟以前一样;想改成"只发私信"等下一个功能版一起调(那样别人的评论区就不会再被我们打扰)。
|
|
531
|
+
- **私信正文的规矩**:不许出现设置名、内部术语、台账口径;**500 字上限**(超了接口直接拒,code 21007)。
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
## 0.1.6 — 2026-10-16
|
|
536
|
+
|
|
537
|
+
**修(都是用户报的,两条来自 GitHub issue)**
|
|
538
|
+
|
|
539
|
+
- ⭐⭐ **「一轮在跑的时候,整个 DSH 宿主直接退出」修好了**(issue #1,用户贴了崩溃日志)。
|
|
540
|
+
根因:`duty.log` 被别的进程占着时会报 `EBUSY`,而我们**接子进程输出**的那个回调没包 try/catch ——
|
|
541
|
+
那个异常没人接,于是**整个宿主被杀、所有会话一起没**。现在所有写日志的地方都包好了:
|
|
542
|
+
**插件再错也只该"这一轮没跑成",绝不该杀宿主**。
|
|
543
|
+
- ⭐ **桌面版(Electron)上"点跑一轮、0.17 秒就结束、什么都没干"**(issue #5 / #6 / #7,三个人从三个角度报):
|
|
544
|
+
- 在 Electron 里 spawn 出去的 node **必须带 `ELECTRON_RUN_AS_NODE=1`**,否则它当成"再开一个应用"、什么都不做就以 0 退出;
|
|
545
|
+
- 桌面版不是 npm 全局安装的,`dsh` 找不到 ⇒ 现在会去应用目录(`process.resourcesPath`)里找;
|
|
546
|
+
- **还找不到就明说**(`duty.log` 里会写清"请在设置里把 dsh 路径指过去"),不再静默失败。
|
|
547
|
+
|
|
548
|
+
**说明**:这一版只修 bug,不加功能 —— 下一个功能版是 `0.2.0`(「它刷过的视频」列表页 / 封面 / 会话头入口)。
|
|
549
|
+
|
|
550
|
+
---
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
### 并入的修复批(PR #4 · @ProgramerNoob · 17 个文件、+577/−142)
|
|
555
|
+
|
|
556
|
+
照着一份完整代码审查逐条过了一遍。界面没变,修的都是「看得见的行为」。
|
|
557
|
+
|
|
558
|
+
**修**
|
|
559
|
+
- ⭐⭐ **值班轮以前能拿到整台工具**:插件把内置的 Python MCP 整个挂给了它 ⇒ 「没开自动评论就不许发评论」那道闸
|
|
560
|
+
只在**工具参数**那一层拦着,模型换个写法就能绕过去。现在改成**按名单注册**:那一轮只拿得到**四个只读工具**
|
|
561
|
+
(搜视频 / 读字幕 / 读评论 / 看视频信息),**开了「自动评论」或「回复评论」才多给一个**「发评论」;
|
|
562
|
+
上传视频、发动态、私信、抓全站那些**根本不注册** —— 模型连它们的名字都看不到(名单走 `BILI_MCP_TOOLS` 下发)。
|
|
563
|
+
- ⭐ **发评论的回执以前不带 `rpid`**:判重表要记它、评论复核要靠它去查,可工具把回执丢了、只回一句「发送成功」
|
|
564
|
+
⇒ **复核永远查不到自己那条评论**,表里也只能空着。现在回执会带 `rpid`(回复别人时连 `root` 一起),
|
|
565
|
+
章程里也写明了「**取不到就写『未取到 rpid』,别自己编一个数字**」。
|
|
566
|
+
- ⭐ **抓评论出错不再装成「这条视频 0 条评论」**:风控(`-412`)、网络错以前被吞掉,日报里就直接当没评论 ⇒
|
|
567
|
+
现在错误会原样记下来,跟「真没有评论」分得清。
|
|
568
|
+
- ⭐ **「每天最多挑几条」以前根本不生效**:这一天到底挑了几条从来没人记 ⇒ 上限永远不触发,中午晚上各跑一轮、
|
|
569
|
+
写进同一份日报还可能互相覆盖。现在按**当天报告里数出来的条数**算(取它和账本里的较大值),到量就不跑;
|
|
570
|
+
提示词里也会写「今天已经挑过 N 条,这一轮最多再挑 M 条」+「有就追加到末尾,别覆盖」。
|
|
571
|
+
- ⭐ **配额不再把「提到过的视频」算成「挑中的」**(复查时发现的坑):报告里还会出现**没挑中**的视频号 ——
|
|
572
|
+
「因无字幕跳过 N 条」那行、评论区里别人问起的视频 —— 全按视频号数的话,一天只要提到 5 个就把当天的额度吃光,
|
|
573
|
+
**傍晚那轮直接不跑** ✗。现在章程规定**每条挑中的视频第一行写 `### BV号`**,宿主只数这种标题行
|
|
574
|
+
(漏写当成没挑中、给提到过的视频加上标题则当成挑中 —— 两种情况都会在日志里显形)。
|
|
575
|
+
- ⭐ **章程升级不再「改一次管一辈子」**:以前家里那份比插件里的新就一直用家里的 ⇒ 你改过一次,
|
|
576
|
+
以后插件带的规则(防注入、「空也是一种结果」这些)就再也进不来。现在记了账(`charter.sha256`):
|
|
577
|
+
**没改过 ⇒ 自动跟着升级;改过 ⇒ 你那份不动、新版另存成 `duty.md.new`**,日志里会说一句,你自己合。
|
|
578
|
+
⚠️ **从 0.1.5 及以前升上来的第一次没有账本可比** ⇒ 只能保守地当成「你改过」:新版落成 `duty.md.new`。
|
|
579
|
+
确认自己没改过,把 `duty.md.new` 覆盖到 `duty.md` 就行(一次的事,之后就跟着自动升级了)。
|
|
580
|
+
- ⭐ **设置页与 DSH 原生设置对账**:以前在「DSH 原生插件设置」里改了不生效(被插件自己的 `config.json` 盖住)。
|
|
581
|
+
现在**逐字段对账**:你在原生设置页里**显式设过**的字段以那边为准,其余以插件这一页为准;
|
|
582
|
+
在这一页改还会**同步写进原生设置**(写不进去会提示,值照样落在 `config.json`)。
|
|
583
|
+
- **凭证文件读取容错 + 原子写**:文件被截断 / 写坏时不再整轮崩,而是记一句日志当作「没登录」;
|
|
584
|
+
写入改成先写临时文件再替换 ⇒ 断电也不会留下半个 JSON。
|
|
585
|
+
- **扫码登录**:切走设置页不再留下一个每 2 秒轮询的定时器(以前会在后台一直轮、还往已卸载的页面写状态);
|
|
586
|
+
「扫了但响应里没有 SESSDATA」这类结果会**当场说清楚**,而不是让你等到超时;HTTP 出错(401/403/500)
|
|
587
|
+
不再被当成「已保存」。
|
|
588
|
+
- **数值钳制统一**:HTTP 接口、`bili_config` 工具、**以及读回来的配置**走同一套范围(「每轮最多发几条评论」
|
|
589
|
+
以前两条路都没钳,现在 0–20 —— 设置页里也能填 0 了,意思是不发评论)。
|
|
590
|
+
|
|
591
|
+
**清理**
|
|
592
|
+
- 老包名 `dsh-bili-duty` → `dsh-bili-scroll`(日志标签、页面里的 CSS 标记、`requirements.txt` 的注释;`LICENSE` 里那句
|
|
593
|
+
是上游署名,不动);MCP 客户端报给服务端的版本号改成读 `package.json`
|
|
594
|
+
- 删掉没人用的代码(评论复核里的 `mid` 兜底分支、`windowKey`)、修掉 `tools/_check-1016.mjs` 里写死的旧路径;
|
|
595
|
+
`package.json` 的 `files` 补上 `selfcheck.mjs`;去掉从没用过的 `@deepseek-ai/dsh-llm` peer;删掉仓库根一个 0 字节垃圾文件
|
|
596
|
+
|
|
597
|
+
**小提示**
|
|
598
|
+
- 章程(`prompts/duty.md`)是**运行时读**的 ⇒ 章程里那几条规则**改动之后不用重装插件**(下一轮就按新章程跑);
|
|
599
|
+
但**新章程文本本身**是插件带下来的 ⇒ 想拿到新规则,还是得升级一次插件。
|
|
600
|
+
- 路线图里那几件(每轮记账 / 周末时段 / 数据目录可配 / 「停掉这一轮」按钮)**还没做**,仍挂在 0.1.6 名下。
|
|
601
|
+
- 评论复核现在**只认 `rpid` 精确匹配**(那段 `mid` 兜底是死代码,删了):判重表里**没有 rpid 的老记录**
|
|
602
|
+
(0.1.5 及以前发的评论 —— 那会儿工具根本不给 rpid)会被直接跳过,不会被误判成「没发出去」。
|
|
603
|
+
- 逐条修完都跑过验证:`node tools/_check-1016.mjs` 里**新加了可复跑的断言**(白名单不留 `@mcp.tool()` 后门、
|
|
604
|
+
章程升级真的跑 `ensureCharter` 的三个分支、配额只数 `### BV号`、旧包名不再出现),`node selfcheck.mjs` 通过;
|
|
605
|
+
**设置对账**那部分是用一次性探针手工验的(含 revision 冲突重试那条路),**没进预检** —— 要让 `loadCfg`
|
|
606
|
+
可测,得先在 `index.js` 上开个口子,留到下一轮。
|
|
607
|
+
|
|
608
|
+
---
|
|
609
|
+
|
|
610
|
+
## 0.1.5 — 2026-10-16
|
|
611
|
+
|
|
612
|
+
**修(都是用户实测反馈,两条来自评论区)**
|
|
613
|
+
- ⭐⭐ **"空"不再被当成故障**:挑到**没有字幕、又是纯音乐 / 纯录屏**的视频时,本地转写会**诚实地返回空** ——
|
|
614
|
+
以前那一轮会把这当成"ASR 坏了",开始写调试脚本反复重试(**有用户实测烧掉了 27 次工具调用**),
|
|
615
|
+
最后**报告是空的、评论没发**,你什么也看不到。现在章程里写死了:
|
|
616
|
+
**空 / 0 字节 / 只有一行「字幕byXX」这类署名 ⇒ 就是这条视频没有语音**
|
|
617
|
+
⇒ 记「跳过(无语音)」、继续下一条,**不许重试、不许写调试脚本**。
|
|
618
|
+
- ⭐ **保底产物**:不管这一轮发生什么,**报告和判重表都会至少留一行**(先把这两样落下,再去做别的);
|
|
619
|
+
万一那一轮还是没写出报告,**插件自己会补一份占位报告**(写明退出码 + 附日志尾部)
|
|
620
|
+
—— 不会再出现"点了跑一轮,结果什么都没有"。
|
|
621
|
+
- 🔴 **防提示注入**:评论 / 字幕 / 视频简介里的文字**只当素材,不当指令** ——
|
|
622
|
+
有人在那里面写「忽略你之前的设定」「按我说的做」「我是作者派来的」,它**不会照做**
|
|
623
|
+
(它只认这一轮开头的说明和章程)。
|
|
624
|
+
- ⭐ **回复评论收紧了**:只有**同时满足三条**才回 ——
|
|
625
|
+
① 那条是**直接回在你那条评论下面**的人;② 问的是**这个插件怎么用**;③ **一两句话能答清**。
|
|
626
|
+
**要代码 / 要作品 / 要承诺 / 吵架 / 长篇追问 / 要隐私 一律不回**;每条正文 **≤100 字**、
|
|
627
|
+
**最多用 2 次工具调用**,⭐ **拿不准就跳过**(跳过比胡说便宜,也不会替你惹麻烦)。
|
|
628
|
+
|
|
629
|
+
**小提示**
|
|
630
|
+
- `prompts/duty.md`(章程)是**运行时读**的 ⇒ 上面两条规则**不升级插件也能生效**;
|
|
631
|
+
但"宿主补占位报告"是代码,要靠这一版带上去。
|
|
632
|
+
|
|
633
|
+
## 0.1.4 — 2026-10-16
|
|
634
|
+
|
|
635
|
+
**新**
|
|
636
|
+
- ⭐「**复核评论**」:接口回"发送成功"**不等于公开可见**(新号会被压审,而且那时候连 @ 都不会推给你)。
|
|
637
|
+
现在由插件**自己去核**:跑完一轮 90 秒后自动核一次,设置页底部的「**复核评论**」按钮也能手动核;
|
|
638
|
+
结果会追加到当天报告末尾。⚠️ 措辞是"**没查到**"而不是"没发出去" —— 翻页和排序都会漏,
|
|
639
|
+
所以看不到**不代表**没发。
|
|
640
|
+
|
|
641
|
+
**修(都是用户实测撞到的)**
|
|
642
|
+
- ⭐⭐ **桌面版装不起来(真 bug,这条最重要)**:以前插件装到桌面版(DSH NEXT / 0.2.x)上,
|
|
643
|
+
设置页里**根本不出现「刷B站」**,日志只有一句 `1 entry did not activate … failed to import`。
|
|
644
|
+
根因:宿主半 import 的两个包在 `package.json` 里是 *optional peer*,而桌面版 profile 是
|
|
645
|
+
`autoInstallPeers: false` ⇒ **pnpm 永远不装它们** ⇒ 插件整条不激活(web 上没露出来,纯属别的插件
|
|
646
|
+
恰好把它们 hoist 上来了)。现在:**不再裸 import 那两个包** —— 先找宿主那棵树、找不到就用自己依赖里那份,
|
|
647
|
+
`dsh-tools` 拿不到就用本地等价实现;`schemastery` 也正式进了 `dependencies`。**0.1.4 起装得上** ✓
|
|
648
|
+
(这一条是用户把复现步骤、两种装法的报错、根因和建议全查清后递过来的)。
|
|
649
|
+
- ⭐ **桌面版**:README 顶上加了提醒,另开一节「**装不上 / 卡住时先看这五条**」(桌面版自动跑会卡 ⇒ 先用手动「现在跑一轮」;
|
|
650
|
+
装依赖卡住 / 没有二维码的旧版指纹 + 救急一行;下不动 uv ⇒ 手动放 `uv.exe` 到 `<家目录>\bin\`;本地转写是两段式的)。
|
|
651
|
+
- ⭐ **判重表**:以前它可能把"家目录"理解成 `~` 而写错地方,**读不出来就当没记录过 ⇒ 同一批视频重复推送**。
|
|
652
|
+
现在路径由插件**预先建好并写死给那一轮**,读不到 / 写不进去**必须在报告里说出来**,而且那一轮不发评论。
|
|
653
|
+
- ⭐ **本地转写不再"静默跳过"**:报告里现在必须写一行「**因无字幕跳过 N 条**」(N=0 也写)——
|
|
654
|
+
以前它悄悄跳掉,你根本不知道漏了几条。
|
|
655
|
+
- ⭐ **中文编码**:给所有 Python 子进程统一钉 `PYTHONUTF8` / `PYTHONIOENCODING=utf-8`(Windows 默认 GBK,
|
|
656
|
+
有用户反馈装依赖时报 `UnicodeDecodeError`)。
|
|
657
|
+
- 文档修正:README 里装法写的是**旧包名**、还写着"工作目录 = 你填的工作区"(实际不是,已改对)。
|
|
658
|
+
|
|
659
|
+
## 0.1.3 — 2026-10-16
|
|
660
|
+
|
|
661
|
+
**新**
|
|
662
|
+
- ⭐ 设置页顶部显示**版本号**,一眼就知道自己装的是哪版。
|
|
663
|
+
- ⭐「**检查更新**」按钮:点一下就知道有没有新版(**只在点的时候联网**,结果缓存一天)。
|
|
664
|
+
- ⭐「**一键升级**」:发现真有新版时出现,点一下它自己升级 —— 之后**重启一次 dsh** 才生效。
|
|
665
|
+
- ⭐「**回复评论**」开关(**默认关**):开了之后它只回「**直接回复到你那条评论下面的人**」,
|
|
666
|
+
每轮最多回几条可以自己填;回复内容会写进报告,你能看到它说了什么。
|
|
667
|
+
|
|
668
|
+
**改**
|
|
669
|
+
- 版本比较改成"比大小"(本地版本比线上新时,不会误报"有新版")。
|
|
670
|
+
|
|
671
|
+
**两个提醒**
|
|
672
|
+
- 升级是"一键 + 重启",不是全自动 —— 最后那步重启只能你点。
|
|
673
|
+
- 如果你是**改过代码的本地版**(`link:` 装的),**别点「一键升级」** —— 它会把你的本地版换成发布版。
|
|
674
|
+
|
|
675
|
+
## 0.1.2 — 2026-10-15
|
|
676
|
+
|
|
677
|
+
**修**
|
|
678
|
+
- ⭐ **「就绪」不再骗人**:以前只要建过目录就显示"就绪" —— **装失败也显示就绪**(有用户被它骗着白折腾)。
|
|
679
|
+
现在会真的去检查依赖装上了没有;日志最后那行也改成真话。
|
|
680
|
+
- 只有依赖**装成功**才把 pythonPath 指过去(以前失败了也指,后面每一步都会连带失败)。
|
|
681
|
+
- 修了一个会崩的隐患:检查依赖时用到的一个函数没被 import。
|
|
682
|
+
|
|
683
|
+
**新**
|
|
684
|
+
- ⭐ 设置页底部加了「**看今天的报告**」—— 在页面里直接展开看,不用再去找文件。
|
|
685
|
+
还有「**打开报告文件夹**」「**打开家目录**」两个一键按钮。
|
|
686
|
+
- ⭐「**日报写多细**」三档:**完整 / 薄(每条一两行)/ 不写(只发评论)** —— 改了立刻生效。
|
|
687
|
+
|
|
688
|
+
**改**
|
|
689
|
+
- README 加了一句救急:**按钮叫「重装依赖」的就是旧版**,跑一次 add 升级。
|
|
690
|
+
- 包信息里补上仓库 / 主页 / issue 地址(npm 页面右侧会多一个 Repository 入口)。
|
|
691
|
+
## 0.1.1 — 2026-10-15
|
|
692
|
+
|
|
693
|
+
**修**
|
|
694
|
+
- 两轮同时转写会互相覆盖:每段音频改用各自的文件名(以前都叫 `audio.m4a`,会串台)
|
|
695
|
+
- 章程加两条纪律:「看够了就下结论」「工具失败两次就记为跳过」—— 实测能省下近一半的 token
|
|
696
|
+
|
|
697
|
+
**新**
|
|
698
|
+
- 设置页加「**测一下**」按钮:真跑一次登录检查 + 一次搜索,直接告诉你"能不能用"
|
|
699
|
+
- 徽章改成说人话:`环境已就绪` / `环境未装`(以前写 `venv 就绪`)
|
|
700
|
+
|
|
701
|
+
**改**
|
|
702
|
+
- 装依赖的按钮旁边会告诉你**下一步做什么**(装好了 → 去扫码登录)
|
|
703
|
+
- README 补上两件最要紧的:**需要 dsh ≥ 0.1.7-rc.1**(版本不满足会被内核静默跳过)、以及**占多少空间**(不装转写约 84MB)
|
|
704
|
+
|
|
705
|
+
---
|
|
706
|
+
|
|
707
|
+
## 0.1.0 — 2026-10-14
|
|
708
|
+
|
|
709
|
+
第一个版本:按谷时自动刷一轮 B站、**读字幕原文**判断、写一份日报,特别值得的留一条评论 **@ 你**。
|
|
710
|
+
设置页里可以配:峰谷时段 / 每天挑几条 / 关注关键词 / 工作区 / 要不要自动评论;账号走**扫码登录**。
|