shuadouyin 0.3.2 → 0.3.3

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/.dy-build-commit CHANGED
@@ -1 +1 @@
1
- ab12c5892c78af42d44e52d70980c742fdd40484
1
+ 9dfa8e6e905ba375b63fc90c7da17e95a6be4be8
@@ -42,7 +42,24 @@ export async function navigate(session, url, kind, signal) {
42
42
  ? state.page_kind === "search"
43
43
  : // The route commits before the profile renders, so the URL alone would let
44
44
  // the caller read a page whose header has not appeared yet.
45
- !!state.url?.includes("/user/") && state.page_kind === "profile", signal);
45
+ !!state.url?.includes("/user/") && state.page_kind === "profile", signal).catch((error) => {
46
+ // A profile that redirects elsewhere is a real answer, not a changed selector:
47
+ // Douyin sends restricted or unavailable accounts to the search page. Saying
48
+ // "the page did not reach the expected state" hides which of the two happened
49
+ // and sends the caller looking for a broken selector.
50
+ // Only when the page actually went somewhere else. A profile that simply took
51
+ // too long is a different answer, and calling it "not found" would send the
52
+ // caller looking for a restricted account that is fine.
53
+ if (kind === "profile" && error instanceof CliError && error.code === "selector_changed") {
54
+ const landed = String(error.details?.url ?? "");
55
+ if (landed && !landed.includes("/user/"))
56
+ throw new CliError("not_found", "This profile redirected elsewhere", {
57
+ hint: "Douyin sent this account somewhere other than its profile: it may be restricted, deleted, or require a fresh login. Run dy auth status, or open one of their works with dy video open.",
58
+ details: { requested: url, landed },
59
+ });
60
+ }
61
+ throw error;
62
+ });
46
63
  }
47
64
  // The recommended feed lives at https://www.douyin.com/?recommend=1, but a
48
65
  // plain load of that URL can land on the 精选 page instead, and the feed there
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shuadouyin",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "packageManager": "pnpm@10.34.7",
5
5
  "description": "Browse Douyin with a persistent bot persona and a memory of its own",
6
6
  "type": "module",
@@ -199,6 +199,38 @@ dy guide # 这份文档的完整内容
199
199
 
200
200
  `references/commands.md` 是按意图索引的全部命令地图。其余文件讲的是流程和判断,冲突时以命令行为为准。
201
201
 
202
+ ## 做事的时候一直在说话
203
+
204
+ 刷十条、看五条、评三条,这种活要跑几分钟。跑的时候**一条一条说**,别憋到最后一起报。
205
+
206
+ 原因很简单:用户在等。他不知道你在干什么,就只能看着屏幕不动。中途说一句「第 3 条是拆蟹教程,评论区在吵该不该用工具」,他就知道这事在推进,也能及时叫停——你要是刷到第 8 条才发现方向不对,已经浪费了七条。
207
+
208
+ **每做完一个可描述的动作就报一句:**
209
+
210
+ ```
211
+ 看第 1 条:南浔弹唱《暧昧》,评论区在接歌词,中位 8 字
212
+ 看第 2 条:拆蟹教程 4 分钟,三帧是完整流程,14.6 万赞
213
+ 第 2 条评了:「大家争的是快慢,我看的是拆的过程本身好看」
214
+ 第 3 条划过了,内容是纯广告
215
+ ```
216
+
217
+ **不要这样:**
218
+
219
+ ```
220
+ ✗ 好的,我来刷一下(然后 5 分钟没声,最后一次性贴 12 条结果)
221
+ ✗ 正在处理第 1/12 条……正在处理第 2/12 条……(这是在刷进度条,不是在说话)
222
+ ```
223
+
224
+ **判断一条值不值得说**:这条读完你有没有新的判断?有就说,没有就跳到下一条。流水账和沉默一样没用。
225
+
226
+ **长任务开始前先说一句要做什么、大概几步**,用户好在跑偏时叫停:
227
+
228
+ ```
229
+ 我去翻 8 条,挑 2 条有意思的看,可能评 1 条。
230
+ ```
231
+
232
+ 写操作(评论、私信)尤其要边说边做,因为 `dispatching` 之后不可逆——发之前那句「我要评这条:……」是用户最后的干预机会。
233
+
202
234
  ## 硬规则
203
235
 
204
236
  这几条在哪个参考文件里都成立: