@jackwener/opencli 1.5.5 → 1.5.7
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 +26 -0
- package/README.md +31 -4
- package/README.zh-CN.md +40 -5
- package/SKILL.md +1 -1
- package/dist/browser/cdp.d.ts +1 -0
- package/dist/browser/cdp.js +30 -27
- package/dist/browser/daemon-client.d.ts +11 -1
- package/dist/browser/daemon-client.js +3 -0
- package/dist/browser/dom-helpers.js +1 -0
- package/dist/browser/dom-helpers.test.js +14 -1
- package/dist/browser/mcp.js +18 -13
- package/dist/browser/page.d.ts +6 -0
- package/dist/browser/page.js +37 -2
- package/dist/browser/page.test.d.ts +1 -0
- package/dist/browser/page.test.js +44 -0
- package/dist/browser/stealth.js +198 -0
- package/dist/browser/stealth.test.d.ts +1 -0
- package/dist/browser/stealth.test.js +134 -0
- package/dist/browser.test.js +1 -1
- package/dist/build-manifest.d.ts +1 -0
- package/dist/build-manifest.js +5 -1
- package/dist/build-manifest.test.js +2 -0
- package/dist/cli-manifest.json +1821 -252
- package/dist/cli.js +20 -3
- package/dist/clis/antigravity/serve.d.ts +1 -1
- package/dist/clis/antigravity/serve.js +5 -8
- package/dist/clis/band/bands.d.ts +1 -0
- package/dist/clis/band/bands.js +72 -0
- package/dist/clis/band/mentions.d.ts +1 -0
- package/dist/clis/band/mentions.js +127 -0
- package/dist/clis/band/post.d.ts +1 -0
- package/dist/clis/band/post.js +175 -0
- package/dist/clis/band/posts.d.ts +1 -0
- package/dist/clis/band/posts.js +94 -0
- package/dist/clis/bilibili/subtitle.js +4 -0
- package/dist/clis/bilibili/subtitle.test.d.ts +1 -0
- package/dist/clis/bilibili/subtitle.test.js +48 -0
- package/dist/clis/chatwise/ask.js +0 -2
- package/dist/clis/chatwise/export.js +0 -2
- package/dist/clis/chatwise/history.js +0 -2
- package/dist/clis/chatwise/model.js +0 -2
- package/dist/clis/chatwise/new.js +1 -2
- package/dist/clis/chatwise/read.js +0 -2
- package/dist/clis/chatwise/screenshot.js +1 -2
- package/dist/clis/chatwise/send.js +0 -2
- package/dist/clis/chatwise/status.js +1 -2
- package/dist/clis/ctrip/search.d.ts +13 -0
- package/dist/clis/ctrip/search.js +73 -48
- package/dist/clis/ctrip/search.test.d.ts +1 -0
- package/dist/clis/ctrip/search.test.js +64 -0
- package/dist/clis/doubao/detail.d.ts +1 -0
- package/dist/clis/doubao/detail.js +33 -0
- package/dist/clis/doubao/detail.test.d.ts +1 -0
- package/dist/clis/doubao/detail.test.js +42 -0
- package/dist/clis/doubao/history.d.ts +1 -0
- package/dist/clis/doubao/history.js +28 -0
- package/dist/clis/doubao/history.test.d.ts +1 -0
- package/dist/clis/doubao/history.test.js +37 -0
- package/dist/clis/doubao/meeting-summary.d.ts +1 -0
- package/dist/clis/doubao/meeting-summary.js +39 -0
- package/dist/clis/doubao/meeting-transcript.d.ts +1 -0
- package/dist/clis/doubao/meeting-transcript.js +36 -0
- package/dist/clis/doubao/utils.d.ts +27 -0
- package/dist/clis/doubao/utils.js +317 -0
- package/dist/clis/doubao/utils.test.d.ts +1 -0
- package/dist/clis/doubao/utils.test.js +24 -0
- package/dist/clis/douyin/_shared/public-api.d.ts +33 -0
- package/dist/clis/douyin/_shared/public-api.js +29 -0
- package/dist/clis/douyin/_shared/sts2.js +8 -2
- package/dist/clis/douyin/_shared/sts2.test.d.ts +1 -0
- package/dist/clis/douyin/_shared/sts2.test.js +27 -0
- package/dist/clis/douyin/activities.js +4 -2
- package/dist/clis/douyin/activities.test.js +34 -1
- package/dist/clis/douyin/collections.js +1 -1
- package/dist/clis/douyin/collections.test.js +24 -2
- package/dist/clis/douyin/draft.d.ts +8 -11
- package/dist/clis/douyin/draft.js +302 -185
- package/dist/clis/douyin/draft.test.d.ts +1 -1
- package/dist/clis/douyin/draft.test.js +357 -2
- package/dist/clis/douyin/hashtag.js +9 -2
- package/dist/clis/douyin/hashtag.test.js +35 -2
- package/dist/clis/douyin/profile.js +1 -1
- package/dist/clis/douyin/profile.test.js +36 -1
- package/dist/clis/douyin/user-videos.d.ts +5 -0
- package/dist/clis/douyin/user-videos.js +74 -0
- package/dist/clis/douyin/user-videos.test.d.ts +1 -0
- package/dist/clis/douyin/user-videos.test.js +108 -0
- package/dist/clis/douyin/videos.js +22 -5
- package/dist/clis/douyin/videos.test.js +45 -2
- package/dist/clis/facebook/search.test.d.ts +5 -0
- package/dist/clis/facebook/search.test.js +60 -0
- package/dist/clis/facebook/search.yaml +4 -3
- package/dist/clis/instagram/download.d.ts +16 -0
- package/dist/clis/instagram/download.js +225 -0
- package/dist/clis/instagram/download.test.d.ts +1 -0
- package/dist/clis/instagram/download.test.js +118 -0
- package/dist/clis/notebooklm/bind-current.d.ts +1 -0
- package/dist/clis/notebooklm/bind-current.js +29 -0
- package/dist/clis/notebooklm/bind-current.test.d.ts +1 -0
- package/dist/clis/notebooklm/bind-current.test.js +35 -0
- package/dist/clis/notebooklm/binding.test.d.ts +1 -0
- package/dist/clis/notebooklm/binding.test.js +44 -0
- package/dist/clis/notebooklm/compat.test.d.ts +3 -0
- package/dist/clis/notebooklm/compat.test.js +16 -0
- package/dist/clis/notebooklm/current.d.ts +1 -0
- package/dist/clis/notebooklm/current.js +28 -0
- package/dist/clis/notebooklm/get.d.ts +1 -0
- package/dist/clis/notebooklm/get.js +37 -0
- package/dist/clis/notebooklm/history.d.ts +1 -0
- package/dist/clis/notebooklm/history.js +25 -0
- package/dist/clis/notebooklm/history.test.d.ts +1 -0
- package/dist/clis/notebooklm/history.test.js +58 -0
- package/dist/clis/notebooklm/list.d.ts +1 -0
- package/dist/clis/notebooklm/list.js +35 -0
- package/dist/clis/notebooklm/note-list.d.ts +1 -0
- package/dist/clis/notebooklm/note-list.js +28 -0
- package/dist/clis/notebooklm/note-list.test.d.ts +1 -0
- package/dist/clis/notebooklm/note-list.test.js +56 -0
- package/dist/clis/notebooklm/notes-get.d.ts +1 -0
- package/dist/clis/notebooklm/notes-get.js +47 -0
- package/dist/clis/notebooklm/notes-get.test.d.ts +1 -0
- package/dist/clis/notebooklm/notes-get.test.js +72 -0
- package/dist/clis/notebooklm/rpc.d.ts +36 -0
- package/dist/clis/notebooklm/rpc.js +189 -0
- package/dist/clis/notebooklm/rpc.test.d.ts +1 -0
- package/dist/clis/notebooklm/rpc.test.js +105 -0
- package/dist/clis/notebooklm/shared.d.ts +87 -0
- package/dist/clis/notebooklm/shared.js +3 -0
- package/dist/clis/notebooklm/source-fulltext.d.ts +1 -0
- package/dist/clis/notebooklm/source-fulltext.js +44 -0
- package/dist/clis/notebooklm/source-fulltext.test.d.ts +1 -0
- package/dist/clis/notebooklm/source-fulltext.test.js +106 -0
- package/dist/clis/notebooklm/source-get.d.ts +1 -0
- package/dist/clis/notebooklm/source-get.js +40 -0
- package/dist/clis/notebooklm/source-get.test.d.ts +1 -0
- package/dist/clis/notebooklm/source-get.test.js +84 -0
- package/dist/clis/notebooklm/source-guide.d.ts +1 -0
- package/dist/clis/notebooklm/source-guide.js +44 -0
- package/dist/clis/notebooklm/source-guide.test.d.ts +1 -0
- package/dist/clis/notebooklm/source-guide.test.js +104 -0
- package/dist/clis/notebooklm/source-list.d.ts +1 -0
- package/dist/clis/notebooklm/source-list.js +30 -0
- package/dist/clis/notebooklm/status.d.ts +1 -0
- package/dist/clis/notebooklm/status.js +31 -0
- package/dist/clis/notebooklm/summary.d.ts +1 -0
- package/dist/clis/notebooklm/summary.js +30 -0
- package/dist/clis/notebooklm/summary.test.d.ts +1 -0
- package/dist/clis/notebooklm/summary.test.js +78 -0
- package/dist/clis/notebooklm/utils.d.ts +37 -0
- package/dist/clis/notebooklm/utils.js +739 -0
- package/dist/clis/notebooklm/utils.test.d.ts +1 -0
- package/dist/clis/notebooklm/utils.test.js +390 -0
- package/dist/clis/ones/common.d.ts +32 -0
- package/dist/clis/ones/common.js +144 -0
- package/dist/clis/ones/enrich-tasks.d.ts +5 -0
- package/dist/clis/ones/enrich-tasks.js +37 -0
- package/dist/clis/ones/login.d.ts +1 -0
- package/dist/clis/ones/login.js +80 -0
- package/dist/clis/ones/logout.d.ts +1 -0
- package/dist/clis/ones/logout.js +17 -0
- package/dist/clis/ones/me.d.ts +1 -0
- package/dist/clis/ones/me.js +30 -0
- package/dist/clis/ones/my-tasks.d.ts +1 -0
- package/dist/clis/ones/my-tasks.js +120 -0
- package/dist/clis/ones/resolve-labels.d.ts +10 -0
- package/dist/clis/ones/resolve-labels.js +64 -0
- package/dist/clis/ones/task-helpers.d.ts +29 -0
- package/dist/clis/ones/task-helpers.js +212 -0
- package/dist/clis/ones/task-helpers.test.d.ts +1 -0
- package/dist/clis/ones/task-helpers.test.js +12 -0
- package/dist/clis/ones/task.d.ts +1 -0
- package/dist/clis/ones/task.js +66 -0
- package/dist/clis/ones/tasks.d.ts +1 -0
- package/dist/clis/ones/tasks.js +79 -0
- package/dist/clis/ones/token-info.d.ts +1 -0
- package/dist/clis/ones/token-info.js +42 -0
- package/dist/clis/ones/worklog.d.ts +11 -0
- package/dist/clis/ones/worklog.js +267 -0
- package/dist/clis/ones/worklog.test.d.ts +1 -0
- package/dist/clis/ones/worklog.test.js +20 -0
- package/dist/clis/spotify/spotify.d.ts +1 -0
- package/dist/clis/spotify/spotify.js +316 -0
- package/dist/clis/spotify/utils.d.ts +21 -0
- package/dist/clis/spotify/utils.js +66 -0
- package/dist/clis/spotify/utils.test.d.ts +1 -0
- package/dist/clis/spotify/utils.test.js +67 -0
- package/dist/clis/substack/utils.d.ts +4 -0
- package/dist/clis/substack/utils.js +8 -2
- package/dist/clis/substack/utils.test.d.ts +1 -0
- package/dist/clis/substack/utils.test.js +46 -0
- package/dist/clis/tieba/commands.test.d.ts +4 -0
- package/dist/clis/tieba/commands.test.js +79 -0
- package/dist/clis/tieba/hot.d.ts +1 -0
- package/dist/clis/tieba/hot.js +48 -0
- package/dist/clis/tieba/posts.d.ts +1 -0
- package/dist/clis/tieba/posts.js +85 -0
- package/dist/clis/tieba/read.d.ts +1 -0
- package/dist/clis/tieba/read.js +140 -0
- package/dist/clis/tieba/search.d.ts +1 -0
- package/dist/clis/tieba/search.js +108 -0
- package/dist/clis/tieba/utils.d.ts +101 -0
- package/dist/clis/tieba/utils.js +240 -0
- package/dist/clis/tieba/utils.test.d.ts +1 -0
- package/dist/clis/tieba/utils.test.js +290 -0
- package/dist/clis/v2ex/hot.yaml +4 -1
- package/dist/clis/v2ex/latest.yaml +4 -1
- package/dist/clis/v2ex/topic.yaml +6 -1
- package/dist/clis/weixin/download.d.ts +9 -0
- package/dist/clis/weixin/download.js +76 -6
- package/dist/clis/weread/book.js +206 -13
- package/dist/clis/weread/commands.test.js +331 -0
- package/dist/clis/weread/private-api-regression.test.d.ts +1 -0
- package/dist/{weread-private-api-regression.test.js → clis/weread/private-api-regression.test.js} +92 -30
- package/dist/clis/weread/search-regression.test.d.ts +1 -0
- package/dist/clis/weread/search-regression.test.js +407 -0
- package/dist/clis/weread/search.js +143 -7
- package/dist/clis/weread/shelf.js +13 -95
- package/dist/clis/weread/utils.d.ts +56 -0
- package/dist/clis/weread/utils.js +234 -7
- package/dist/clis/weread/utils.test.js +71 -1
- package/dist/clis/xiaohongshu/comments.d.ts +3 -0
- package/dist/clis/xiaohongshu/comments.js +76 -17
- package/dist/clis/xiaohongshu/comments.test.js +70 -9
- package/dist/clis/xiaohongshu/download.d.ts +4 -1
- package/dist/clis/xiaohongshu/download.js +83 -22
- package/dist/clis/xiaohongshu/download.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/download.test.js +75 -0
- package/dist/clis/xiaohongshu/note-helpers.d.ts +12 -0
- package/dist/clis/xiaohongshu/note-helpers.js +23 -0
- package/dist/clis/xiaohongshu/note.d.ts +7 -0
- package/dist/clis/xiaohongshu/note.js +76 -0
- package/dist/clis/xiaohongshu/note.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/note.test.js +136 -0
- package/dist/clis/xiaohongshu/publish.d.ts +1 -1
- package/dist/clis/xiaohongshu/publish.js +78 -31
- package/dist/clis/xiaohongshu/publish.test.js +66 -1
- package/dist/clis/xiaohongshu/search.js +9 -0
- package/dist/clis/xiaohongshu/search.test.js +10 -4
- package/dist/clis/xiaohongshu/user-helpers.d.ts +1 -0
- package/dist/clis/xiaohongshu/user-helpers.js +2 -0
- package/dist/clis/xiaohongshu/user-helpers.test.js +18 -0
- package/dist/clis/xueqiu/comments.d.ts +118 -0
- package/dist/clis/xueqiu/comments.js +354 -0
- package/dist/clis/xueqiu/comments.test.d.ts +1 -0
- package/dist/clis/xueqiu/comments.test.js +696 -0
- package/dist/clis/youtube/search.js +57 -17
- package/dist/clis/youtube/transcript.js +2 -4
- package/dist/clis/youtube/utils.d.ts +9 -0
- package/dist/clis/youtube/utils.js +67 -3
- package/dist/clis/youtube/utils.test.d.ts +1 -0
- package/dist/clis/youtube/utils.test.js +37 -0
- package/dist/clis/youtube/video.js +16 -15
- package/dist/clis/zhihu/question.js +19 -17
- package/dist/clis/zhihu/question.test.d.ts +1 -0
- package/dist/clis/zhihu/question.test.js +54 -0
- package/dist/clis/zsxq/dynamics.d.ts +1 -0
- package/dist/clis/zsxq/dynamics.js +47 -0
- package/dist/clis/zsxq/groups.d.ts +1 -0
- package/dist/clis/zsxq/groups.js +32 -0
- package/dist/clis/zsxq/search.d.ts +1 -0
- package/dist/clis/zsxq/search.js +43 -0
- package/dist/clis/zsxq/search.test.d.ts +1 -0
- package/dist/clis/zsxq/search.test.js +24 -0
- package/dist/clis/zsxq/topic.d.ts +1 -0
- package/dist/clis/zsxq/topic.js +47 -0
- package/dist/clis/zsxq/topic.test.d.ts +1 -0
- package/dist/clis/zsxq/topic.test.js +29 -0
- package/dist/clis/zsxq/topics.d.ts +1 -0
- package/dist/clis/zsxq/topics.js +25 -0
- package/dist/clis/zsxq/topics.test.d.ts +1 -0
- package/dist/clis/zsxq/topics.test.js +24 -0
- package/dist/clis/zsxq/utils.d.ts +97 -0
- package/dist/clis/zsxq/utils.js +230 -0
- package/dist/commanderAdapter.js +10 -1
- package/dist/commanderAdapter.test.js +64 -0
- package/dist/commands/daemon.d.ts +9 -0
- package/dist/commands/daemon.js +124 -0
- package/dist/commands/daemon.test.d.ts +1 -0
- package/dist/commands/daemon.test.js +185 -0
- package/dist/completion.js +3 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/daemon.d.ts +1 -1
- package/dist/daemon.js +25 -14
- package/dist/daemon.test.d.ts +1 -0
- package/dist/daemon.test.js +65 -0
- package/dist/discovery.d.ts +9 -0
- package/dist/discovery.js +47 -2
- package/dist/electron-apps.d.ts +29 -0
- package/dist/electron-apps.js +65 -0
- package/dist/electron-apps.test.d.ts +1 -0
- package/dist/electron-apps.test.js +43 -0
- package/dist/engine.test.js +41 -9
- package/dist/execution.js +20 -16
- package/dist/external-clis.yaml +17 -0
- package/dist/idle-manager.d.ts +19 -0
- package/dist/idle-manager.js +54 -0
- package/dist/launcher.d.ts +36 -0
- package/dist/launcher.js +152 -0
- package/dist/launcher.test.d.ts +1 -0
- package/dist/launcher.test.js +57 -0
- package/dist/main.js +3 -3
- package/dist/registry.d.ts +1 -0
- package/dist/registry.js +31 -3
- package/dist/registry.test.js +13 -0
- package/dist/runtime.d.ts +5 -3
- package/dist/runtime.js +12 -5
- package/dist/serialization.d.ts +1 -0
- package/dist/serialization.js +3 -0
- package/dist/serialization.test.js +17 -1
- package/dist/tui.d.ts +7 -0
- package/dist/tui.js +52 -0
- package/dist/tui.test.d.ts +1 -0
- package/dist/tui.test.js +19 -0
- package/dist/types.d.ts +5 -0
- package/dist/weixin-download.test.js +14 -0
- package/docs/.vitepress/config.mts +4 -0
- package/docs/adapters/browser/band.md +63 -0
- package/docs/adapters/browser/notebooklm.md +69 -0
- package/docs/adapters/browser/ones.md +59 -0
- package/docs/adapters/browser/spotify.md +62 -0
- package/docs/adapters/browser/tieba.md +45 -0
- package/docs/adapters/browser/xiaohongshu.md +19 -10
- package/docs/adapters/browser/xueqiu.md +5 -0
- package/docs/adapters/browser/zsxq.md +49 -0
- package/docs/adapters/index.md +67 -63
- package/docs/adapters-doc/ones.md +32 -0
- package/docs/guide/browser-bridge.md +12 -0
- package/docs/guide/troubleshooting.md +9 -4
- package/docs/superpowers/plans/2026-03-31-daemon-lifecycle-redesign.md +857 -0
- package/docs/superpowers/specs/2026-03-31-daemon-lifecycle-redesign.md +208 -0
- package/docs/zh/guide/browser-bridge.md +12 -0
- package/extension/dist/background.js +794 -513
- package/extension/src/background.test.ts +202 -2
- package/extension/src/background.ts +189 -10
- package/extension/src/cdp.ts +54 -0
- package/extension/src/protocol.ts +11 -5
- package/package.json +1 -1
- package/scripts/postinstall.js +16 -0
- package/src/browser/cdp.ts +24 -17
- package/src/browser/daemon-client.ts +11 -1
- package/src/browser/dom-helpers.test.ts +15 -1
- package/src/browser/dom-helpers.ts +1 -0
- package/src/browser/mcp.ts +18 -13
- package/src/browser/page.test.ts +58 -0
- package/src/browser/page.ts +34 -2
- package/src/browser/stealth.test.ts +153 -0
- package/src/browser/stealth.ts +198 -0
- package/src/browser.test.ts +1 -1
- package/src/build-manifest.test.ts +2 -0
- package/src/build-manifest.ts +6 -1
- package/src/cli.ts +21 -3
- package/src/clis/antigravity/SKILL.md +3 -12
- package/src/clis/antigravity/serve.ts +5 -10
- package/src/clis/band/bands.ts +76 -0
- package/src/clis/band/mentions.ts +134 -0
- package/src/clis/band/post.ts +187 -0
- package/src/clis/band/posts.ts +106 -0
- package/src/clis/bilibili/subtitle.test.ts +60 -0
- package/src/clis/bilibili/subtitle.ts +4 -0
- package/src/clis/chatwise/ask.ts +0 -2
- package/src/clis/chatwise/export.ts +0 -2
- package/src/clis/chatwise/history.ts +0 -2
- package/src/clis/chatwise/model.ts +0 -2
- package/src/clis/chatwise/new.ts +1 -2
- package/src/clis/chatwise/read.ts +0 -2
- package/src/clis/chatwise/screenshot.ts +1 -2
- package/src/clis/chatwise/send.ts +0 -2
- package/src/clis/chatwise/status.ts +1 -2
- package/src/clis/ctrip/search.test.ts +73 -0
- package/src/clis/ctrip/search.ts +97 -47
- package/src/clis/doubao/detail.test.ts +53 -0
- package/src/clis/doubao/detail.ts +41 -0
- package/src/clis/doubao/history.test.ts +45 -0
- package/src/clis/doubao/history.ts +32 -0
- package/src/clis/doubao/meeting-summary.ts +53 -0
- package/src/clis/doubao/meeting-transcript.ts +48 -0
- package/src/clis/doubao/utils.test.ts +45 -0
- package/src/clis/doubao/utils.ts +371 -0
- package/src/clis/douyin/_shared/public-api.ts +84 -0
- package/src/clis/douyin/_shared/sts2.test.ts +31 -0
- package/src/clis/douyin/_shared/sts2.ts +11 -3
- package/src/clis/douyin/activities.test.ts +41 -1
- package/src/clis/douyin/activities.ts +12 -3
- package/src/clis/douyin/collections.test.ts +35 -2
- package/src/clis/douyin/collections.ts +1 -1
- package/src/clis/douyin/draft.test.ts +444 -2
- package/src/clis/douyin/draft.ts +382 -218
- package/src/clis/douyin/hashtag.test.ts +42 -2
- package/src/clis/douyin/hashtag.ts +11 -3
- package/src/clis/douyin/profile.test.ts +43 -1
- package/src/clis/douyin/profile.ts +9 -2
- package/src/clis/douyin/user-videos.test.ts +122 -0
- package/src/clis/douyin/user-videos.ts +101 -0
- package/src/clis/douyin/videos.test.ts +52 -2
- package/src/clis/douyin/videos.ts +49 -15
- package/src/clis/facebook/search.test.ts +70 -0
- package/src/clis/facebook/search.yaml +4 -3
- package/src/clis/instagram/download.test.ts +159 -0
- package/src/clis/instagram/download.ts +286 -0
- package/src/clis/notebooklm/bind-current.test.ts +43 -0
- package/src/clis/notebooklm/bind-current.ts +36 -0
- package/src/clis/notebooklm/binding.test.ts +53 -0
- package/src/clis/notebooklm/compat.test.ts +19 -0
- package/src/clis/notebooklm/current.ts +38 -0
- package/src/clis/notebooklm/get.ts +53 -0
- package/src/clis/notebooklm/history.test.ts +70 -0
- package/src/clis/notebooklm/history.ts +36 -0
- package/src/clis/notebooklm/list.ts +40 -0
- package/src/clis/notebooklm/note-list.test.ts +64 -0
- package/src/clis/notebooklm/note-list.ts +42 -0
- package/src/clis/notebooklm/notes-get.test.ts +88 -0
- package/src/clis/notebooklm/notes-get.ts +67 -0
- package/src/clis/notebooklm/rpc.test.ts +126 -0
- package/src/clis/notebooklm/rpc.ts +286 -0
- package/src/clis/notebooklm/shared.ts +98 -0
- package/src/clis/notebooklm/source-fulltext.test.ts +123 -0
- package/src/clis/notebooklm/source-fulltext.ts +69 -0
- package/src/clis/notebooklm/source-get.test.ts +100 -0
- package/src/clis/notebooklm/source-get.ts +60 -0
- package/src/clis/notebooklm/source-guide.test.ts +121 -0
- package/src/clis/notebooklm/source-guide.ts +69 -0
- package/src/clis/notebooklm/source-list.ts +45 -0
- package/src/clis/notebooklm/status.ts +34 -0
- package/src/clis/notebooklm/summary.test.ts +94 -0
- package/src/clis/notebooklm/summary.ts +45 -0
- package/src/clis/notebooklm/utils.test.ts +446 -0
- package/src/clis/notebooklm/utils.ts +893 -0
- package/src/clis/ones/common.ts +187 -0
- package/src/clis/ones/enrich-tasks.ts +47 -0
- package/src/clis/ones/login.ts +103 -0
- package/src/clis/ones/logout.ts +19 -0
- package/src/clis/ones/me.ts +34 -0
- package/src/clis/ones/my-tasks.ts +148 -0
- package/src/clis/ones/resolve-labels.ts +80 -0
- package/src/clis/ones/task-helpers.test.ts +14 -0
- package/src/clis/ones/task-helpers.ts +214 -0
- package/src/clis/ones/task.ts +79 -0
- package/src/clis/ones/tasks.ts +92 -0
- package/src/clis/ones/token-info.ts +46 -0
- package/src/clis/ones/worklog.test.ts +24 -0
- package/src/clis/ones/worklog.ts +306 -0
- package/src/clis/spotify/spotify.ts +328 -0
- package/src/clis/spotify/utils.test.ts +87 -0
- package/src/clis/spotify/utils.ts +92 -0
- package/src/clis/substack/utils.test.ts +54 -0
- package/src/clis/substack/utils.ts +10 -2
- package/src/clis/tieba/commands.test.ts +86 -0
- package/src/clis/tieba/hot.ts +52 -0
- package/src/clis/tieba/posts.ts +108 -0
- package/src/clis/tieba/read.ts +158 -0
- package/src/clis/tieba/search.ts +119 -0
- package/src/clis/tieba/utils.test.ts +322 -0
- package/src/clis/tieba/utils.ts +348 -0
- package/src/clis/v2ex/hot.yaml +4 -1
- package/src/clis/v2ex/latest.yaml +4 -1
- package/src/clis/v2ex/topic.yaml +6 -1
- package/src/clis/weixin/download.ts +95 -6
- package/src/clis/weread/book.ts +256 -13
- package/src/clis/weread/commands.test.ts +409 -0
- package/src/{weread-private-api-regression.test.ts → clis/weread/private-api-regression.test.ts} +108 -30
- package/src/clis/weread/search-regression.test.ts +440 -0
- package/src/clis/weread/search.ts +189 -9
- package/src/clis/weread/shelf.ts +20 -122
- package/src/clis/weread/utils.test.ts +81 -1
- package/src/clis/weread/utils.ts +293 -7
- package/src/clis/xiaohongshu/comments.test.ts +85 -9
- package/src/clis/xiaohongshu/comments.ts +76 -17
- package/src/clis/xiaohongshu/download.test.ts +96 -0
- package/src/clis/xiaohongshu/download.ts +83 -22
- package/src/clis/xiaohongshu/note-helpers.ts +25 -0
- package/src/clis/xiaohongshu/note.test.ts +164 -0
- package/src/clis/xiaohongshu/note.ts +86 -0
- package/src/clis/xiaohongshu/publish.test.ts +79 -1
- package/src/clis/xiaohongshu/publish.ts +84 -30
- package/src/clis/xiaohongshu/search.test.ts +11 -4
- package/src/clis/xiaohongshu/search.ts +13 -0
- package/src/clis/xiaohongshu/user-helpers.test.ts +23 -0
- package/src/clis/xiaohongshu/user-helpers.ts +4 -0
- package/src/clis/xueqiu/comments.test.ts +823 -0
- package/src/clis/xueqiu/comments.ts +461 -0
- package/src/clis/youtube/search.ts +57 -17
- package/src/clis/youtube/transcript.ts +2 -4
- package/src/clis/youtube/utils.test.ts +43 -0
- package/src/clis/youtube/utils.ts +69 -0
- package/src/clis/youtube/video.ts +16 -15
- package/src/clis/zhihu/question.test.ts +71 -0
- package/src/clis/zhihu/question.ts +27 -15
- package/src/clis/zsxq/dynamics.ts +60 -0
- package/src/clis/zsxq/groups.ts +41 -0
- package/src/clis/zsxq/search.test.ts +29 -0
- package/src/clis/zsxq/search.ts +54 -0
- package/src/clis/zsxq/topic.test.ts +34 -0
- package/src/clis/zsxq/topic.ts +68 -0
- package/src/clis/zsxq/topics.test.ts +29 -0
- package/src/clis/zsxq/topics.ts +36 -0
- package/src/clis/zsxq/utils.ts +351 -0
- package/src/commanderAdapter.test.ts +77 -0
- package/src/commanderAdapter.ts +8 -1
- package/src/commands/daemon.test.ts +238 -0
- package/src/commands/daemon.ts +135 -0
- package/src/completion.ts +2 -1
- package/src/constants.ts +3 -0
- package/src/daemon.test.ts +88 -0
- package/src/daemon.ts +26 -14
- package/src/discovery.ts +52 -2
- package/src/electron-apps.test.ts +50 -0
- package/src/electron-apps.ts +89 -0
- package/src/engine.test.ts +45 -9
- package/src/execution.ts +24 -19
- package/src/external-clis.yaml +17 -0
- package/src/idle-manager.ts +60 -0
- package/src/launcher.test.ts +67 -0
- package/src/launcher.ts +185 -0
- package/src/main.ts +3 -2
- package/src/registry.test.ts +15 -0
- package/src/registry.ts +32 -3
- package/src/runtime.ts +13 -7
- package/src/serialization.test.ts +19 -1
- package/src/serialization.ts +2 -0
- package/src/tui.test.ts +23 -0
- package/src/tui.ts +65 -0
- package/src/types.ts +5 -0
- package/src/weixin-download.test.ts +27 -0
- package/tests/e2e/band-auth.test.ts +20 -0
- package/tests/e2e/browser-auth-helpers.ts +18 -0
- package/tests/e2e/browser-auth.test.ts +35 -47
- package/tests/e2e/browser-public-extended.test.ts +6 -2
- package/tests/e2e/browser-public.test.ts +288 -0
- package/tests/e2e/management.test.ts +1 -1
- package/tests/e2e/plugin-management.test.ts +1 -1
- package/vitest.config.ts +1 -0
- package/chatwise-opencli.ps1 +0 -82
- package/dist/clis/chatwise/shared.d.ts +0 -2
- package/dist/clis/chatwise/shared.js +0 -6
- package/dist/weread-private-api-regression.test.d.ts +0 -1
- package/dist/weread-search-regression.test.d.ts +0 -1
- package/dist/weread-search-regression.test.js +0 -39
- package/src/clis/chatwise/shared.ts +0 -8
- package/src/weread-search-regression.test.ts +0 -44
|
@@ -2,6 +2,11 @@ import type { IPage } from '../../types.js';
|
|
|
2
2
|
export declare const DOUBAO_DOMAIN = "www.doubao.com";
|
|
3
3
|
export declare const DOUBAO_CHAT_URL = "https://www.doubao.com/chat";
|
|
4
4
|
export declare const DOUBAO_NEW_CHAT_URL = "https://www.doubao.com/chat/new-thread/create-by-msg";
|
|
5
|
+
export interface DoubaoConversation {
|
|
6
|
+
Id: string;
|
|
7
|
+
Title: string;
|
|
8
|
+
Url: string;
|
|
9
|
+
}
|
|
5
10
|
export interface DoubaoTurn {
|
|
6
11
|
Role: 'User' | 'Assistant' | 'System';
|
|
7
12
|
Text: string;
|
|
@@ -20,4 +25,26 @@ export declare function getDoubaoVisibleTurns(page: IPage): Promise<DoubaoTurn[]
|
|
|
20
25
|
export declare function getDoubaoTranscriptLines(page: IPage): Promise<string[]>;
|
|
21
26
|
export declare function sendDoubaoMessage(page: IPage, text: string): Promise<'button' | 'enter'>;
|
|
22
27
|
export declare function waitForDoubaoResponse(page: IPage, beforeLines: string[], beforeTurns: DoubaoTurn[], promptText: string, timeoutSeconds: number): Promise<string>;
|
|
28
|
+
export declare function getDoubaoConversationList(page: IPage): Promise<DoubaoConversation[]>;
|
|
29
|
+
export interface DoubaoMessage {
|
|
30
|
+
Role: 'User' | 'Assistant' | 'System';
|
|
31
|
+
Text: string;
|
|
32
|
+
HasMeetingCard: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface DoubaoMeetingInfo {
|
|
35
|
+
title: string;
|
|
36
|
+
time: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function parseDoubaoConversationId(input: string): string;
|
|
39
|
+
export declare function navigateToConversation(page: IPage, conversationId: string): Promise<void>;
|
|
40
|
+
export declare function getConversationDetail(page: IPage, conversationId: string): Promise<{
|
|
41
|
+
messages: DoubaoMessage[];
|
|
42
|
+
meeting: DoubaoMeetingInfo | null;
|
|
43
|
+
}>;
|
|
44
|
+
export declare function mergeTranscriptSnapshots(existing: string, incoming: string): string;
|
|
45
|
+
export declare function openMeetingPanel(page: IPage, conversationId: string): Promise<boolean>;
|
|
46
|
+
export declare function getMeetingSummary(page: IPage): Promise<string>;
|
|
47
|
+
export declare function getMeetingChapters(page: IPage): Promise<string>;
|
|
48
|
+
export declare function getMeetingTranscript(page: IPage): Promise<string>;
|
|
49
|
+
export declare function triggerTranscriptDownload(page: IPage): Promise<boolean>;
|
|
23
50
|
export declare function startNewDoubaoChat(page: IPage): Promise<string>;
|
|
@@ -551,6 +551,323 @@ export async function waitForDoubaoResponse(page, beforeLines, beforeTurns, prom
|
|
|
551
551
|
}
|
|
552
552
|
return lastCandidate;
|
|
553
553
|
}
|
|
554
|
+
function getConversationListScript() {
|
|
555
|
+
return `
|
|
556
|
+
(() => {
|
|
557
|
+
const sidebar = document.querySelector('[data-testid="flow_chat_sidebar"]');
|
|
558
|
+
if (!sidebar) return [];
|
|
559
|
+
|
|
560
|
+
const items = Array.from(
|
|
561
|
+
sidebar.querySelectorAll('a[data-testid="chat_list_thread_item"]')
|
|
562
|
+
);
|
|
563
|
+
|
|
564
|
+
return items
|
|
565
|
+
.map(a => {
|
|
566
|
+
const href = a.getAttribute('href') || '';
|
|
567
|
+
const match = href.match(/\\/chat\\/(\\d{10,})/);
|
|
568
|
+
if (!match) return null;
|
|
569
|
+
const id = match[1];
|
|
570
|
+
const textContent = (a.textContent || a.innerText || '').trim();
|
|
571
|
+
const title = textContent
|
|
572
|
+
.replace(/\\s+/g, ' ')
|
|
573
|
+
.substring(0, 200);
|
|
574
|
+
return { id, title, href };
|
|
575
|
+
})
|
|
576
|
+
.filter(Boolean);
|
|
577
|
+
})()
|
|
578
|
+
`;
|
|
579
|
+
}
|
|
580
|
+
export async function getDoubaoConversationList(page) {
|
|
581
|
+
await ensureDoubaoChatPage(page);
|
|
582
|
+
const raw = await page.evaluate(getConversationListScript());
|
|
583
|
+
if (!Array.isArray(raw))
|
|
584
|
+
return [];
|
|
585
|
+
return raw.map((item) => ({
|
|
586
|
+
Id: item.id,
|
|
587
|
+
Title: item.title,
|
|
588
|
+
Url: `${DOUBAO_CHAT_URL}/${item.id}`,
|
|
589
|
+
}));
|
|
590
|
+
}
|
|
591
|
+
export function parseDoubaoConversationId(input) {
|
|
592
|
+
const match = input.match(/(\d{10,})/);
|
|
593
|
+
return match ? match[1] : input;
|
|
594
|
+
}
|
|
595
|
+
function getConversationDetailScript() {
|
|
596
|
+
return `
|
|
597
|
+
(() => {
|
|
598
|
+
const clean = (v) => (v || '').replace(/\\u00a0/g, ' ').replace(/\\n{3,}/g, '\\n\\n').trim();
|
|
599
|
+
|
|
600
|
+
const messageList = document.querySelector('[data-testid="message-list"]');
|
|
601
|
+
if (!messageList) return { messages: [], meeting: null };
|
|
602
|
+
|
|
603
|
+
const meetingCard = messageList.querySelector('[data-testid="meeting-minutes-card"]');
|
|
604
|
+
let meeting = null;
|
|
605
|
+
if (meetingCard) {
|
|
606
|
+
const raw = clean(meetingCard.textContent || '');
|
|
607
|
+
const match = raw.match(/^(.+?)(?:会议时间:|\\s*$)(.*)/);
|
|
608
|
+
meeting = {
|
|
609
|
+
title: match ? match[1].trim() : raw,
|
|
610
|
+
time: match && match[2] ? match[2].trim() : '',
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
const unions = Array.from(messageList.querySelectorAll('[data-testid="union_message"]'));
|
|
615
|
+
const messages = unions.map(u => {
|
|
616
|
+
const isSend = !!u.querySelector('[data-testid="send_message"]');
|
|
617
|
+
const isReceive = !!u.querySelector('[data-testid="receive_message"]');
|
|
618
|
+
const textEl = u.querySelector('[data-testid="message_text_content"]');
|
|
619
|
+
const text = textEl ? clean(textEl.innerText || textEl.textContent || '') : '';
|
|
620
|
+
return {
|
|
621
|
+
role: isSend ? 'User' : isReceive ? 'Assistant' : 'System',
|
|
622
|
+
text,
|
|
623
|
+
hasMeetingCard: !!u.querySelector('[data-testid="meeting-minutes-card"]'),
|
|
624
|
+
};
|
|
625
|
+
}).filter(m => m.text);
|
|
626
|
+
|
|
627
|
+
return { messages, meeting };
|
|
628
|
+
})()
|
|
629
|
+
`;
|
|
630
|
+
}
|
|
631
|
+
export async function navigateToConversation(page, conversationId) {
|
|
632
|
+
const url = `${DOUBAO_CHAT_URL}/${conversationId}`;
|
|
633
|
+
const currentUrl = await page.evaluate('window.location.href').catch(() => '');
|
|
634
|
+
if (typeof currentUrl === 'string' && currentUrl.includes(`/chat/${conversationId}`)) {
|
|
635
|
+
await page.wait(1);
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
await page.goto(url, { waitUntil: 'load', settleMs: 3000 });
|
|
639
|
+
await page.wait(2);
|
|
640
|
+
}
|
|
641
|
+
export async function getConversationDetail(page, conversationId) {
|
|
642
|
+
await navigateToConversation(page, conversationId);
|
|
643
|
+
const raw = await page.evaluate(getConversationDetailScript());
|
|
644
|
+
const messages = (raw.messages || []).map((m) => ({
|
|
645
|
+
Role: m.role,
|
|
646
|
+
Text: m.text,
|
|
647
|
+
HasMeetingCard: m.hasMeetingCard,
|
|
648
|
+
}));
|
|
649
|
+
return { messages, meeting: raw.meeting };
|
|
650
|
+
}
|
|
651
|
+
// ---------------------------------------------------------------------------
|
|
652
|
+
// Meeting minutes panel helpers
|
|
653
|
+
// ---------------------------------------------------------------------------
|
|
654
|
+
function clickMeetingCardScript() {
|
|
655
|
+
return `
|
|
656
|
+
(() => {
|
|
657
|
+
const card = document.querySelector('[data-testid="meeting-minutes-card"]');
|
|
658
|
+
if (!card) return false;
|
|
659
|
+
card.click();
|
|
660
|
+
return true;
|
|
661
|
+
})()
|
|
662
|
+
`;
|
|
663
|
+
}
|
|
664
|
+
function readMeetingSummaryScript() {
|
|
665
|
+
return `
|
|
666
|
+
(() => {
|
|
667
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
668
|
+
if (!panel) return { error: 'no panel' };
|
|
669
|
+
|
|
670
|
+
const summary = panel.querySelector('[data-testid="meeting-summary-todos"]');
|
|
671
|
+
const summaryText = summary
|
|
672
|
+
? (summary.innerText || summary.textContent || '').trim()
|
|
673
|
+
: '';
|
|
674
|
+
|
|
675
|
+
return { summary: summaryText };
|
|
676
|
+
})()
|
|
677
|
+
`;
|
|
678
|
+
}
|
|
679
|
+
function clickTextNotesTabScript() {
|
|
680
|
+
return `
|
|
681
|
+
(() => {
|
|
682
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
683
|
+
if (!panel) return false;
|
|
684
|
+
const tabs = panel.querySelectorAll('[role="tab"], .semi-tabs-tab');
|
|
685
|
+
for (const tab of tabs) {
|
|
686
|
+
if ((tab.textContent || '').trim().includes('文字')) {
|
|
687
|
+
tab.click();
|
|
688
|
+
return true;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return false;
|
|
692
|
+
})()
|
|
693
|
+
`;
|
|
694
|
+
}
|
|
695
|
+
function readTextNotesScript() {
|
|
696
|
+
return `
|
|
697
|
+
(() => {
|
|
698
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
699
|
+
if (!panel) return '';
|
|
700
|
+
const textNotes = panel.querySelector('[data-testid="meeting-text-notes"]');
|
|
701
|
+
if (!textNotes) return '';
|
|
702
|
+
return (textNotes.innerText || textNotes.textContent || '').trim();
|
|
703
|
+
})()
|
|
704
|
+
`;
|
|
705
|
+
}
|
|
706
|
+
function normalizeTranscriptLines(text) {
|
|
707
|
+
return text
|
|
708
|
+
.split('\n')
|
|
709
|
+
.map(line => line.trim())
|
|
710
|
+
.filter(Boolean);
|
|
711
|
+
}
|
|
712
|
+
function containsLineSequence(haystack, needle) {
|
|
713
|
+
if (needle.length === 0)
|
|
714
|
+
return true;
|
|
715
|
+
if (needle.length > haystack.length)
|
|
716
|
+
return false;
|
|
717
|
+
for (let start = 0; start <= haystack.length - needle.length; start += 1) {
|
|
718
|
+
let matched = true;
|
|
719
|
+
for (let offset = 0; offset < needle.length; offset += 1) {
|
|
720
|
+
if (haystack[start + offset] !== needle[offset]) {
|
|
721
|
+
matched = false;
|
|
722
|
+
break;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
if (matched)
|
|
726
|
+
return true;
|
|
727
|
+
}
|
|
728
|
+
return false;
|
|
729
|
+
}
|
|
730
|
+
export function mergeTranscriptSnapshots(existing, incoming) {
|
|
731
|
+
const currentLines = normalizeTranscriptLines(existing);
|
|
732
|
+
const nextLines = normalizeTranscriptLines(incoming);
|
|
733
|
+
if (nextLines.length === 0)
|
|
734
|
+
return currentLines.join('\n');
|
|
735
|
+
if (currentLines.length === 0)
|
|
736
|
+
return nextLines.join('\n');
|
|
737
|
+
if (containsLineSequence(currentLines, nextLines))
|
|
738
|
+
return currentLines.join('\n');
|
|
739
|
+
const maxOverlap = Math.min(currentLines.length, nextLines.length);
|
|
740
|
+
for (let overlap = maxOverlap; overlap > 0; overlap -= 1) {
|
|
741
|
+
let matched = true;
|
|
742
|
+
for (let index = 0; index < overlap; index += 1) {
|
|
743
|
+
if (currentLines[currentLines.length - overlap + index] !== nextLines[index]) {
|
|
744
|
+
matched = false;
|
|
745
|
+
break;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
if (matched) {
|
|
749
|
+
return [...currentLines, ...nextLines.slice(overlap)].join('\n');
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
return [...currentLines, ...nextLines].join('\n');
|
|
753
|
+
}
|
|
754
|
+
function clickChapterTabScript() {
|
|
755
|
+
return `
|
|
756
|
+
(() => {
|
|
757
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
758
|
+
if (!panel) return false;
|
|
759
|
+
const tabs = panel.querySelectorAll('[role="tab"], .semi-tabs-tab');
|
|
760
|
+
for (const tab of tabs) {
|
|
761
|
+
if ((tab.textContent || '').trim().includes('章节')) {
|
|
762
|
+
tab.click();
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
return false;
|
|
767
|
+
})()
|
|
768
|
+
`;
|
|
769
|
+
}
|
|
770
|
+
function readChapterScript() {
|
|
771
|
+
return `
|
|
772
|
+
(() => {
|
|
773
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
774
|
+
if (!panel) return '';
|
|
775
|
+
const chapter = panel.querySelector('[data-testid="meeting-ai-chapter"]');
|
|
776
|
+
if (!chapter) return '';
|
|
777
|
+
return (chapter.innerText || chapter.textContent || '').trim();
|
|
778
|
+
})()
|
|
779
|
+
`;
|
|
780
|
+
}
|
|
781
|
+
function triggerTranscriptDownloadScript() {
|
|
782
|
+
return `
|
|
783
|
+
(() => {
|
|
784
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
785
|
+
if (!panel) return { error: 'no panel' };
|
|
786
|
+
|
|
787
|
+
const downloadIcon = panel.querySelector('[class*="DownloadMeetingAudio"] span[role="img"]');
|
|
788
|
+
if (!downloadIcon) return { error: 'no download icon' };
|
|
789
|
+
|
|
790
|
+
downloadIcon.click();
|
|
791
|
+
return { clicked: 'icon' };
|
|
792
|
+
})()
|
|
793
|
+
`;
|
|
794
|
+
}
|
|
795
|
+
function clickTranscriptDownloadBtnScript() {
|
|
796
|
+
return `
|
|
797
|
+
(() => {
|
|
798
|
+
const btn = document.querySelector('[data-testid="minutes-download-text-btn"]');
|
|
799
|
+
if (!btn) return { error: 'no download text btn' };
|
|
800
|
+
btn.click();
|
|
801
|
+
return { clicked: 'transcript' };
|
|
802
|
+
})()
|
|
803
|
+
`;
|
|
804
|
+
}
|
|
805
|
+
export async function openMeetingPanel(page, conversationId) {
|
|
806
|
+
await navigateToConversation(page, conversationId);
|
|
807
|
+
const clicked = await page.evaluate(clickMeetingCardScript());
|
|
808
|
+
if (!clicked)
|
|
809
|
+
return false;
|
|
810
|
+
await page.wait(2);
|
|
811
|
+
return true;
|
|
812
|
+
}
|
|
813
|
+
export async function getMeetingSummary(page) {
|
|
814
|
+
const result = await page.evaluate(readMeetingSummaryScript());
|
|
815
|
+
return result.summary || '';
|
|
816
|
+
}
|
|
817
|
+
export async function getMeetingChapters(page) {
|
|
818
|
+
await page.evaluate(clickChapterTabScript());
|
|
819
|
+
await page.wait(1.5);
|
|
820
|
+
return await page.evaluate(readChapterScript());
|
|
821
|
+
}
|
|
822
|
+
function scrollTextNotesPanelScript() {
|
|
823
|
+
return `
|
|
824
|
+
(() => {
|
|
825
|
+
const panel = document.querySelector('[data-testid="canvas_panel_container"]');
|
|
826
|
+
if (!panel) return 0;
|
|
827
|
+
const textNotes = panel.querySelector('[data-testid="meeting-text-notes"]');
|
|
828
|
+
if (!textNotes) return 0;
|
|
829
|
+
|
|
830
|
+
const scrollable = textNotes.closest('[class*="overflow"]')
|
|
831
|
+
|| textNotes.parentElement
|
|
832
|
+
|| textNotes;
|
|
833
|
+
const maxScroll = scrollable.scrollHeight - scrollable.clientHeight;
|
|
834
|
+
if (maxScroll > 0) {
|
|
835
|
+
scrollable.scrollTop = scrollable.scrollHeight;
|
|
836
|
+
}
|
|
837
|
+
return maxScroll;
|
|
838
|
+
})()
|
|
839
|
+
`;
|
|
840
|
+
}
|
|
841
|
+
export async function getMeetingTranscript(page) {
|
|
842
|
+
await page.evaluate(clickTextNotesTabScript());
|
|
843
|
+
await page.wait(2);
|
|
844
|
+
let merged = '';
|
|
845
|
+
let stableRounds = 0;
|
|
846
|
+
for (let i = 0; i < 10; i++) {
|
|
847
|
+
await page.evaluate(scrollTextNotesPanelScript());
|
|
848
|
+
await page.wait(1);
|
|
849
|
+
const snapshot = await page.evaluate(readTextNotesScript());
|
|
850
|
+
const nextMerged = mergeTranscriptSnapshots(merged, snapshot);
|
|
851
|
+
if (nextMerged === merged && snapshot.length > 0) {
|
|
852
|
+
stableRounds += 1;
|
|
853
|
+
if (stableRounds >= 2)
|
|
854
|
+
break;
|
|
855
|
+
}
|
|
856
|
+
else {
|
|
857
|
+
stableRounds = 0;
|
|
858
|
+
merged = nextMerged;
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
return merged;
|
|
862
|
+
}
|
|
863
|
+
export async function triggerTranscriptDownload(page) {
|
|
864
|
+
const iconResult = await page.evaluate(triggerTranscriptDownloadScript());
|
|
865
|
+
if (iconResult.error)
|
|
866
|
+
return false;
|
|
867
|
+
await page.wait(1);
|
|
868
|
+
const btnResult = await page.evaluate(clickTranscriptDownloadBtnScript());
|
|
869
|
+
return !btnResult.error;
|
|
870
|
+
}
|
|
554
871
|
export async function startNewDoubaoChat(page) {
|
|
555
872
|
await ensureDoubaoChatPage(page);
|
|
556
873
|
const clickedLabel = await page.evaluate(clickNewChatScript());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { mergeTranscriptSnapshots, parseDoubaoConversationId } from './utils.js';
|
|
3
|
+
describe('parseDoubaoConversationId', () => {
|
|
4
|
+
it('extracts the numeric id from a full conversation URL', () => {
|
|
5
|
+
expect(parseDoubaoConversationId('https://www.doubao.com/chat/1234567890123')).toBe('1234567890123');
|
|
6
|
+
});
|
|
7
|
+
it('keeps a raw id unchanged', () => {
|
|
8
|
+
expect(parseDoubaoConversationId('1234567890123')).toBe('1234567890123');
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
describe('mergeTranscriptSnapshots', () => {
|
|
12
|
+
it('extends the transcript when the next snapshot overlaps with the tail', () => {
|
|
13
|
+
const merged = mergeTranscriptSnapshots('Alice 00:00\nHello team\nBob 00:05\nHi', 'Bob 00:05\nHi\nAlice 00:10\nNext topic');
|
|
14
|
+
expect(merged).toBe('Alice 00:00\nHello team\nBob 00:05\nHi\nAlice 00:10\nNext topic');
|
|
15
|
+
});
|
|
16
|
+
it('does not duplicate a snapshot that is already contained in the transcript', () => {
|
|
17
|
+
const merged = mergeTranscriptSnapshots('Alice 00:00\nHello team\nBob 00:05\nHi', 'Bob 00:05\nHi');
|
|
18
|
+
expect(merged).toBe('Alice 00:00\nHello team\nBob 00:05\nHi');
|
|
19
|
+
});
|
|
20
|
+
it('keeps both windows when a virtualized panel returns adjacent chunks without full history', () => {
|
|
21
|
+
const merged = mergeTranscriptSnapshots('Alice 00:00\nHello team\nBob 00:05\nHi', 'Alice 00:10\nNext topic\nBob 00:15\nAction items');
|
|
22
|
+
expect(merged).toBe('Alice 00:00\nHello team\nBob 00:05\nHi\nAlice 00:10\nNext topic\nBob 00:15\nAction items');
|
|
23
|
+
});
|
|
24
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { IPage } from '../../../types.js';
|
|
2
|
+
export interface DouyinComment {
|
|
3
|
+
text?: string;
|
|
4
|
+
digg_count?: number;
|
|
5
|
+
user?: {
|
|
6
|
+
nickname?: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface DouyinVideo {
|
|
10
|
+
aweme_id: string;
|
|
11
|
+
desc?: string;
|
|
12
|
+
video?: {
|
|
13
|
+
duration?: number;
|
|
14
|
+
play_addr?: {
|
|
15
|
+
url_list?: string[];
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
statistics?: {
|
|
19
|
+
digg_count?: number;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface DouyinVideoListResponse {
|
|
23
|
+
aweme_list?: DouyinVideo[];
|
|
24
|
+
}
|
|
25
|
+
export interface DouyinCommentListResponse {
|
|
26
|
+
comments?: DouyinComment[];
|
|
27
|
+
}
|
|
28
|
+
export declare function fetchDouyinUserVideos(page: IPage, secUid: string, count: number): Promise<DouyinVideo[]>;
|
|
29
|
+
export declare function fetchDouyinComments(page: IPage, awemeId: string, count: number): Promise<Array<{
|
|
30
|
+
text: string;
|
|
31
|
+
digg_count: number;
|
|
32
|
+
nickname: string;
|
|
33
|
+
}>>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { browserFetch } from './browser-fetch.js';
|
|
2
|
+
export async function fetchDouyinUserVideos(page, secUid, count) {
|
|
3
|
+
const params = new URLSearchParams({
|
|
4
|
+
sec_user_id: secUid,
|
|
5
|
+
max_cursor: '0',
|
|
6
|
+
count: String(count),
|
|
7
|
+
aid: '6383',
|
|
8
|
+
});
|
|
9
|
+
const data = await browserFetch(page, 'GET', `https://www.douyin.com/aweme/v1/web/aweme/post/?${params.toString()}`, {
|
|
10
|
+
headers: { referer: 'https://www.douyin.com/' },
|
|
11
|
+
});
|
|
12
|
+
return data.aweme_list || [];
|
|
13
|
+
}
|
|
14
|
+
export async function fetchDouyinComments(page, awemeId, count) {
|
|
15
|
+
const params = new URLSearchParams({
|
|
16
|
+
aweme_id: awemeId,
|
|
17
|
+
count: String(count),
|
|
18
|
+
cursor: '0',
|
|
19
|
+
aid: '6383',
|
|
20
|
+
});
|
|
21
|
+
const data = await browserFetch(page, 'GET', `https://www.douyin.com/aweme/v1/web/comment/list/?${params.toString()}`, {
|
|
22
|
+
headers: { referer: 'https://www.douyin.com/' },
|
|
23
|
+
});
|
|
24
|
+
return (data.comments || []).slice(0, count).map((comment) => ({
|
|
25
|
+
text: comment.text || '',
|
|
26
|
+
digg_count: comment.digg_count ?? 0,
|
|
27
|
+
nickname: comment.user?.nickname || '',
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
@@ -8,8 +8,14 @@ const STS2_URL = 'https://creator.douyin.com/aweme/mid/video/sts2/?scene=web&aid
|
|
|
8
8
|
export async function getSts2Credentials(page) {
|
|
9
9
|
const js = `fetch(${JSON.stringify(STS2_URL)}, { credentials: 'include' }).then(r => r.json())`;
|
|
10
10
|
const res = await page.evaluate(js);
|
|
11
|
-
|
|
11
|
+
const credentials = (typeof res === 'object' &&
|
|
12
|
+
res !== null &&
|
|
13
|
+
'data' in res &&
|
|
14
|
+
res.data)
|
|
15
|
+
? res.data
|
|
16
|
+
: res;
|
|
17
|
+
if (!credentials?.access_key_id) {
|
|
12
18
|
throw new AuthRequiredError('creator.douyin.com', 'STS2 credentials missing');
|
|
13
19
|
}
|
|
14
|
-
return
|
|
20
|
+
return credentials;
|
|
15
21
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { AuthRequiredError } from '../../../errors.js';
|
|
3
|
+
import { getSts2Credentials } from './sts2.js';
|
|
4
|
+
describe('douyin sts2 credentials', () => {
|
|
5
|
+
it('accepts top-level credential fields returned by creator center', async () => {
|
|
6
|
+
const page = {
|
|
7
|
+
evaluate: async () => ({
|
|
8
|
+
access_key_id: 'ak',
|
|
9
|
+
secret_access_key: 'sk',
|
|
10
|
+
session_token: 'token',
|
|
11
|
+
expired_time: 1_234_567_890,
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
await expect(getSts2Credentials(page)).resolves.toEqual({
|
|
15
|
+
access_key_id: 'ak',
|
|
16
|
+
secret_access_key: 'sk',
|
|
17
|
+
session_token: 'token',
|
|
18
|
+
expired_time: 1_234_567_890,
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
it('still rejects responses without credential fields', async () => {
|
|
22
|
+
const page = {
|
|
23
|
+
evaluate: async () => ({ status_code: 8 }),
|
|
24
|
+
};
|
|
25
|
+
await expect(getSts2Credentials(page)).rejects.toBeInstanceOf(AuthRequiredError);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -13,8 +13,10 @@ cli({
|
|
|
13
13
|
const res = await browserFetch(page, 'GET', url);
|
|
14
14
|
return (res.activity_list ?? []).map(a => ({
|
|
15
15
|
activity_id: a.activity_id,
|
|
16
|
-
title: a.title,
|
|
17
|
-
end_time:
|
|
16
|
+
title: a.title ?? a.activity_name ?? '',
|
|
17
|
+
end_time: typeof a.end_time === 'number'
|
|
18
|
+
? new Date(a.end_time * 1000).toLocaleString('zh-CN', { timeZone: 'Asia/Tokyo' })
|
|
19
|
+
: (a.show_end_time ?? ''),
|
|
18
20
|
}));
|
|
19
21
|
},
|
|
20
22
|
});
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
const { browserFetchMock } = vi.hoisted(() => ({
|
|
3
|
+
browserFetchMock: vi.fn(),
|
|
4
|
+
}));
|
|
5
|
+
vi.mock('./_shared/browser-fetch.js', () => ({
|
|
6
|
+
browserFetch: browserFetchMock,
|
|
7
|
+
}));
|
|
2
8
|
import { getRegistry } from '../../registry.js';
|
|
3
9
|
import './activities.js';
|
|
4
10
|
describe('douyin activities registration', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
browserFetchMock.mockReset();
|
|
13
|
+
});
|
|
5
14
|
it('registers the activities command', () => {
|
|
6
15
|
const registry = getRegistry();
|
|
7
16
|
const cmd = [...registry.values()].find(c => c.site === 'douyin' && c.name === 'activities');
|
|
@@ -19,4 +28,28 @@ describe('douyin activities registration', () => {
|
|
|
19
28
|
const cmd = [...registry.values()].find(c => c.site === 'douyin' && c.name === 'activities');
|
|
20
29
|
expect(cmd?.strategy).toBe('cookie');
|
|
21
30
|
});
|
|
31
|
+
it('maps the current activity payload shape returned by creator center', async () => {
|
|
32
|
+
const registry = getRegistry();
|
|
33
|
+
const cmd = [...registry.values()].find(c => c.site === 'douyin' && c.name === 'activities');
|
|
34
|
+
expect(cmd?.func).toBeDefined();
|
|
35
|
+
if (!cmd?.func)
|
|
36
|
+
throw new Error('douyin activities command not registered');
|
|
37
|
+
browserFetchMock.mockResolvedValueOnce({
|
|
38
|
+
activity_list: [
|
|
39
|
+
{
|
|
40
|
+
activity_id: '200',
|
|
41
|
+
activity_name: '超会玩派对',
|
|
42
|
+
show_end_time: '2026.05.31',
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
});
|
|
46
|
+
const rows = await cmd.func({}, {});
|
|
47
|
+
expect(rows).toEqual([
|
|
48
|
+
{
|
|
49
|
+
activity_id: '200',
|
|
50
|
+
title: '超会玩派对',
|
|
51
|
+
end_time: '2026.05.31',
|
|
52
|
+
},
|
|
53
|
+
]);
|
|
54
|
+
});
|
|
22
55
|
});
|
|
@@ -11,7 +11,7 @@ cli({
|
|
|
11
11
|
],
|
|
12
12
|
columns: ['mix_id', 'name', 'item_count'],
|
|
13
13
|
func: async (page, kwargs) => {
|
|
14
|
-
const url = `https://creator.douyin.com/web/api/mix/list/?
|
|
14
|
+
const url = `https://creator.douyin.com/web/api/mix/list/?status=0,1,2,3,6&count=${kwargs.limit}&cursor=0&should_query_new_mix=1&device_platform=web&aid=1128`;
|
|
15
15
|
const res = await browserFetch(page, 'GET', url);
|
|
16
16
|
return (res.mix_list ?? []).map(m => ({
|
|
17
17
|
mix_id: m.mix_id,
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
const { browserFetchMock } = vi.hoisted(() => ({
|
|
3
|
+
browserFetchMock: vi.fn(),
|
|
4
|
+
}));
|
|
5
|
+
vi.mock('./_shared/browser-fetch.js', () => ({
|
|
6
|
+
browserFetch: browserFetchMock,
|
|
7
|
+
}));
|
|
2
8
|
import { getRegistry } from '../../registry.js';
|
|
3
9
|
import './collections.js';
|
|
4
|
-
describe('douyin collections
|
|
10
|
+
describe('douyin collections', () => {
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
browserFetchMock.mockReset();
|
|
13
|
+
});
|
|
5
14
|
it('registers the collections command', () => {
|
|
6
15
|
const registry = getRegistry();
|
|
7
16
|
const cmd = [...registry.values()].find(c => c.site === 'douyin' && c.name === 'collections');
|
|
@@ -20,4 +29,17 @@ describe('douyin collections registration', () => {
|
|
|
20
29
|
const cmd = [...registry.values()].find(c => c.site === 'douyin' && c.name === 'collections');
|
|
21
30
|
expect(cmd?.strategy).toBe('cookie');
|
|
22
31
|
});
|
|
32
|
+
it('uses the current mix list request shape', async () => {
|
|
33
|
+
const registry = getRegistry();
|
|
34
|
+
const command = [...registry.values()].find((cmd) => cmd.site === 'douyin' && cmd.name === 'collections');
|
|
35
|
+
expect(command?.func).toBeDefined();
|
|
36
|
+
if (!command?.func)
|
|
37
|
+
throw new Error('douyin collections command not registered');
|
|
38
|
+
browserFetchMock.mockResolvedValueOnce({
|
|
39
|
+
mix_list: [],
|
|
40
|
+
});
|
|
41
|
+
const rows = await command.func({}, { limit: 12 });
|
|
42
|
+
expect(browserFetchMock).toHaveBeenCalledWith({}, 'GET', 'https://creator.douyin.com/web/api/mix/list/?status=0,1,2,3,6&count=12&cursor=0&should_query_new_mix=1&device_platform=web&aid=1128');
|
|
43
|
+
expect(rows).toEqual([]);
|
|
44
|
+
});
|
|
23
45
|
});
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Douyin draft —
|
|
2
|
+
* Douyin draft — upload through the official creator page and save as draft.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 3. TOS multipart upload
|
|
8
|
-
* 4. Cover upload (optional, via ImageX)
|
|
9
|
-
* 5. Enable video
|
|
10
|
-
* 6. Poll transcode
|
|
11
|
-
* 7. (skipped — no safety check for drafts)
|
|
12
|
-
* 8. create_v2 with is_draft: 1
|
|
4
|
+
* The previous API pipeline relied on an old pre-upload endpoint that no longer
|
|
5
|
+
* matches creator center's live upload flow. This command now drives the
|
|
6
|
+
* official upload page directly so it stays aligned with the site.
|
|
13
7
|
*/
|
|
14
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Read the local quick-check panel text that reflects cover validation state.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildCoverCheckPanelTextJs(): string;
|