@jackwener/opencli 1.3.0 → 1.3.2

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.
Files changed (218) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/README.md +44 -5
  3. package/README.zh-CN.md +44 -5
  4. package/SKILL.md +317 -5
  5. package/TESTING.md +4 -4
  6. package/dist/browser/errors.d.ts +2 -1
  7. package/dist/browser/errors.js +9 -10
  8. package/dist/build-manifest.js +1 -3
  9. package/dist/cli-manifest.json +2573 -989
  10. package/dist/cli.js +42 -2
  11. package/dist/clis/bilibili/download.js +20 -65
  12. package/dist/clis/bilibili/utils.js +2 -1
  13. package/dist/clis/chaoxing/assignments.js +2 -1
  14. package/dist/clis/doubao/ask.d.ts +1 -0
  15. package/dist/clis/doubao/ask.js +35 -0
  16. package/dist/clis/doubao/common.d.ts +23 -0
  17. package/dist/clis/doubao/common.js +564 -0
  18. package/dist/clis/doubao/new.d.ts +1 -0
  19. package/dist/clis/doubao/new.js +20 -0
  20. package/dist/clis/doubao/read.d.ts +1 -0
  21. package/dist/clis/doubao/read.js +19 -0
  22. package/dist/clis/doubao/send.d.ts +1 -0
  23. package/dist/clis/doubao/send.js +22 -0
  24. package/dist/clis/doubao/status.d.ts +1 -0
  25. package/dist/clis/doubao/status.js +24 -0
  26. package/dist/clis/doubao-app/ask.d.ts +1 -0
  27. package/dist/clis/doubao-app/ask.js +53 -0
  28. package/dist/clis/doubao-app/common.d.ts +37 -0
  29. package/dist/clis/doubao-app/common.js +110 -0
  30. package/dist/clis/doubao-app/dump.d.ts +1 -0
  31. package/dist/clis/doubao-app/dump.js +24 -0
  32. package/dist/clis/doubao-app/new.d.ts +1 -0
  33. package/dist/clis/doubao-app/new.js +20 -0
  34. package/dist/clis/doubao-app/read.d.ts +1 -0
  35. package/dist/clis/doubao-app/read.js +18 -0
  36. package/dist/clis/doubao-app/screenshot.d.ts +1 -0
  37. package/dist/clis/doubao-app/screenshot.js +18 -0
  38. package/dist/clis/doubao-app/send.d.ts +1 -0
  39. package/dist/clis/doubao-app/send.js +27 -0
  40. package/dist/clis/doubao-app/status.d.ts +1 -0
  41. package/dist/clis/doubao-app/status.js +16 -0
  42. package/dist/clis/hackernews/ask.yaml +38 -0
  43. package/dist/clis/hackernews/best.yaml +38 -0
  44. package/dist/clis/hackernews/jobs.yaml +36 -0
  45. package/dist/clis/hackernews/new.yaml +38 -0
  46. package/dist/clis/hackernews/search.yaml +44 -0
  47. package/dist/clis/hackernews/show.yaml +38 -0
  48. package/dist/clis/hackernews/top.yaml +3 -1
  49. package/dist/clis/hackernews/user.yaml +25 -0
  50. package/dist/clis/twitter/download.js +13 -97
  51. package/dist/clis/twitter/thread.js +2 -1
  52. package/dist/clis/v2ex/member.yaml +29 -0
  53. package/dist/clis/v2ex/node.yaml +34 -0
  54. package/dist/clis/v2ex/nodes.yaml +31 -0
  55. package/dist/clis/v2ex/replies.yaml +32 -0
  56. package/dist/clis/v2ex/user.yaml +34 -0
  57. package/dist/clis/weibo/search.d.ts +1 -0
  58. package/dist/clis/weibo/search.js +73 -0
  59. package/dist/clis/weixin/download.d.ts +12 -0
  60. package/dist/clis/weixin/download.js +183 -0
  61. package/dist/clis/xiaohongshu/download.js +12 -60
  62. package/dist/clis/xiaohongshu/publish.d.ts +18 -0
  63. package/dist/clis/xiaohongshu/publish.js +352 -0
  64. package/dist/clis/xiaohongshu/search.js +47 -15
  65. package/dist/clis/xiaohongshu/search.test.d.ts +1 -0
  66. package/dist/clis/xiaohongshu/search.test.js +114 -0
  67. package/dist/clis/yollomi/background.d.ts +4 -0
  68. package/dist/clis/yollomi/background.js +45 -0
  69. package/dist/clis/yollomi/edit.d.ts +5 -0
  70. package/dist/clis/yollomi/edit.js +56 -0
  71. package/dist/clis/yollomi/face-swap.d.ts +5 -0
  72. package/dist/clis/yollomi/face-swap.js +43 -0
  73. package/dist/clis/yollomi/generate.d.ts +9 -0
  74. package/dist/clis/yollomi/generate.js +100 -0
  75. package/dist/clis/yollomi/models.d.ts +1 -0
  76. package/dist/clis/yollomi/models.js +33 -0
  77. package/dist/clis/yollomi/object-remover.d.ts +4 -0
  78. package/dist/clis/yollomi/object-remover.js +42 -0
  79. package/dist/clis/yollomi/remove-bg.d.ts +4 -0
  80. package/dist/clis/yollomi/remove-bg.js +38 -0
  81. package/dist/clis/yollomi/restore.d.ts +4 -0
  82. package/dist/clis/yollomi/restore.js +38 -0
  83. package/dist/clis/yollomi/try-on.d.ts +4 -0
  84. package/dist/clis/yollomi/try-on.js +46 -0
  85. package/dist/clis/yollomi/upload.d.ts +7 -0
  86. package/dist/clis/yollomi/upload.js +71 -0
  87. package/dist/clis/yollomi/upscale.d.ts +4 -0
  88. package/dist/clis/yollomi/upscale.js +53 -0
  89. package/dist/clis/yollomi/utils.d.ts +45 -0
  90. package/dist/clis/yollomi/utils.js +180 -0
  91. package/dist/clis/yollomi/video.d.ts +5 -0
  92. package/dist/clis/yollomi/video.js +56 -0
  93. package/dist/clis/zhihu/download.d.ts +1 -5
  94. package/dist/clis/zhihu/download.js +20 -126
  95. package/dist/clis/zhihu/download.test.js +7 -5
  96. package/dist/clis/zhihu/question.js +2 -1
  97. package/dist/commanderAdapter.js +4 -6
  98. package/dist/daemon.js +5 -2
  99. package/dist/discovery.js +10 -10
  100. package/dist/download/article-download.d.ts +59 -0
  101. package/dist/download/article-download.js +178 -0
  102. package/dist/download/media-download.d.ts +49 -0
  103. package/dist/download/media-download.js +112 -0
  104. package/dist/errors.d.ts +23 -2
  105. package/dist/errors.js +58 -2
  106. package/dist/errors.test.d.ts +1 -0
  107. package/dist/errors.test.js +59 -0
  108. package/dist/execution.js +9 -10
  109. package/dist/explore.js +4 -2
  110. package/dist/external.d.ts +15 -0
  111. package/dist/external.js +48 -2
  112. package/dist/external.test.d.ts +1 -0
  113. package/dist/external.test.js +64 -0
  114. package/dist/main.js +10 -0
  115. package/dist/plugin.d.ts +4 -0
  116. package/dist/plugin.js +45 -23
  117. package/dist/plugin.test.js +6 -1
  118. package/dist/record.d.ts +47 -0
  119. package/dist/record.js +545 -0
  120. package/dist/registry.d.ts +7 -2
  121. package/dist/registry.js +2 -6
  122. package/dist/runtime.d.ts +3 -1
  123. package/dist/runtime.js +10 -3
  124. package/dist/validate.js +1 -3
  125. package/docs/.vitepress/config.mts +1 -0
  126. package/docs/adapters/browser/doubao.md +35 -0
  127. package/docs/adapters/browser/hackernews.md +20 -4
  128. package/docs/adapters/browser/tiktok.md +1 -1
  129. package/docs/adapters/browser/v2ex.md +31 -10
  130. package/docs/adapters/browser/weibo.md +4 -0
  131. package/docs/adapters/browser/weixin.md +33 -0
  132. package/docs/adapters/browser/xiaohongshu.md +8 -6
  133. package/docs/adapters/browser/yollomi.md +69 -0
  134. package/docs/adapters/desktop/doubao-app.md +35 -0
  135. package/docs/adapters/index.md +16 -5
  136. package/docs/advanced/download.md +4 -0
  137. package/package.json +3 -1
  138. package/src/browser/errors.ts +17 -11
  139. package/src/build-manifest.ts +2 -3
  140. package/src/cli.ts +45 -2
  141. package/src/clis/bilibili/download.ts +25 -83
  142. package/src/clis/bilibili/utils.ts +2 -1
  143. package/src/clis/chaoxing/assignments.ts +2 -1
  144. package/src/clis/doubao/ask.ts +40 -0
  145. package/src/clis/doubao/common.ts +619 -0
  146. package/src/clis/doubao/new.ts +22 -0
  147. package/src/clis/doubao/read.ts +20 -0
  148. package/src/clis/doubao/send.ts +25 -0
  149. package/src/clis/doubao/status.ts +27 -0
  150. package/src/clis/doubao-app/ask.ts +60 -0
  151. package/src/clis/doubao-app/common.ts +116 -0
  152. package/src/clis/doubao-app/dump.ts +28 -0
  153. package/src/clis/doubao-app/new.ts +21 -0
  154. package/src/clis/doubao-app/read.ts +21 -0
  155. package/src/clis/doubao-app/screenshot.ts +19 -0
  156. package/src/clis/doubao-app/send.ts +30 -0
  157. package/src/clis/doubao-app/status.ts +17 -0
  158. package/src/clis/hackernews/ask.yaml +38 -0
  159. package/src/clis/hackernews/best.yaml +38 -0
  160. package/src/clis/hackernews/jobs.yaml +36 -0
  161. package/src/clis/hackernews/new.yaml +38 -0
  162. package/src/clis/hackernews/search.yaml +44 -0
  163. package/src/clis/hackernews/show.yaml +38 -0
  164. package/src/clis/hackernews/top.yaml +3 -1
  165. package/src/clis/hackernews/user.yaml +25 -0
  166. package/src/clis/twitter/download.ts +13 -111
  167. package/src/clis/twitter/thread.ts +2 -1
  168. package/src/clis/v2ex/member.yaml +29 -0
  169. package/src/clis/v2ex/node.yaml +34 -0
  170. package/src/clis/v2ex/nodes.yaml +31 -0
  171. package/src/clis/v2ex/replies.yaml +32 -0
  172. package/src/clis/v2ex/user.yaml +34 -0
  173. package/src/clis/weibo/search.ts +78 -0
  174. package/src/clis/weixin/download.ts +199 -0
  175. package/src/clis/xiaohongshu/download.ts +12 -71
  176. package/src/clis/xiaohongshu/publish.ts +392 -0
  177. package/src/clis/xiaohongshu/search.test.ts +134 -0
  178. package/src/clis/xiaohongshu/search.ts +49 -15
  179. package/src/clis/yollomi/background.ts +48 -0
  180. package/src/clis/yollomi/edit.ts +58 -0
  181. package/src/clis/yollomi/face-swap.ts +45 -0
  182. package/src/clis/yollomi/generate.ts +95 -0
  183. package/src/clis/yollomi/models.ts +38 -0
  184. package/src/clis/yollomi/object-remover.ts +44 -0
  185. package/src/clis/yollomi/remove-bg.ts +40 -0
  186. package/src/clis/yollomi/restore.ts +40 -0
  187. package/src/clis/yollomi/try-on.ts +48 -0
  188. package/src/clis/yollomi/upload.ts +78 -0
  189. package/src/clis/yollomi/upscale.ts +49 -0
  190. package/src/clis/yollomi/utils.ts +202 -0
  191. package/src/clis/yollomi/video.ts +61 -0
  192. package/src/clis/zhihu/download.test.ts +7 -5
  193. package/src/clis/zhihu/download.ts +23 -158
  194. package/src/clis/zhihu/question.ts +2 -1
  195. package/src/commanderAdapter.ts +4 -7
  196. package/src/daemon.ts +5 -2
  197. package/src/discovery.ts +26 -26
  198. package/src/download/article-download.ts +272 -0
  199. package/src/download/media-download.ts +178 -0
  200. package/src/errors.test.ts +79 -0
  201. package/src/errors.ts +92 -2
  202. package/src/execution.ts +14 -10
  203. package/src/explore.ts +4 -2
  204. package/src/external.test.ts +88 -0
  205. package/src/external.ts +56 -2
  206. package/src/generate.ts +2 -1
  207. package/src/main.ts +10 -0
  208. package/src/plugin.test.ts +7 -1
  209. package/src/plugin.ts +49 -25
  210. package/src/record.ts +617 -0
  211. package/src/registry.ts +9 -5
  212. package/src/runtime.ts +16 -4
  213. package/src/validate.ts +2 -3
  214. package/tests/e2e/browser-auth.test.ts +10 -1
  215. package/tests/e2e/browser-public.test.ts +13 -8
  216. package/tests/e2e/public-commands.test.ts +209 -21
  217. package/tests/smoke/api-health.test.ts +65 -6
  218. package/.github/workflows/release-please.yml +0 -25
