@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.
- package/CHANGELOG.md +128 -0
- package/README.md +44 -5
- package/README.zh-CN.md +44 -5
- package/SKILL.md +317 -5
- package/TESTING.md +4 -4
- package/dist/browser/errors.d.ts +2 -1
- package/dist/browser/errors.js +9 -10
- package/dist/build-manifest.js +1 -3
- package/dist/cli-manifest.json +2573 -989
- package/dist/cli.js +42 -2
- package/dist/clis/bilibili/download.js +20 -65
- package/dist/clis/bilibili/utils.js +2 -1
- package/dist/clis/chaoxing/assignments.js +2 -1
- package/dist/clis/doubao/ask.d.ts +1 -0
- package/dist/clis/doubao/ask.js +35 -0
- package/dist/clis/doubao/common.d.ts +23 -0
- package/dist/clis/doubao/common.js +564 -0
- package/dist/clis/doubao/new.d.ts +1 -0
- package/dist/clis/doubao/new.js +20 -0
- package/dist/clis/doubao/read.d.ts +1 -0
- package/dist/clis/doubao/read.js +19 -0
- package/dist/clis/doubao/send.d.ts +1 -0
- package/dist/clis/doubao/send.js +22 -0
- package/dist/clis/doubao/status.d.ts +1 -0
- package/dist/clis/doubao/status.js +24 -0
- package/dist/clis/doubao-app/ask.d.ts +1 -0
- package/dist/clis/doubao-app/ask.js +53 -0
- package/dist/clis/doubao-app/common.d.ts +37 -0
- package/dist/clis/doubao-app/common.js +110 -0
- package/dist/clis/doubao-app/dump.d.ts +1 -0
- package/dist/clis/doubao-app/dump.js +24 -0
- package/dist/clis/doubao-app/new.d.ts +1 -0
- package/dist/clis/doubao-app/new.js +20 -0
- package/dist/clis/doubao-app/read.d.ts +1 -0
- package/dist/clis/doubao-app/read.js +18 -0
- package/dist/clis/doubao-app/screenshot.d.ts +1 -0
- package/dist/clis/doubao-app/screenshot.js +18 -0
- package/dist/clis/doubao-app/send.d.ts +1 -0
- package/dist/clis/doubao-app/send.js +27 -0
- package/dist/clis/doubao-app/status.d.ts +1 -0
- package/dist/clis/doubao-app/status.js +16 -0
- package/dist/clis/hackernews/ask.yaml +38 -0
- package/dist/clis/hackernews/best.yaml +38 -0
- package/dist/clis/hackernews/jobs.yaml +36 -0
- package/dist/clis/hackernews/new.yaml +38 -0
- package/dist/clis/hackernews/search.yaml +44 -0
- package/dist/clis/hackernews/show.yaml +38 -0
- package/dist/clis/hackernews/top.yaml +3 -1
- package/dist/clis/hackernews/user.yaml +25 -0
- package/dist/clis/twitter/download.js +13 -97
- package/dist/clis/twitter/thread.js +2 -1
- package/dist/clis/v2ex/member.yaml +29 -0
- package/dist/clis/v2ex/node.yaml +34 -0
- package/dist/clis/v2ex/nodes.yaml +31 -0
- package/dist/clis/v2ex/replies.yaml +32 -0
- package/dist/clis/v2ex/user.yaml +34 -0
- package/dist/clis/weibo/search.d.ts +1 -0
- package/dist/clis/weibo/search.js +73 -0
- package/dist/clis/weixin/download.d.ts +12 -0
- package/dist/clis/weixin/download.js +183 -0
- package/dist/clis/xiaohongshu/download.js +12 -60
- package/dist/clis/xiaohongshu/publish.d.ts +18 -0
- package/dist/clis/xiaohongshu/publish.js +352 -0
- package/dist/clis/xiaohongshu/search.js +47 -15
- package/dist/clis/xiaohongshu/search.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/search.test.js +114 -0
- package/dist/clis/yollomi/background.d.ts +4 -0
- package/dist/clis/yollomi/background.js +45 -0
- package/dist/clis/yollomi/edit.d.ts +5 -0
- package/dist/clis/yollomi/edit.js +56 -0
- package/dist/clis/yollomi/face-swap.d.ts +5 -0
- package/dist/clis/yollomi/face-swap.js +43 -0
- package/dist/clis/yollomi/generate.d.ts +9 -0
- package/dist/clis/yollomi/generate.js +100 -0
- package/dist/clis/yollomi/models.d.ts +1 -0
- package/dist/clis/yollomi/models.js +33 -0
- package/dist/clis/yollomi/object-remover.d.ts +4 -0
- package/dist/clis/yollomi/object-remover.js +42 -0
- package/dist/clis/yollomi/remove-bg.d.ts +4 -0
- package/dist/clis/yollomi/remove-bg.js +38 -0
- package/dist/clis/yollomi/restore.d.ts +4 -0
- package/dist/clis/yollomi/restore.js +38 -0
- package/dist/clis/yollomi/try-on.d.ts +4 -0
- package/dist/clis/yollomi/try-on.js +46 -0
- package/dist/clis/yollomi/upload.d.ts +7 -0
- package/dist/clis/yollomi/upload.js +71 -0
- package/dist/clis/yollomi/upscale.d.ts +4 -0
- package/dist/clis/yollomi/upscale.js +53 -0
- package/dist/clis/yollomi/utils.d.ts +45 -0
- package/dist/clis/yollomi/utils.js +180 -0
- package/dist/clis/yollomi/video.d.ts +5 -0
- package/dist/clis/yollomi/video.js +56 -0
- package/dist/clis/zhihu/download.d.ts +1 -5
- package/dist/clis/zhihu/download.js +20 -126
- package/dist/clis/zhihu/download.test.js +7 -5
- package/dist/clis/zhihu/question.js +2 -1
- package/dist/commanderAdapter.js +4 -6
- package/dist/daemon.js +5 -2
- package/dist/discovery.js +10 -10
- package/dist/download/article-download.d.ts +59 -0
- package/dist/download/article-download.js +178 -0
- package/dist/download/media-download.d.ts +49 -0
- package/dist/download/media-download.js +112 -0
- package/dist/errors.d.ts +23 -2
- package/dist/errors.js +58 -2
- package/dist/errors.test.d.ts +1 -0
- package/dist/errors.test.js +59 -0
- package/dist/execution.js +9 -10
- package/dist/explore.js +4 -2
- package/dist/external.d.ts +15 -0
- package/dist/external.js +48 -2
- package/dist/external.test.d.ts +1 -0
- package/dist/external.test.js +64 -0
- package/dist/main.js +10 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.js +45 -23
- package/dist/plugin.test.js +6 -1
- package/dist/record.d.ts +47 -0
- package/dist/record.js +545 -0
- package/dist/registry.d.ts +7 -2
- package/dist/registry.js +2 -6
- package/dist/runtime.d.ts +3 -1
- package/dist/runtime.js +10 -3
- package/dist/validate.js +1 -3
- package/docs/.vitepress/config.mts +1 -0
- package/docs/adapters/browser/doubao.md +35 -0
- package/docs/adapters/browser/hackernews.md +20 -4
- package/docs/adapters/browser/tiktok.md +1 -1
- package/docs/adapters/browser/v2ex.md +31 -10
- package/docs/adapters/browser/weibo.md +4 -0
- package/docs/adapters/browser/weixin.md +33 -0
- package/docs/adapters/browser/xiaohongshu.md +8 -6
- package/docs/adapters/browser/yollomi.md +69 -0
- package/docs/adapters/desktop/doubao-app.md +35 -0
- package/docs/adapters/index.md +16 -5
- package/docs/advanced/download.md +4 -0
- package/package.json +3 -1
- package/src/browser/errors.ts +17 -11
- package/src/build-manifest.ts +2 -3
- package/src/cli.ts +45 -2
- package/src/clis/bilibili/download.ts +25 -83
- package/src/clis/bilibili/utils.ts +2 -1
- package/src/clis/chaoxing/assignments.ts +2 -1
- package/src/clis/doubao/ask.ts +40 -0
- package/src/clis/doubao/common.ts +619 -0
- package/src/clis/doubao/new.ts +22 -0
- package/src/clis/doubao/read.ts +20 -0
- package/src/clis/doubao/send.ts +25 -0
- package/src/clis/doubao/status.ts +27 -0
- package/src/clis/doubao-app/ask.ts +60 -0
- package/src/clis/doubao-app/common.ts +116 -0
- package/src/clis/doubao-app/dump.ts +28 -0
- package/src/clis/doubao-app/new.ts +21 -0
- package/src/clis/doubao-app/read.ts +21 -0
- package/src/clis/doubao-app/screenshot.ts +19 -0
- package/src/clis/doubao-app/send.ts +30 -0
- package/src/clis/doubao-app/status.ts +17 -0
- package/src/clis/hackernews/ask.yaml +38 -0
- package/src/clis/hackernews/best.yaml +38 -0
- package/src/clis/hackernews/jobs.yaml +36 -0
- package/src/clis/hackernews/new.yaml +38 -0
- package/src/clis/hackernews/search.yaml +44 -0
- package/src/clis/hackernews/show.yaml +38 -0
- package/src/clis/hackernews/top.yaml +3 -1
- package/src/clis/hackernews/user.yaml +25 -0
- package/src/clis/twitter/download.ts +13 -111
- package/src/clis/twitter/thread.ts +2 -1
- package/src/clis/v2ex/member.yaml +29 -0
- package/src/clis/v2ex/node.yaml +34 -0
- package/src/clis/v2ex/nodes.yaml +31 -0
- package/src/clis/v2ex/replies.yaml +32 -0
- package/src/clis/v2ex/user.yaml +34 -0
- package/src/clis/weibo/search.ts +78 -0
- package/src/clis/weixin/download.ts +199 -0
- package/src/clis/xiaohongshu/download.ts +12 -71
- package/src/clis/xiaohongshu/publish.ts +392 -0
- package/src/clis/xiaohongshu/search.test.ts +134 -0
- package/src/clis/xiaohongshu/search.ts +49 -15
- package/src/clis/yollomi/background.ts +48 -0
- package/src/clis/yollomi/edit.ts +58 -0
- package/src/clis/yollomi/face-swap.ts +45 -0
- package/src/clis/yollomi/generate.ts +95 -0
- package/src/clis/yollomi/models.ts +38 -0
- package/src/clis/yollomi/object-remover.ts +44 -0
- package/src/clis/yollomi/remove-bg.ts +40 -0
- package/src/clis/yollomi/restore.ts +40 -0
- package/src/clis/yollomi/try-on.ts +48 -0
- package/src/clis/yollomi/upload.ts +78 -0
- package/src/clis/yollomi/upscale.ts +49 -0
- package/src/clis/yollomi/utils.ts +202 -0
- package/src/clis/yollomi/video.ts +61 -0
- package/src/clis/zhihu/download.test.ts +7 -5
- package/src/clis/zhihu/download.ts +23 -158
- package/src/clis/zhihu/question.ts +2 -1
- package/src/commanderAdapter.ts +4 -7
- package/src/daemon.ts +5 -2
- package/src/discovery.ts +26 -26
- package/src/download/article-download.ts +272 -0
- package/src/download/media-download.ts +178 -0
- package/src/errors.test.ts +79 -0
- package/src/errors.ts +92 -2
- package/src/execution.ts +14 -10
- package/src/explore.ts +4 -2
- package/src/external.test.ts +88 -0
- package/src/external.ts +56 -2
- package/src/generate.ts +2 -1
- package/src/main.ts +10 -0
- package/src/plugin.test.ts +7 -1
- package/src/plugin.ts +49 -25
- package/src/record.ts +617 -0
- package/src/registry.ts +9 -5
- package/src/runtime.ts +16 -4
- package/src/validate.ts +2 -3
- package/tests/e2e/browser-auth.test.ts +10 -1
- package/tests/e2e/browser-public.test.ts +13 -8
- package/tests/e2e/public-commands.test.ts +209 -21
- package/tests/smoke/api-health.test.ts +65 -6
- 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
|
-
|
|
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
|
|
67
|
-
const
|
|
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
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
|
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
|
|
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
|
+
});
|