@sovovs/bycli 2.1.40 → 2.1.42
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/cli-manifest.json +10 -2
- package/clis/weixin/_wechat/article-artifact.js +55 -0
- package/clis/weixin/_wechat/article-identity.js +27 -0
- package/clis/weixin/_wechat/publish-analysis.js +8 -4
- package/clis/weixin/_wechat/publish-download.js +3 -1
- package/clis/weixin/download-publish-data.js +20 -0
- package/clis/weixin/download.js +15 -2
- package/dist/src/adapter-coordination.d.ts +26 -0
- package/dist/src/adapter-coordination.js +183 -0
- package/dist/src/adapter-coordination.test.d.ts +1 -0
- package/dist/src/adapter-execution-context.d.ts +6 -0
- package/dist/src/adapter-execution-context.js +8 -0
- package/dist/src/adapter-scheduler.d.ts +86 -0
- package/dist/src/adapter-scheduler.js +349 -0
- package/dist/src/adapter-scheduler.test.d.ts +1 -0
- package/dist/src/browser/daemon-client.d.ts +11 -0
- package/dist/src/browser/daemon-client.js +53 -1
- package/dist/src/browser/extension-capabilities.d.ts +1 -0
- package/dist/src/browser/extension-capabilities.js +18 -5
- package/dist/src/browser/page.d.ts +2 -1
- package/dist/src/browser/page.js +3 -0
- package/dist/src/build-manifest.js +1 -0
- package/dist/src/cli-argv-preprocess.d.ts +3 -0
- package/dist/src/cli-argv-preprocess.js +4 -0
- package/dist/src/commanderAdapter.js +11 -0
- package/dist/src/daemon.js +118 -0
- package/dist/src/discovery.js +1 -0
- package/dist/src/download/article-download.d.ts +2 -0
- package/dist/src/download/article-download.js +30 -4
- package/dist/src/errors.d.ts +3 -0
- package/dist/src/errors.js +5 -0
- package/dist/src/execution.d.ts +2 -0
- package/dist/src/execution.js +172 -105
- package/dist/src/help.d.ts +1 -0
- package/dist/src/help.js +40 -0
- package/dist/src/manifest-types.d.ts +4 -0
- package/dist/src/registry.d.ts +6 -0
- package/dist/src/registry.js +23 -0
- package/dist/src/serialization.d.ts +1 -0
- package/dist/src/serialization.js +1 -0
- package/dist/src/types.d.ts +2 -0
- package/package.json +3 -2
package/dist/src/help.js
CHANGED
|
@@ -48,6 +48,19 @@ const BROWSER_COMMON_OPTIONS = [
|
|
|
48
48
|
choices: ['true', 'false'],
|
|
49
49
|
},
|
|
50
50
|
];
|
|
51
|
+
const ADAPTER_SESSION_OPTIONS = [
|
|
52
|
+
{
|
|
53
|
+
flags: '--adapter-session <name>',
|
|
54
|
+
name: 'adapter-session',
|
|
55
|
+
help: 'Named persistent Adapter tab session',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
flags: '--adapter-queue-timeout <seconds>',
|
|
59
|
+
name: 'adapter-queue-timeout',
|
|
60
|
+
help: 'Seconds to wait for an Adapter command lease',
|
|
61
|
+
default: 300,
|
|
62
|
+
},
|
|
63
|
+
];
|
|
51
64
|
function normalizeStructuredHelpFormat(value) {
|
|
52
65
|
const normalized = value?.toLowerCase();
|
|
53
66
|
if (normalized === 'yaml' || normalized === 'yml')
|
|
@@ -369,6 +382,12 @@ function compactCommand(cmd) {
|
|
|
369
382
|
positionals: positionals(cmd).map(compactArg),
|
|
370
383
|
command_options: commandOptions(cmd).map(compactArg),
|
|
371
384
|
...(hasBrowserCapability(cmd) ? { browser_common_options: BROWSER_COMMON_OPTIONS.map(compactCommonOption) } : {}),
|
|
385
|
+
...(cmd.adapterConcurrency?.isolatedTabs === true
|
|
386
|
+
? {
|
|
387
|
+
adapterConcurrency: cmd.adapterConcurrency,
|
|
388
|
+
adapter_common_options: ADAPTER_SESSION_OPTIONS.map(compactCommonOption),
|
|
389
|
+
}
|
|
390
|
+
: {}),
|
|
372
391
|
example: formatCommandExample(cmd),
|
|
373
392
|
...(cmd.siteSession ? { siteSession: cmd.siteSession } : {}),
|
|
374
393
|
...(cmd.defaultFormat ? { defaultFormat: cmd.defaultFormat } : {}),
|
|
@@ -417,6 +436,9 @@ export function siteHelpData(site, commands) {
|
|
|
417
436
|
commands: unique.map(cmd => compactCommand(cmd)),
|
|
418
437
|
common_options: COMMON_OPTIONS.map(compactCommonOption),
|
|
419
438
|
...(unique.some(hasBrowserCapability) ? { browser_common_options: BROWSER_COMMON_OPTIONS.map(compactCommonOption) } : {}),
|
|
439
|
+
...(unique.some(cmd => cmd.adapterConcurrency?.isolatedTabs === true)
|
|
440
|
+
? { adapter_common_options: ADAPTER_SESSION_OPTIONS.map(compactCommonOption) }
|
|
441
|
+
: {}),
|
|
420
442
|
next: [
|
|
421
443
|
`bycli ${site} <command> --help -f yaml`,
|
|
422
444
|
`bycli ${site} <command> -f yaml`,
|
|
@@ -429,6 +451,12 @@ export function commandHelpData(cmd) {
|
|
|
429
451
|
...compactCommand(cmd),
|
|
430
452
|
common_options: COMMON_OPTIONS.map(compactCommonOption),
|
|
431
453
|
...(hasBrowserCapability(cmd) ? { browser_common_options: BROWSER_COMMON_OPTIONS.map(compactCommonOption) } : {}),
|
|
454
|
+
...(cmd.adapterConcurrency?.isolatedTabs === true
|
|
455
|
+
? {
|
|
456
|
+
adapterConcurrency: cmd.adapterConcurrency,
|
|
457
|
+
adapter_common_options: ADAPTER_SESSION_OPTIONS.map(compactCommonOption),
|
|
458
|
+
}
|
|
459
|
+
: {}),
|
|
432
460
|
output_formats: ['table', 'plain', 'yaml', 'json', 'md', 'csv'],
|
|
433
461
|
};
|
|
434
462
|
}
|
|
@@ -468,6 +496,15 @@ export function formatBrowserCommonOptionsHelpText() {
|
|
|
468
496
|
});
|
|
469
497
|
return ['Browser common options:', ...formatRows(rows)].join('\n');
|
|
470
498
|
}
|
|
499
|
+
export function formatAdapterSessionOptionsHelpText() {
|
|
500
|
+
const rows = ADAPTER_SESSION_OPTIONS.map(option => {
|
|
501
|
+
const details = [option.help];
|
|
502
|
+
if ('default' in option)
|
|
503
|
+
details.push(`default: ${option.default}`);
|
|
504
|
+
return [option.flags, details.join(' ')];
|
|
505
|
+
});
|
|
506
|
+
return ['Adapter session options:', ...formatRows(rows)].join('\n');
|
|
507
|
+
}
|
|
471
508
|
export function formatSiteHelpText(site, commands) {
|
|
472
509
|
const unique = [...new Map(commands.map(cmd => [fullName(cmd), cmd])).values()]
|
|
473
510
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
@@ -481,6 +518,7 @@ export function formatSiteHelpText(site, commands) {
|
|
|
481
518
|
'',
|
|
482
519
|
formatCommonOptionsHelpText(),
|
|
483
520
|
...(unique.some(hasBrowserCapability) ? ['', formatBrowserCommonOptionsHelpText()] : []),
|
|
521
|
+
...(unique.some(cmd => cmd.adapterConcurrency?.isolatedTabs === true) ? ['', formatAdapterSessionOptionsHelpText()] : []),
|
|
484
522
|
'',
|
|
485
523
|
`Agent tip: use 'bycli ${site} --help -f yaml' to get all command args/options in one structured response.`,
|
|
486
524
|
'',
|
|
@@ -511,6 +549,8 @@ export function formatCommandHelpText(cmd) {
|
|
|
511
549
|
lines.push(formatCommonOptionsHelpText(), '');
|
|
512
550
|
if (hasBrowserCapability(cmd))
|
|
513
551
|
lines.push(formatBrowserCommonOptionsHelpText(), '');
|
|
552
|
+
if (cmd.adapterConcurrency?.isolatedTabs === true)
|
|
553
|
+
lines.push(formatAdapterSessionOptionsHelpText(), '');
|
|
514
554
|
const meta = [];
|
|
515
555
|
meta.push(`Access: ${cmd.access}`);
|
|
516
556
|
meta.push(`Browser: ${browserRequirementLabel(cmd)}`);
|
|
@@ -38,4 +38,8 @@ export interface ManifestEntry {
|
|
|
38
38
|
navigateBefore?: boolean | string;
|
|
39
39
|
/** Site session lifecycle defaults — see CliCommand.siteSession */
|
|
40
40
|
siteSession?: 'ephemeral' | 'persistent';
|
|
41
|
+
adapterConcurrency?: {
|
|
42
|
+
isolatedTabs: true;
|
|
43
|
+
maxParallel: number;
|
|
44
|
+
};
|
|
41
45
|
}
|
package/dist/src/registry.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export type ConditionalBrowserCommandFunc = (page: IPage | null, kwargs: Command
|
|
|
28
28
|
export type NonBrowserCommandFunc = (kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
29
29
|
export type CommandAccess = 'read' | 'write';
|
|
30
30
|
export type SiteSessionMode = 'ephemeral' | 'persistent';
|
|
31
|
+
export interface AdapterConcurrency {
|
|
32
|
+
isolatedTabs: true;
|
|
33
|
+
maxParallel: number;
|
|
34
|
+
}
|
|
31
35
|
/**
|
|
32
36
|
* 所有已注册 adapter command 的共享元数据和运行选项。
|
|
33
37
|
*
|
|
@@ -82,6 +86,8 @@ interface BaseCliCommand {
|
|
|
82
86
|
navigateBefore?: boolean | string;
|
|
83
87
|
/** adapter 浏览器站点 session 生命周期:临时 session 或持久 session。 */
|
|
84
88
|
siteSession?: SiteSessionMode;
|
|
89
|
+
/** Opt-in authorization for isolated persistent Adapter tabs. */
|
|
90
|
+
adapterConcurrency?: AdapterConcurrency;
|
|
85
91
|
/** 用户没有传 `-f/--format` 时使用的默认输出格式。 */
|
|
86
92
|
defaultFormat?: 'table' | 'plain' | 'json' | 'yaml' | 'yml' | 'md' | 'markdown' | 'csv';
|
|
87
93
|
}
|
package/dist/src/registry.js
CHANGED
|
@@ -95,6 +95,7 @@ function rawCommandBase(opts) {
|
|
|
95
95
|
validateArgs: opts.validateArgs,
|
|
96
96
|
navigateBefore: opts.navigateBefore,
|
|
97
97
|
siteSession: opts.siteSession,
|
|
98
|
+
adapterConcurrency: opts.adapterConcurrency,
|
|
98
99
|
defaultFormat: opts.defaultFormat,
|
|
99
100
|
};
|
|
100
101
|
}
|
|
@@ -190,6 +191,27 @@ function assertSiteSession(cmd) {
|
|
|
190
191
|
throw new Error(`Command ${key} siteSession must be one of: ephemeral, persistent`);
|
|
191
192
|
}
|
|
192
193
|
}
|
|
194
|
+
function assertAdapterConcurrency(cmd) {
|
|
195
|
+
if (cmd.adapterConcurrency === undefined)
|
|
196
|
+
return;
|
|
197
|
+
const key = `${cmd.site}/${cmd.name}`;
|
|
198
|
+
if (!cmd.adapterConcurrency || typeof cmd.adapterConcurrency !== 'object') {
|
|
199
|
+
throw new Error(`Command ${key} adapterConcurrency must be an object`);
|
|
200
|
+
}
|
|
201
|
+
const metadata = cmd.adapterConcurrency;
|
|
202
|
+
if (metadata.isolatedTabs !== true) {
|
|
203
|
+
throw new Error(`Command ${key} adapterConcurrency.isolatedTabs must be true`);
|
|
204
|
+
}
|
|
205
|
+
if (!Number.isInteger(metadata.maxParallel)
|
|
206
|
+
|| metadata.maxParallel < 1
|
|
207
|
+
|| metadata.maxParallel > 3) {
|
|
208
|
+
throw new Error(`Command ${key} adapterConcurrency.maxParallel must be an integer between 1 and 3`);
|
|
209
|
+
}
|
|
210
|
+
if (cmd.browser === false
|
|
211
|
+
|| (cmd.browser === undefined && (cmd.strategy === Strategy.PUBLIC || cmd.strategy === Strategy.LOCAL))) {
|
|
212
|
+
throw new Error(`Command ${key} adapterConcurrency requires browser capability`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
193
215
|
export function registerCommand(cmd) {
|
|
194
216
|
registerCommandInput(cmd);
|
|
195
217
|
}
|
|
@@ -197,6 +219,7 @@ function registerCommandInput(cmd) {
|
|
|
197
219
|
withRegistryMutationGroup(() => {
|
|
198
220
|
assertCommandAccess(cmd);
|
|
199
221
|
assertSiteSession(cmd);
|
|
222
|
+
assertAdapterConcurrency(cmd);
|
|
200
223
|
if (cmd.browser === 'conditional') {
|
|
201
224
|
if (typeof cmd.requiresBrowser !== 'function') {
|
|
202
225
|
const key = `${cmd.site}/${cmd.name}`;
|
|
@@ -33,6 +33,7 @@ export declare function serializeCommand(cmd: CliCommand): {
|
|
|
33
33
|
example: string;
|
|
34
34
|
defaultFormat: "table" | "plain" | "json" | "yaml" | "yml" | "md" | "markdown" | "csv" | null;
|
|
35
35
|
siteSession: import("./registry.js").SiteSessionMode | null;
|
|
36
|
+
adapterConcurrency: import("./registry.js").AdapterConcurrency | null;
|
|
36
37
|
};
|
|
37
38
|
/** Human-readable arg summary: `<required> [optional]` style. */
|
|
38
39
|
export declare function formatArgSummary(args: Arg[]): string;
|
|
@@ -35,6 +35,7 @@ export function serializeCommand(cmd) {
|
|
|
35
35
|
example: formatCommandExample(cmd),
|
|
36
36
|
defaultFormat: cmd.defaultFormat ?? null,
|
|
37
37
|
siteSession: cmd.siteSession ?? null,
|
|
38
|
+
adapterConcurrency: cmd.adapterConcurrency ?? null,
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
// ── Formatting ──────────────────────────────────────────────────────────────
|
package/dist/src/types.d.ts
CHANGED
|
@@ -222,6 +222,8 @@ export interface IPage {
|
|
|
222
222
|
/** Focus the browser window containing the active page for interactive login. */
|
|
223
223
|
focusWindow?(): Promise<void>;
|
|
224
224
|
closeWindow?(): Promise<void>;
|
|
225
|
+
/** Pin subsequent commands to the daemon profile selected for this operation. */
|
|
226
|
+
setContextId?(contextId: string): void;
|
|
225
227
|
/** Returns the current page URL, or null if unavailable. */
|
|
226
228
|
getCurrentUrl?(): Promise<string | null>;
|
|
227
229
|
/** Returns the active page identity (targetId), or undefined if not yet resolved. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sovovs/bycli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.42",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"./download/media-download": "./dist/src/download/media-download.js",
|
|
34
34
|
"./download/progress": "./dist/src/download/progress.js",
|
|
35
35
|
"./download/wechat-article": "./dist/src/download/wechat-article.js",
|
|
36
|
-
"./pipeline": "./dist/src/pipeline/index.js"
|
|
36
|
+
"./pipeline": "./dist/src/pipeline/index.js",
|
|
37
|
+
"./adapter-coordination": "./dist/src/adapter-coordination.js"
|
|
37
38
|
},
|
|
38
39
|
"files": [
|
|
39
40
|
"dist/src/",
|