@@ -8,18 +8,9 @@
8
8
  * - yt-dlp must be installed: pip install yt-dlp
9
9
  */
10
10
 
11
- import * as fs from 'node:fs';
12
- import * as path from 'node:path';
13
11
  import { cli, Strategy } from '../../registry.js';
14
- import {
15
- ytdlpDownload,
16
- checkYtdlp,
17
- sanitizeFilename,
18
- getTempDir,
19
- exportCookiesToNetscape,
20
- formatCookieHeader,
21
- } from '../../download/index.js';
22
- import { DownloadProgressTracker, formatBytes } from '../../download/progress.js';
12
+ import { checkYtdlp, sanitizeFilename } from '../../download/index.js';
13
+ import { downloadMedia } from '../../download/media-download.js';
23
14
 
24
15
  cli({
25
16
  site: 'bilibili',
@@ -63,21 +54,8 @@ cli({
63
54
 
64
55
  const title = sanitizeFilename(data?.title || 'video');
65
56
 
66
- // Extract cookies for authenticated downloads
67
- const cookies = await page.getCookies({ domain: 'bilibili.com' });
68
- const cookieString = formatCookieHeader(cookies);
69
-
70
- // Create output directory
71
- fs.mkdirSync(output, { recursive: true });
72
-
73
- // Export cookies to Netscape format for yt-dlp
74
- let cookiesFile: string | undefined;
75
- if (cookies.length > 0) {
76
- const tempDir = getTempDir();
77
- fs.mkdirSync(tempDir, { recursive: true });
78
- cookiesFile = path.join(tempDir, `bilibili_cookies_${Date.now()}.txt`);
79
- exportCookiesToNetscape(cookies, cookiesFile);
80
- }
57
+ // Extract cookies for yt-dlp
58
+ const browserCookies = await page.getCookies({ domain: 'bilibili.com' });
81
59
 
82
60
  // Build yt-dlp format string based on quality
83
61
  let format = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best';
@@ -89,62 +67,26 @@ cli({
89
67
  format = 'bestvideo[height<=480][ext=mp4]+bestaudio[ext=m4a]/best[height<=480]';
90
68
  }
91
69
 
92
- const destPath = path.join(output, `${bvid}_${title}.mp4`);
93
-
94
- const tracker = new DownloadProgressTracker(1, true);
95
- const progressBar = tracker.onFileStart(`${bvid}.mp4`, 0);
96
-
97
- try {
98
- const result = await ytdlpDownload(
99
- `https://www.bilibili.com/video/${bvid}`,
100
- destPath,
101
- {
102
- cookiesFile,
103
- format,
104
- extraArgs: [
105
- '--merge-output-format', 'mp4',
106
- '--embed-thumbnail',
107
- ],
108
- onProgress: (percent) => {
109
- if (progressBar) progressBar.update(percent, 100);
110
- },
111
- },
112
- );
113
-
114
- if (progressBar) {
115
- progressBar.complete(result.success, result.success ? formatBytes(result.size) : undefined);
116
- }
117
-
118
- tracker.onFileComplete(result.success);
119
- tracker.finish();
120
-
121
- // Cleanup cookies file
122
- if (cookiesFile && fs.existsSync(cookiesFile)) {
123
- fs.unlinkSync(cookiesFile);
124
- }
125
-
126
- return [{
127
- bvid,
128
- title: data?.title || 'video',
129
- status: result.success ? 'success' : 'failed',
130
- size: result.success ? formatBytes(result.size) : (result.error || 'unknown error'),
131
- }];
132
- } catch (err: any) {
133
- if (progressBar) progressBar.fail(err.message);
134
- tracker.onFileComplete(false);
135
- tracker.finish();
136
-
137
- // Cleanup cookies file
138
- if (cookiesFile && fs.existsSync(cookiesFile)) {
139
- fs.unlinkSync(cookiesFile);
140
- }
141
-
142
- return [{
143
- bvid,
144
- title: data?.title || 'video',
145
- status: 'failed',
146
- size: err.message,
147
- }];
148
- }
70
+ const videoUrl = `https://www.bilibili.com/video/${bvid}`;
71
+ const filename = `${bvid}_${title}.mp4`;
72
+
73
+ const results = await downloadMedia(
74
+ [{ type: 'video-ytdlp', url: videoUrl, filename }],
75
+ {
76
+ output,
77
+ browserCookies,
78
+ filenamePrefix: bvid,
79
+ ytdlpExtraArgs: ['-f', format, '--merge-output-format', 'mp4', '--embed-thumbnail'],
80
+ },
81
+ );
82
+
83
+ // Map results to bilibili-specific columns
84
+ const r = results[0] || { status: 'failed', size: '-' };
85
+ return [{
86
+ bvid,
87
+ title: data?.title || 'video',
88
+ status: r.status,
89
+ size: r.size,
90
+ }];
149
91
  },
150
92
  });
@@ -3,6 +3,7 @@
3
3
  */
4
4
 
5
5
  import type { IPage } from '../../types.js';
6
+ import { AuthRequiredError } from '../../errors.js';
6
7
 
7
8
  const MIXIN_KEY_ENC_TAB = [
8
9
  46,47,18,2,53,8,23,32,15,50,10,31,58,3,45,35,27,43,5,49,
@@ -98,7 +99,7 @@ export async function fetchJson(page: IPage, url: string): Promise<any> {
98
99
  export async function getSelfUid(page: IPage): Promise<string> {
99
100
  const nav = await getNavData(page);
100
101
  const mid = nav?.data?.mid;
101
- if (!mid) throw new Error('Not logged in to Bilibili');
102
+ if (!mid) throw new AuthRequiredError('bilibili.com');
102
103
  return String(mid);
103
104
  }
104
105
 
@@ -1,4 +1,5 @@
1
1
  import { cli, Strategy } from '../../registry.js';
2
+ import { AuthRequiredError } from '../../errors.js';
2
3
  import {
3
4
  getCourses, initSession, enterCourse, getTabIframeUrl,
4
5
  parseAssignmentsFromDom, sleep,
@@ -33,7 +34,7 @@ cli({
33
34
 
34
35
  // 2. Get courses
35
36
  const courses = await getCourses(page);
36
- if (!courses.length) throw new Error('未获取到课程列表,请确认已登录学习通');
37
+ if (!courses.length) throw new AuthRequiredError('mooc2-ans.chaoxing.com', '未获取到课程列表');
37
38
 
38
39
  const filtered = courseFilter
39
40
  ? courses.filter(c => c.title.includes(courseFilter))
@@ -0,0 +1,40 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ import type { IPage } from '../../types.js';
3
+ import { DOUBAO_DOMAIN, getDoubaoTranscriptLines, getDoubaoVisibleTurns, sendDoubaoMessage, waitForDoubaoResponse } from './common.js';
4
+
5
+ export const askCommand = cli({
6
+ site: 'doubao',
7
+ name: 'ask',
8
+ description: 'Send a prompt and wait for the Doubao response',
9
+ domain: DOUBAO_DOMAIN,
10
+ strategy: Strategy.COOKIE,
11
+ browser: true,
12
+ navigateBefore: false,
13
+ timeoutSeconds: 180,
14
+ args: [
15
+ { name: 'text', required: true, positional: true, help: 'Prompt to send' },
16
+ { name: 'timeout', required: false, help: 'Max seconds to wait (default: 60)', default: '60' },
17
+ ],
18
+ columns: ['Role', 'Text'],
19
+ func: async (page: IPage, kwargs: any) => {
20
+ const text = kwargs.text as string;
21
+ const timeout = parseInt(kwargs.timeout as string, 10) || 60;
22
+ const beforeTurns = await getDoubaoVisibleTurns(page);
23
+ const beforeLines = await getDoubaoTranscriptLines(page);
24
+
25
+ await sendDoubaoMessage(page, text);
26
+ const response = await waitForDoubaoResponse(page, beforeLines, beforeTurns, text, timeout);
27
+
28
+ if (!response) {
29
+ return [
30
+ { Role: 'User', Text: text },
31
+ { Role: 'System', Text: `No response within ${timeout}s. Doubao may still be generating.` },
32
+ ];
33
+ }
34
+
35
+ return [
36
+ { Role: 'User', Text: text },
37
+ { Role: 'Assistant', Text: response },
38
+ ];
39
+ },
40
+ });