@jackwener/opencli 1.7.8 → 1.7.10
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/README.md +49 -14
- package/README.zh-CN.md +30 -10
- package/cli-manifest.json +646 -30
- package/clis/36kr/news.js +1 -1
- package/clis/apple-podcasts/commands.test.js +4 -4
- package/clis/apple-podcasts/episodes.js +1 -1
- package/clis/apple-podcasts/search.js +1 -1
- package/clis/apple-podcasts/top.js +1 -1
- package/clis/arxiv/paper.js +1 -1
- package/clis/arxiv/search.js +1 -1
- package/clis/band/mentions.js +3 -3
- package/clis/bbc/news.js +1 -1
- package/clis/bilibili/subtitle.js +2 -2
- package/clis/bloomberg/businessweek.js +1 -1
- package/clis/bloomberg/economics.js +1 -1
- package/clis/bloomberg/industries.js +1 -1
- package/clis/bloomberg/main.js +1 -1
- package/clis/bloomberg/markets.js +1 -1
- package/clis/bloomberg/opinions.js +1 -1
- package/clis/bloomberg/politics.js +1 -1
- package/clis/bloomberg/tech.js +1 -1
- package/clis/boss/search.js +49 -8
- package/clis/boss/search.test.js +78 -0
- package/clis/boss/send.js +3 -3
- package/clis/chatgpt/image.js +37 -8
- package/clis/chatgpt/image.test.js +92 -0
- package/clis/chatgpt/utils.js +39 -6
- package/clis/chatgpt/utils.test.js +63 -0
- package/clis/chatgpt-app/ask.js +1 -1
- package/clis/chatgpt-app/ax.js +4 -2
- package/clis/chatgpt-app/ax.test.js +12 -0
- package/clis/chatgpt-app/model.js +1 -1
- package/clis/chatgpt-app/new.js +1 -1
- package/clis/chatgpt-app/read.js +1 -1
- package/clis/chatgpt-app/send.js +1 -1
- package/clis/chatgpt-app/status.js +1 -1
- package/clis/chatwise/ask.js +2 -2
- package/clis/chatwise/model.js +2 -2
- package/clis/chatwise/send.js +2 -2
- package/clis/claude/ask.js +128 -0
- package/clis/claude/ask.test.js +338 -0
- package/clis/claude/commands.test.js +118 -0
- package/clis/claude/detail.js +29 -0
- package/clis/claude/history.js +31 -0
- package/clis/claude/new.js +21 -0
- package/clis/claude/read.js +24 -0
- package/clis/claude/send.js +41 -0
- package/clis/claude/status.js +24 -0
- package/clis/claude/utils.js +440 -0
- package/clis/claude/utils.test.js +148 -0
- package/clis/codex/ask.js +2 -2
- package/clis/codex/send.js +2 -2
- package/clis/ctrip/search.js +1 -1
- package/clis/ctrip/search.test.js +4 -4
- package/clis/cursor/ask.js +2 -2
- package/clis/cursor/composer.js +2 -2
- package/clis/cursor/send.js +2 -2
- package/clis/deepseek/ask.js +17 -4
- package/clis/deepseek/ask.test.js +46 -0
- package/clis/deepseek/utils.js +55 -16
- package/clis/deepseek/utils.test.js +124 -5
- package/clis/doubao/utils.js +53 -11
- package/clis/doubao/utils.test.js +22 -2
- package/clis/eastmoney/announcement.js +1 -1
- package/clis/eastmoney/convertible.js +1 -1
- package/clis/eastmoney/etf.js +1 -1
- package/clis/eastmoney/holders.js +1 -1
- package/clis/eastmoney/index-board.js +1 -1
- package/clis/eastmoney/kline.js +1 -1
- package/clis/eastmoney/kuaixun.js +1 -1
- package/clis/eastmoney/longhu.js +1 -1
- package/clis/eastmoney/money-flow.js +1 -1
- package/clis/eastmoney/northbound.js +1 -1
- package/clis/eastmoney/quote.js +1 -1
- package/clis/eastmoney/rank.js +1 -1
- package/clis/eastmoney/sectors.js +1 -1
- package/clis/facebook/marketplace-inbox.js +83 -0
- package/clis/facebook/marketplace-listings.js +83 -0
- package/clis/facebook/marketplace.test.js +91 -0
- package/clis/google/news.js +1 -1
- package/clis/google/suggest.js +1 -1
- package/clis/google/trends.js +1 -1
- package/clis/google-scholar/cite.js +74 -0
- package/clis/google-scholar/cite.test.js +47 -0
- package/clis/google-scholar/profile.js +92 -0
- package/clis/google-scholar/profile.test.js +49 -0
- package/clis/google-scholar/search.js +1 -1
- package/clis/google-scholar/search.test.js +15 -0
- package/clis/hf/top.js +1 -1
- package/clis/instagram/collection-create.js +57 -0
- package/clis/instagram/saved.js +21 -7
- package/clis/jd/item.js +679 -47
- package/clis/jd/item.test.js +318 -7
- package/clis/jd/item.test.ts +517 -0
- package/clis/lesswrong/comments.js +1 -1
- package/clis/lesswrong/curated.js +1 -1
- package/clis/lesswrong/frontpage.js +1 -1
- package/clis/lesswrong/new.js +1 -1
- package/clis/lesswrong/read.js +1 -1
- package/clis/lesswrong/sequences.js +1 -1
- package/clis/lesswrong/shortform.js +1 -1
- package/clis/lesswrong/tag.js +1 -1
- package/clis/lesswrong/tags.js +1 -1
- package/clis/lesswrong/top-month.js +1 -1
- package/clis/lesswrong/top-week.js +1 -1
- package/clis/lesswrong/top-year.js +1 -1
- package/clis/lesswrong/top.js +1 -1
- package/clis/lesswrong/user-posts.js +1 -1
- package/clis/lesswrong/user.js +1 -1
- package/clis/paperreview/commands.test.js +6 -6
- package/clis/paperreview/feedback.js +1 -1
- package/clis/paperreview/review.js +1 -1
- package/clis/paperreview/submit.js +1 -1
- package/clis/producthunt/posts.js +1 -1
- package/clis/producthunt/today.js +1 -1
- package/clis/sinablog/search.js +1 -1
- package/clis/sinafinance/news.js +1 -1
- package/clis/sinafinance/stock.js +1 -1
- package/clis/sinafinance/stock.test.js +2 -2
- package/clis/spotify/spotify.js +6 -6
- package/clis/substack/search.js +1 -1
- package/clis/toutiao/articles.js +5 -6
- package/clis/toutiao/articles.test.js +22 -15
- package/clis/twitter/followers.js +2 -2
- package/clis/twitter/following.js +224 -73
- package/clis/twitter/following.test.js +277 -0
- package/clis/twitter/post.js +184 -47
- package/clis/twitter/post.test.js +114 -34
- package/clis/uiverse/_shared.js +63 -4
- package/clis/uiverse/_shared.test.js +7 -0
- package/clis/uiverse/code.js +1 -0
- package/clis/uiverse/navigation.test.js +12 -0
- package/clis/uiverse/preview.js +1 -0
- package/clis/web/read.js +319 -81
- package/clis/web/read.test.js +221 -5
- package/clis/weibo/favorites.js +169 -0
- package/clis/weibo/favorites.test.js +114 -0
- package/clis/weibo/publish.js +282 -0
- package/clis/weibo/publish.test.js +183 -0
- package/clis/weread/ranking.js +1 -1
- package/clis/weread/search-regression.test.js +8 -8
- package/clis/weread/search.js +1 -1
- package/clis/wikipedia/random.js +1 -1
- package/clis/wikipedia/search.js +1 -1
- package/clis/wikipedia/summary.js +1 -1
- package/clis/wikipedia/trending.js +1 -1
- package/clis/xianyu/chat.js +3 -3
- package/clis/xianyu/item.js +2 -2
- package/clis/xianyu/item.test.js +3 -3
- package/clis/xiaohongshu/search.js +17 -2
- package/clis/xiaohongshu/search.test.js +37 -1
- package/clis/xiaoyuzhou/download.js +1 -1
- package/clis/xiaoyuzhou/download.test.js +3 -3
- package/clis/xiaoyuzhou/episode.js +1 -1
- package/clis/xiaoyuzhou/podcast-episodes.js +1 -1
- package/clis/xiaoyuzhou/podcast-episodes.test.js +2 -2
- package/clis/xiaoyuzhou/podcast.js +1 -1
- package/clis/xiaoyuzhou/transcript.js +1 -1
- package/clis/xiaoyuzhou/transcript.test.js +5 -5
- package/clis/yollomi/models.js +1 -1
- package/clis/youtube/channel.js +24 -1
- package/clis/youtube/channel.test.js +59 -0
- package/clis/zhihu/answer.js +21 -162
- package/clis/zhihu/answer.test.js +26 -53
- package/clis/zhihu/collection.js +197 -0
- package/clis/zhihu/collection.test.js +290 -0
- package/clis/zhihu/collections.js +127 -0
- package/clis/zhihu/collections.test.js +182 -0
- package/clis/zhihu/comment.js +24 -305
- package/clis/zhihu/comment.test.js +31 -35
- package/clis/zhihu/favorite.js +44 -182
- package/clis/zhihu/favorite.test.js +30 -167
- package/clis/zhihu/follow.js +25 -56
- package/clis/zhihu/follow.test.js +20 -23
- package/clis/zhihu/like.js +22 -67
- package/clis/zhihu/like.test.js +19 -42
- package/clis/zhihu/search.js +3 -2
- package/clis/zhihu/write-shared.js +8 -1
- package/clis/zhihu/write-shared.test.js +1 -0
- package/clis/zlibrary/commands.test.js +75 -0
- package/clis/zlibrary/info.js +47 -0
- package/clis/zlibrary/search.js +46 -0
- package/clis/zlibrary/utils.js +136 -0
- package/dist/src/adapter-source.d.ts +11 -0
- package/dist/src/adapter-source.js +24 -0
- package/dist/src/adapter-source.test.js +29 -0
- package/dist/src/browser/base-page.d.ts +3 -1
- package/dist/src/browser/base-page.js +76 -1
- package/dist/src/browser/base-page.test.d.ts +1 -0
- package/dist/src/browser/base-page.test.js +74 -0
- package/dist/src/browser/bridge.d.ts +1 -2
- package/dist/src/browser/bridge.js +40 -41
- package/dist/src/browser/cdp.d.ts +1 -0
- package/dist/src/browser/cdp.js +3 -3
- package/dist/src/browser/daemon-client.d.ts +38 -4
- package/dist/src/browser/daemon-client.js +24 -7
- package/dist/src/browser/daemon-client.test.js +49 -0
- package/dist/src/browser/daemon-lifecycle.d.ts +23 -0
- package/dist/src/browser/daemon-lifecycle.js +67 -0
- package/dist/src/browser/daemon-version.d.ts +4 -0
- package/dist/src/browser/daemon-version.js +12 -0
- package/dist/src/browser/errors.js +3 -0
- package/dist/src/browser/errors.test.js +3 -0
- package/dist/src/browser/network-cache.d.ts +1 -0
- package/dist/src/browser/page.d.ts +3 -1
- package/dist/src/browser/page.js +10 -2
- package/dist/src/browser/profile.d.ts +14 -0
- package/dist/src/browser/profile.js +85 -0
- package/dist/src/build-manifest.d.ts +2 -0
- package/dist/src/build-manifest.js +13 -3
- package/dist/src/build-manifest.test.js +20 -2
- package/dist/src/cli.d.ts +6 -0
- package/dist/src/cli.js +477 -35
- package/dist/src/cli.test.js +303 -2
- package/dist/src/commanderAdapter.js +17 -9
- package/dist/src/commanderAdapter.test.js +67 -2
- package/dist/src/commands/daemon.d.ts +2 -0
- package/dist/src/commands/daemon.js +42 -1
- package/dist/src/commands/daemon.test.js +103 -2
- package/dist/src/completion-shared.js +1 -2
- package/dist/src/completion.test.js +3 -2
- package/dist/src/daemon.js +125 -41
- package/dist/src/doctor.d.ts +5 -6
- package/dist/src/doctor.js +77 -19
- package/dist/src/doctor.test.js +117 -0
- package/dist/src/engine.test.js +6 -5
- package/dist/src/errors.d.ts +14 -8
- package/dist/src/errors.js +36 -30
- package/dist/src/errors.test.js +5 -5
- package/dist/src/execution.d.ts +4 -0
- package/dist/src/execution.js +173 -25
- package/dist/src/execution.test.js +171 -1
- package/dist/src/main.js +10 -0
- package/dist/src/observation/artifact.d.ts +16 -0
- package/dist/src/observation/artifact.js +260 -0
- package/dist/src/observation/artifact.test.d.ts +1 -0
- package/dist/src/observation/artifact.test.js +121 -0
- package/dist/src/observation/events.d.ts +89 -0
- package/dist/src/observation/events.js +1 -0
- package/dist/src/observation/index.d.ts +7 -0
- package/dist/src/observation/index.js +7 -0
- package/dist/src/observation/manager.d.ts +9 -0
- package/dist/src/observation/manager.js +27 -0
- package/dist/src/observation/manager.test.d.ts +1 -0
- package/dist/src/observation/manager.test.js +13 -0
- package/dist/src/observation/redaction.d.ts +11 -0
- package/dist/src/observation/redaction.js +81 -0
- package/dist/src/observation/redaction.test.d.ts +1 -0
- package/dist/src/observation/redaction.test.js +32 -0
- package/dist/src/observation/retention.d.ts +32 -0
- package/dist/src/observation/retention.js +160 -0
- package/dist/src/observation/retention.test.d.ts +1 -0
- package/dist/src/observation/retention.test.js +118 -0
- package/dist/src/observation/ring-buffer.d.ts +22 -0
- package/dist/src/observation/ring-buffer.js +45 -0
- package/dist/src/observation/ring-buffer.test.d.ts +1 -0
- package/dist/src/observation/ring-buffer.test.js +22 -0
- package/dist/src/observation/session.d.ts +25 -0
- package/dist/src/observation/session.js +50 -0
- package/dist/src/pipeline/executor.test.js +1 -0
- package/dist/src/pipeline/steps/download.test.js +1 -0
- package/dist/src/pipeline/steps/fetch.js +1 -21
- package/dist/src/pipeline/steps/fetch.test.js +6 -12
- package/dist/src/plugin-scaffold.js +1 -1
- package/dist/src/plugin-scaffold.test.js +1 -1
- package/dist/src/registry.d.ts +40 -9
- package/dist/src/registry.js +3 -1
- package/dist/src/runtime-detect.d.ts +10 -0
- package/dist/src/runtime-detect.js +19 -0
- package/dist/src/runtime-detect.test.js +12 -1
- package/dist/src/runtime.d.ts +2 -0
- package/dist/src/runtime.js +1 -0
- package/dist/src/types.d.ts +22 -0
- package/dist/src/update-check.d.ts +31 -1
- package/dist/src/update-check.js +62 -16
- package/dist/src/update-check.test.js +86 -1
- package/package.json +1 -1
- package/dist/src/diagnostic.d.ts +0 -63
- package/dist/src/diagnostic.js +0 -292
- package/dist/src/diagnostic.test.js +0 -302
- /package/dist/src/{diagnostic.test.d.ts → adapter-source.test.d.ts} +0 -0
package/dist/src/registry.d.ts
CHANGED
|
@@ -25,17 +25,17 @@ export interface RequiredEnv {
|
|
|
25
25
|
help?: string;
|
|
26
26
|
}
|
|
27
27
|
export type CommandArgs = Record<string, any>;
|
|
28
|
-
export
|
|
28
|
+
export type BrowserCommandFunc = (page: IPage, kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
29
|
+
export type NonBrowserCommandFunc = (kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
30
|
+
interface BaseCliCommand {
|
|
29
31
|
site: string;
|
|
30
32
|
name: string;
|
|
31
33
|
aliases?: string[];
|
|
32
34
|
description: string;
|
|
33
35
|
domain?: string;
|
|
34
36
|
strategy?: Strategy;
|
|
35
|
-
browser?: boolean;
|
|
36
37
|
args: Arg[];
|
|
37
38
|
columns?: string[];
|
|
38
|
-
func?: (page: IPage, kwargs: CommandArgs, debug?: boolean) => Promise<unknown>;
|
|
39
39
|
pipeline?: Record<string, unknown>[];
|
|
40
40
|
timeoutSeconds?: number;
|
|
41
41
|
/** Origin of this command: 'yaml', 'ts', or plugin name. */
|
|
@@ -66,22 +66,53 @@ export interface CliCommand {
|
|
|
66
66
|
/** Override the default CLI output format when the user does not pass -f/--format. */
|
|
67
67
|
defaultFormat?: 'table' | 'plain' | 'json' | 'yaml' | 'yml' | 'md' | 'markdown' | 'csv';
|
|
68
68
|
}
|
|
69
|
+
export interface BrowserCliCommand extends BaseCliCommand {
|
|
70
|
+
/** Browser commands receive an IPage. Omitted means true after normalization. */
|
|
71
|
+
browser?: true;
|
|
72
|
+
func?: BrowserCommandFunc;
|
|
73
|
+
}
|
|
74
|
+
export interface NonBrowserCliCommand extends BaseCliCommand {
|
|
75
|
+
/** Non-browser commands do not receive a page argument. */
|
|
76
|
+
browser: false;
|
|
77
|
+
func?: NonBrowserCommandFunc;
|
|
78
|
+
}
|
|
79
|
+
export type CliCommand = BrowserCliCommand | NonBrowserCliCommand;
|
|
80
|
+
type RawCliCommand = BaseCliCommand & {
|
|
81
|
+
browser?: boolean;
|
|
82
|
+
func?: BrowserCommandFunc | NonBrowserCommandFunc;
|
|
83
|
+
};
|
|
69
84
|
/** Internal extension for lazy-loaded TS modules (not exposed in public API) */
|
|
70
|
-
export
|
|
85
|
+
export type InternalCliCommand = CliCommand & {
|
|
71
86
|
_lazy?: boolean;
|
|
72
87
|
_modulePath?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
88
|
+
};
|
|
89
|
+
type RequiredCliOptions = {
|
|
75
90
|
site: string;
|
|
76
91
|
name: string;
|
|
77
92
|
description?: string;
|
|
78
93
|
args?: Arg[];
|
|
79
|
-
}
|
|
94
|
+
};
|
|
95
|
+
type BrowserStrategy = Exclude<Strategy, Strategy.PUBLIC | Strategy.LOCAL>;
|
|
96
|
+
type BrowserCliOptions = Partial<Omit<BrowserCliCommand, 'args' | 'description' | 'browser' | 'strategy'>> & RequiredCliOptions & ({
|
|
97
|
+
browser: true;
|
|
98
|
+
strategy?: Strategy;
|
|
99
|
+
} | {
|
|
100
|
+
browser?: true;
|
|
101
|
+
strategy?: BrowserStrategy;
|
|
102
|
+
});
|
|
103
|
+
type NonBrowserCliOptions = Partial<Omit<NonBrowserCliCommand, 'args' | 'description'>> & RequiredCliOptions & ({
|
|
104
|
+
browser: false;
|
|
105
|
+
} | {
|
|
106
|
+
strategy: Strategy.PUBLIC | Strategy.LOCAL;
|
|
107
|
+
browser?: false;
|
|
108
|
+
});
|
|
109
|
+
export type CliOptions = BrowserCliOptions | NonBrowserCliOptions;
|
|
80
110
|
declare global {
|
|
81
111
|
var __opencli_registry__: Map<string, CliCommand> | undefined;
|
|
82
112
|
}
|
|
83
113
|
export declare function cli(opts: CliOptions): CliCommand;
|
|
84
114
|
export declare function getRegistry(): Map<string, CliCommand>;
|
|
85
|
-
export declare function fullName(cmd:
|
|
115
|
+
export declare function fullName(cmd: Pick<BaseCliCommand, 'site' | 'name'>): string;
|
|
86
116
|
export declare function strategyLabel(cmd: CliCommand): string;
|
|
87
|
-
export declare function registerCommand(cmd:
|
|
117
|
+
export declare function registerCommand(cmd: RawCliCommand): void;
|
|
118
|
+
export {};
|
package/dist/src/registry.js
CHANGED
|
@@ -72,7 +72,9 @@ function normalizeCommand(cmd) {
|
|
|
72
72
|
navigateBefore = true;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
return
|
|
75
|
+
return browser
|
|
76
|
+
? { ...cmd, strategy, browser: true, navigateBefore }
|
|
77
|
+
: { ...cmd, strategy, browser: false, navigateBefore };
|
|
76
78
|
}
|
|
77
79
|
export function registerCommand(cmd) {
|
|
78
80
|
const normalized = normalizeCommand(cmd);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* (e.g. logging, diagnostics) without littering runtime sniffing everywhere.
|
|
7
7
|
*/
|
|
8
8
|
export type Runtime = 'bun' | 'node';
|
|
9
|
+
export declare const MIN_SUPPORTED_NODE_MAJOR = 21;
|
|
9
10
|
/**
|
|
10
11
|
* Detect the current JavaScript runtime.
|
|
11
12
|
*/
|
|
@@ -19,3 +20,12 @@ export declare function getRuntimeVersion(): string;
|
|
|
19
20
|
* Return a combined label like "node v22.13.0" or "bun 1.1.42".
|
|
20
21
|
*/
|
|
21
22
|
export declare function getRuntimeLabel(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Parse a Node.js version string like "v22.13.0" and return its major version.
|
|
25
|
+
* Returns null for non-Node or malformed inputs.
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseNodeMajor(version: string): number | null;
|
|
28
|
+
/**
|
|
29
|
+
* Whether the given Node.js version satisfies the current minimum support policy.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isSupportedNodeVersion(version?: string): boolean;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* This module centralises the check so other code can adapt behaviour
|
|
6
6
|
* (e.g. logging, diagnostics) without littering runtime sniffing everywhere.
|
|
7
7
|
*/
|
|
8
|
+
export const MIN_SUPPORTED_NODE_MAJOR = 21;
|
|
8
9
|
/**
|
|
9
10
|
* Detect the current JavaScript runtime.
|
|
10
11
|
*/
|
|
@@ -26,3 +27,21 @@ export function getRuntimeVersion() {
|
|
|
26
27
|
export function getRuntimeLabel() {
|
|
27
28
|
return `${detectRuntime()} ${getRuntimeVersion()}`;
|
|
28
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a Node.js version string like "v22.13.0" and return its major version.
|
|
32
|
+
* Returns null for non-Node or malformed inputs.
|
|
33
|
+
*/
|
|
34
|
+
export function parseNodeMajor(version) {
|
|
35
|
+
const match = /^v?(\d+)\./.exec(String(version).trim());
|
|
36
|
+
if (!match)
|
|
37
|
+
return null;
|
|
38
|
+
const major = Number(match[1]);
|
|
39
|
+
return Number.isInteger(major) ? major : null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Whether the given Node.js version satisfies the current minimum support policy.
|
|
43
|
+
*/
|
|
44
|
+
export function isSupportedNodeVersion(version = process.version) {
|
|
45
|
+
const major = parseNodeMajor(version);
|
|
46
|
+
return major !== null && major >= MIN_SUPPORTED_NODE_MAJOR;
|
|
47
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { detectRuntime, getRuntimeVersion, getRuntimeLabel } from './runtime-detect.js';
|
|
2
|
+
import { detectRuntime, getRuntimeVersion, getRuntimeLabel, parseNodeMajor, isSupportedNodeVersion, MIN_SUPPORTED_NODE_MAJOR } from './runtime-detect.js';
|
|
3
3
|
describe('runtime-detect', () => {
|
|
4
4
|
it('detectRuntime returns a valid runtime string', () => {
|
|
5
5
|
const rt = detectRuntime();
|
|
@@ -24,4 +24,15 @@ describe('runtime-detect', () => {
|
|
|
24
24
|
expect(rt).toBe('node');
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
|
+
it('parses Node major versions from standard version strings', () => {
|
|
28
|
+
expect(parseNodeMajor('v21.0.0')).toBe(21);
|
|
29
|
+
expect(parseNodeMajor('22.13.1')).toBe(22);
|
|
30
|
+
expect(parseNodeMajor('bun-1.2.0')).toBeNull();
|
|
31
|
+
});
|
|
32
|
+
it('checks the current minimum supported Node major version', () => {
|
|
33
|
+
expect(MIN_SUPPORTED_NODE_MAJOR).toBe(21);
|
|
34
|
+
expect(isSupportedNodeVersion('v20.18.0')).toBe(false);
|
|
35
|
+
expect(isSupportedNodeVersion('v21.0.0')).toBe(true);
|
|
36
|
+
expect(isSupportedNodeVersion('v25.0.0')).toBe(true);
|
|
37
|
+
});
|
|
27
38
|
});
|
package/dist/src/runtime.d.ts
CHANGED
|
@@ -27,10 +27,12 @@ export interface IBrowserFactory {
|
|
|
27
27
|
timeout?: number;
|
|
28
28
|
workspace?: string;
|
|
29
29
|
cdpEndpoint?: string;
|
|
30
|
+
contextId?: string;
|
|
30
31
|
}): Promise<IPage>;
|
|
31
32
|
close(): Promise<void>;
|
|
32
33
|
}
|
|
33
34
|
export declare function browserSession<T>(BrowserFactory: new () => IBrowserFactory, fn: (page: IPage) => Promise<T>, opts?: {
|
|
34
35
|
workspace?: string;
|
|
35
36
|
cdpEndpoint?: string;
|
|
37
|
+
contextId?: string;
|
|
36
38
|
}): Promise<T>;
|
package/dist/src/runtime.js
CHANGED
package/dist/src/types.d.ts
CHANGED
|
@@ -33,19 +33,41 @@ export interface ScreenshotOptions {
|
|
|
33
33
|
fullPage?: boolean;
|
|
34
34
|
path?: string;
|
|
35
35
|
}
|
|
36
|
+
export interface FetchJsonOptions {
|
|
37
|
+
method?: string;
|
|
38
|
+
headers?: Record<string, string>;
|
|
39
|
+
body?: unknown;
|
|
40
|
+
timeoutMs?: number;
|
|
41
|
+
}
|
|
36
42
|
export interface BrowserSessionInfo {
|
|
37
43
|
workspace?: string;
|
|
38
44
|
connected?: boolean;
|
|
45
|
+
windowId?: number;
|
|
46
|
+
preferredTabId?: number | null;
|
|
47
|
+
owned?: boolean;
|
|
48
|
+
ownership?: 'owned' | 'borrowed';
|
|
49
|
+
lifecycle?: 'ephemeral' | 'persistent' | 'pinned';
|
|
50
|
+
surface?: 'dedicated-container' | 'borrowed-user-tab';
|
|
51
|
+
contextId?: string;
|
|
52
|
+
tabCount?: number;
|
|
53
|
+
idleMsRemaining?: number | null;
|
|
39
54
|
[key: string]: unknown;
|
|
40
55
|
}
|
|
41
56
|
export interface IPage {
|
|
42
57
|
goto(url: string, options?: {
|
|
43
58
|
waitUntil?: 'load' | 'none';
|
|
44
59
|
settleMs?: number;
|
|
60
|
+
allowBoundNavigation?: boolean;
|
|
45
61
|
}): Promise<void>;
|
|
46
62
|
evaluate(js: string): Promise<any>;
|
|
47
63
|
/** Safely evaluate JS with pre-serialized arguments — prevents injection. */
|
|
48
64
|
evaluateWithArgs?(js: string, args: Record<string, unknown>): Promise<any>;
|
|
65
|
+
/**
|
|
66
|
+
* Fetch JSON from inside the browser context, carrying the page's cookies.
|
|
67
|
+
* This is intentionally narrow: browser-context JSON fetch, not a generic
|
|
68
|
+
* HTTP client.
|
|
69
|
+
*/
|
|
70
|
+
fetchJson(url: string, opts?: FetchJsonOptions): Promise<unknown>;
|
|
49
71
|
getCookies(opts?: {
|
|
50
72
|
domain?: string;
|
|
51
73
|
url?: string;
|
|
@@ -7,7 +7,20 @@
|
|
|
7
7
|
* - Check interval: 24 hours
|
|
8
8
|
* - Notice appears AFTER command output, not before (same as npm/gh/yarn)
|
|
9
9
|
* - Never delays or blocks the CLI command
|
|
10
|
+
*
|
|
11
|
+
* Cache is shared between the CLI process (writes latestVersion / latestExtensionVersion
|
|
12
|
+
* via background fetch) and the daemon process (writes currentExtensionVersion /
|
|
13
|
+
* extensionLastSeenAt via `recordExtensionVersion` on each hello). Writes use a
|
|
14
|
+
* read-merge-write pattern so neither side clobbers the other.
|
|
10
15
|
*/
|
|
16
|
+
declare const EXTENSION_STALE_MS: number;
|
|
17
|
+
interface UpdateCache {
|
|
18
|
+
lastCheck?: number;
|
|
19
|
+
latestVersion?: string;
|
|
20
|
+
latestExtensionVersion?: string;
|
|
21
|
+
currentExtensionVersion?: string;
|
|
22
|
+
extensionLastSeenAt?: number;
|
|
23
|
+
}
|
|
11
24
|
interface GitHubReleaseAsset {
|
|
12
25
|
name: string;
|
|
13
26
|
}
|
|
@@ -15,6 +28,17 @@ interface GitHubRelease {
|
|
|
15
28
|
tag_name: string;
|
|
16
29
|
assets?: GitHubReleaseAsset[];
|
|
17
30
|
}
|
|
31
|
+
interface NoticeInputs {
|
|
32
|
+
cliVersion: string;
|
|
33
|
+
cache: UpdateCache | null;
|
|
34
|
+
now: number;
|
|
35
|
+
}
|
|
36
|
+
interface NoticeLines {
|
|
37
|
+
cli?: string;
|
|
38
|
+
extension?: string;
|
|
39
|
+
}
|
|
40
|
+
/** Pure function: derive notice text from cache state. Exported for tests. */
|
|
41
|
+
declare function buildUpdateNotices({ cliVersion, cache, now }: NoticeInputs): NoticeLines;
|
|
18
42
|
/**
|
|
19
43
|
* Register a process exit hook that prints an update notice if a newer
|
|
20
44
|
* version was found on the last background check.
|
|
@@ -28,9 +52,15 @@ declare function extractLatestExtensionVersionFromReleases(releases: GitHubRelea
|
|
|
28
52
|
* Fully non-blocking — never awaited.
|
|
29
53
|
*/
|
|
30
54
|
export declare function checkForUpdateBackground(): void;
|
|
55
|
+
/**
|
|
56
|
+
* Stash the current extension version into the shared cache. Called by the
|
|
57
|
+
* daemon on each hello handshake. Lets the next CLI process compare against
|
|
58
|
+
* the latest known release and print an exit notice without any extra I/O.
|
|
59
|
+
*/
|
|
60
|
+
export declare function recordExtensionVersion(version: string): void;
|
|
31
61
|
/**
|
|
32
62
|
* Get the cached latest extension version (if available).
|
|
33
63
|
* Used by `opencli doctor` to report extension updates.
|
|
34
64
|
*/
|
|
35
65
|
export declare function getCachedLatestExtensionVersion(): string | undefined;
|
|
36
|
-
export { extractLatestExtensionVersionFromReleases as _extractLatestExtensionVersionFromReleases, };
|
|
66
|
+
export { extractLatestExtensionVersionFromReleases as _extractLatestExtensionVersionFromReleases, buildUpdateNotices as _buildUpdateNotices, EXTENSION_STALE_MS as _EXTENSION_STALE_MS, };
|
package/dist/src/update-check.js
CHANGED
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
* - Check interval: 24 hours
|
|
8
8
|
* - Notice appears AFTER command output, not before (same as npm/gh/yarn)
|
|
9
9
|
* - Never delays or blocks the CLI command
|
|
10
|
+
*
|
|
11
|
+
* Cache is shared between the CLI process (writes latestVersion / latestExtensionVersion
|
|
12
|
+
* via background fetch) and the daemon process (writes currentExtensionVersion /
|
|
13
|
+
* extensionLastSeenAt via `recordExtensionVersion` on each hello). Writes use a
|
|
14
|
+
* read-merge-write pattern so neither side clobbers the other.
|
|
10
15
|
*/
|
|
11
16
|
import * as fs from 'node:fs';
|
|
12
17
|
import * as path from 'node:path';
|
|
@@ -16,24 +21,25 @@ import { PKG_VERSION } from './version.js';
|
|
|
16
21
|
const CACHE_DIR = path.join(os.homedir(), '.opencli');
|
|
17
22
|
const CACHE_FILE = path.join(CACHE_DIR, 'update-check.json');
|
|
18
23
|
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
24
|
+
const EXTENSION_STALE_MS = 7 * 24 * 60 * 60 * 1000; // 7d
|
|
19
25
|
const NPM_REGISTRY_URL = 'https://registry.npmjs.org/@jackwener/opencli/latest';
|
|
20
26
|
const GITHUB_RELEASES_URL = 'https://api.github.com/repos/jackwener/OpenCLI/releases?per_page=20';
|
|
21
|
-
|
|
22
|
-
const _cache = (() => {
|
|
27
|
+
function readCacheSync() {
|
|
23
28
|
try {
|
|
24
29
|
return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf-8'));
|
|
25
30
|
}
|
|
26
31
|
catch {
|
|
27
32
|
return null;
|
|
28
33
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
34
|
+
}
|
|
35
|
+
// Read cache once at module load — shared by both exported functions
|
|
36
|
+
const _cache = readCacheSync();
|
|
37
|
+
function writeCacheMerge(updates) {
|
|
31
38
|
try {
|
|
32
39
|
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
fs.writeFileSync(CACHE_FILE, JSON.stringify(data), 'utf-8');
|
|
40
|
+
const existing = readCacheSync() ?? {};
|
|
41
|
+
const merged = { ...existing, ...updates };
|
|
42
|
+
fs.writeFileSync(CACHE_FILE, JSON.stringify(merged), 'utf-8');
|
|
37
43
|
}
|
|
38
44
|
catch {
|
|
39
45
|
// Best-effort; never fail
|
|
@@ -57,6 +63,28 @@ function isNewer(a, b) {
|
|
|
57
63
|
function isCI() {
|
|
58
64
|
return !!(process.env.CI || process.env.CONTINUOUS_INTEGRATION);
|
|
59
65
|
}
|
|
66
|
+
/** Pure function: derive notice text from cache state. Exported for tests. */
|
|
67
|
+
function buildUpdateNotices({ cliVersion, cache, now }) {
|
|
68
|
+
if (!cache)
|
|
69
|
+
return {};
|
|
70
|
+
const lines = {};
|
|
71
|
+
if (cache.latestVersion && isNewer(cache.latestVersion, cliVersion)) {
|
|
72
|
+
lines.cli =
|
|
73
|
+
styleText('yellow', `\n Update available: v${cliVersion} → v${cache.latestVersion}\n`) +
|
|
74
|
+
styleText('dim', ` Run: npm install -g @jackwener/opencli\n`);
|
|
75
|
+
}
|
|
76
|
+
const { currentExtensionVersion, latestExtensionVersion, extensionLastSeenAt } = cache;
|
|
77
|
+
if (currentExtensionVersion &&
|
|
78
|
+
latestExtensionVersion &&
|
|
79
|
+
extensionLastSeenAt &&
|
|
80
|
+
now - extensionLastSeenAt < EXTENSION_STALE_MS &&
|
|
81
|
+
isNewer(latestExtensionVersion, currentExtensionVersion)) {
|
|
82
|
+
lines.extension =
|
|
83
|
+
styleText('yellow', `\n Extension update available: v${currentExtensionVersion} → v${latestExtensionVersion}\n`) +
|
|
84
|
+
styleText('dim', ` Download: https://github.com/jackwener/opencli/releases\n`);
|
|
85
|
+
}
|
|
86
|
+
return lines;
|
|
87
|
+
}
|
|
60
88
|
/**
|
|
61
89
|
* Register a process exit hook that prints an update notice if a newer
|
|
62
90
|
* version was found on the last background check.
|
|
@@ -71,13 +99,15 @@ export function registerUpdateNoticeOnExit() {
|
|
|
71
99
|
process.on('exit', (code) => {
|
|
72
100
|
if (code !== 0)
|
|
73
101
|
return; // Don't show update notice on error exit
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
const { cli, extension } = buildUpdateNotices({
|
|
103
|
+
cliVersion: PKG_VERSION,
|
|
104
|
+
cache: _cache,
|
|
105
|
+
now: Date.now(),
|
|
106
|
+
});
|
|
107
|
+
if (!cli && !extension)
|
|
77
108
|
return;
|
|
78
109
|
try {
|
|
79
|
-
process.stderr.write(
|
|
80
|
-
styleText('dim', ` Run: npm install -g @jackwener/opencli\n\n`));
|
|
110
|
+
process.stderr.write(`${cli ?? ''}${extension ?? ''}\n`);
|
|
81
111
|
}
|
|
82
112
|
catch {
|
|
83
113
|
// Ignore broken pipe (stderr closed before process exits)
|
|
@@ -123,7 +153,7 @@ async function fetchLatestExtensionVersion() {
|
|
|
123
153
|
export function checkForUpdateBackground() {
|
|
124
154
|
if (isCI())
|
|
125
155
|
return;
|
|
126
|
-
if (_cache && Date.now() - _cache.lastCheck < CHECK_INTERVAL_MS)
|
|
156
|
+
if (_cache?.lastCheck && Date.now() - _cache.lastCheck < CHECK_INTERVAL_MS)
|
|
127
157
|
return;
|
|
128
158
|
void (async () => {
|
|
129
159
|
try {
|
|
@@ -139,7 +169,10 @@ export function checkForUpdateBackground() {
|
|
|
139
169
|
const data = await res.json();
|
|
140
170
|
if (typeof data.version === 'string') {
|
|
141
171
|
const extVersion = await fetchLatestExtensionVersion();
|
|
142
|
-
|
|
172
|
+
const updates = { lastCheck: Date.now(), latestVersion: data.version };
|
|
173
|
+
if (extVersion)
|
|
174
|
+
updates.latestExtensionVersion = extVersion;
|
|
175
|
+
writeCacheMerge(updates);
|
|
143
176
|
}
|
|
144
177
|
}
|
|
145
178
|
catch {
|
|
@@ -147,6 +180,19 @@ export function checkForUpdateBackground() {
|
|
|
147
180
|
}
|
|
148
181
|
})();
|
|
149
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Stash the current extension version into the shared cache. Called by the
|
|
185
|
+
* daemon on each hello handshake. Lets the next CLI process compare against
|
|
186
|
+
* the latest known release and print an exit notice without any extra I/O.
|
|
187
|
+
*/
|
|
188
|
+
export function recordExtensionVersion(version) {
|
|
189
|
+
if (typeof version !== 'string' || !version.trim())
|
|
190
|
+
return;
|
|
191
|
+
writeCacheMerge({
|
|
192
|
+
currentExtensionVersion: version.trim(),
|
|
193
|
+
extensionLastSeenAt: Date.now(),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
150
196
|
/**
|
|
151
197
|
* Get the cached latest extension version (if available).
|
|
152
198
|
* Used by `opencli doctor` to report extension updates.
|
|
@@ -154,4 +200,4 @@ export function checkForUpdateBackground() {
|
|
|
154
200
|
export function getCachedLatestExtensionVersion() {
|
|
155
201
|
return _cache?.latestExtensionVersion;
|
|
156
202
|
}
|
|
157
|
-
export { extractLatestExtensionVersionFromReleases as _extractLatestExtensionVersionFromReleases, };
|
|
203
|
+
export { extractLatestExtensionVersionFromReleases as _extractLatestExtensionVersionFromReleases, buildUpdateNotices as _buildUpdateNotices, EXTENSION_STALE_MS as _EXTENSION_STALE_MS, };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { _extractLatestExtensionVersionFromReleases as extractLatestExtensionVersionFromReleases } from './update-check.js';
|
|
2
|
+
import { _extractLatestExtensionVersionFromReleases as extractLatestExtensionVersionFromReleases, _buildUpdateNotices as buildUpdateNotices, _EXTENSION_STALE_MS as EXTENSION_STALE_MS, } from './update-check.js';
|
|
3
3
|
describe('extractLatestExtensionVersionFromReleases', () => {
|
|
4
4
|
it('reads the extension version from a versioned asset on a normal CLI release', () => {
|
|
5
5
|
expect(extractLatestExtensionVersionFromReleases([
|
|
@@ -29,3 +29,88 @@ describe('extractLatestExtensionVersionFromReleases', () => {
|
|
|
29
29
|
])).toBeUndefined();
|
|
30
30
|
});
|
|
31
31
|
});
|
|
32
|
+
describe('buildUpdateNotices', () => {
|
|
33
|
+
const now = 1_700_000_000_000;
|
|
34
|
+
it('returns nothing when cache is empty', () => {
|
|
35
|
+
expect(buildUpdateNotices({ cliVersion: '1.0.0', cache: null, now })).toEqual({});
|
|
36
|
+
});
|
|
37
|
+
it('emits a CLI notice when registry version is newer', () => {
|
|
38
|
+
const lines = buildUpdateNotices({
|
|
39
|
+
cliVersion: '1.0.0',
|
|
40
|
+
cache: { lastCheck: now, latestVersion: '1.0.1' },
|
|
41
|
+
now,
|
|
42
|
+
});
|
|
43
|
+
expect(lines.cli).toContain('v1.0.0 → v1.0.1');
|
|
44
|
+
expect(lines.extension).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
it('emits an extension notice when current ext is older and cache is fresh', () => {
|
|
47
|
+
const lines = buildUpdateNotices({
|
|
48
|
+
cliVersion: '1.0.0',
|
|
49
|
+
cache: {
|
|
50
|
+
lastCheck: now,
|
|
51
|
+
latestVersion: '1.0.0',
|
|
52
|
+
latestExtensionVersion: '2.1.0',
|
|
53
|
+
currentExtensionVersion: '2.0.0',
|
|
54
|
+
extensionLastSeenAt: now - 60_000,
|
|
55
|
+
},
|
|
56
|
+
now,
|
|
57
|
+
});
|
|
58
|
+
expect(lines.cli).toBeUndefined();
|
|
59
|
+
expect(lines.extension).toContain('v2.0.0 → v2.1.0');
|
|
60
|
+
});
|
|
61
|
+
it('skips the extension notice when lastSeenAt is older than the stale window', () => {
|
|
62
|
+
const lines = buildUpdateNotices({
|
|
63
|
+
cliVersion: '1.0.0',
|
|
64
|
+
cache: {
|
|
65
|
+
lastCheck: now,
|
|
66
|
+
latestVersion: '1.0.0',
|
|
67
|
+
latestExtensionVersion: '2.1.0',
|
|
68
|
+
currentExtensionVersion: '2.0.0',
|
|
69
|
+
extensionLastSeenAt: now - EXTENSION_STALE_MS - 1,
|
|
70
|
+
},
|
|
71
|
+
now,
|
|
72
|
+
});
|
|
73
|
+
expect(lines.extension).toBeUndefined();
|
|
74
|
+
});
|
|
75
|
+
it('skips the extension notice when current and latest are equal', () => {
|
|
76
|
+
const lines = buildUpdateNotices({
|
|
77
|
+
cliVersion: '1.0.0',
|
|
78
|
+
cache: {
|
|
79
|
+
lastCheck: now,
|
|
80
|
+
latestVersion: '1.0.0',
|
|
81
|
+
latestExtensionVersion: '2.0.0',
|
|
82
|
+
currentExtensionVersion: '2.0.0',
|
|
83
|
+
extensionLastSeenAt: now,
|
|
84
|
+
},
|
|
85
|
+
now,
|
|
86
|
+
});
|
|
87
|
+
expect(lines.extension).toBeUndefined();
|
|
88
|
+
});
|
|
89
|
+
it('does not throw when cache has only daemon-written fields and no latestVersion', () => {
|
|
90
|
+
const lines = buildUpdateNotices({
|
|
91
|
+
cliVersion: '1.0.0',
|
|
92
|
+
cache: {
|
|
93
|
+
currentExtensionVersion: '2.0.0',
|
|
94
|
+
extensionLastSeenAt: now,
|
|
95
|
+
},
|
|
96
|
+
now,
|
|
97
|
+
});
|
|
98
|
+
expect(lines.cli).toBeUndefined();
|
|
99
|
+
expect(lines.extension).toBeUndefined();
|
|
100
|
+
});
|
|
101
|
+
it('emits both notices when both are out of date', () => {
|
|
102
|
+
const lines = buildUpdateNotices({
|
|
103
|
+
cliVersion: '1.0.0',
|
|
104
|
+
cache: {
|
|
105
|
+
lastCheck: now,
|
|
106
|
+
latestVersion: '1.1.0',
|
|
107
|
+
latestExtensionVersion: '2.1.0',
|
|
108
|
+
currentExtensionVersion: '2.0.0',
|
|
109
|
+
extensionLastSeenAt: now,
|
|
110
|
+
},
|
|
111
|
+
now,
|
|
112
|
+
});
|
|
113
|
+
expect(lines.cli).toContain('v1.0.0 → v1.1.0');
|
|
114
|
+
expect(lines.extension).toContain('v2.0.0 → v2.1.0');
|
|
115
|
+
});
|
|
116
|
+
});
|
package/package.json
CHANGED
package/dist/src/diagnostic.d.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Structured diagnostic output for AI-driven adapter repair.
|
|
3
|
-
*
|
|
4
|
-
* When OPENCLI_DIAGNOSTIC=1, failed commands emit a JSON RepairContext to stderr
|
|
5
|
-
* containing the error, adapter source, and browser state (DOM snapshot, network
|
|
6
|
-
* requests, console errors). AI Agents consume this to diagnose and fix adapters.
|
|
7
|
-
*
|
|
8
|
-
* Safety boundaries:
|
|
9
|
-
* - Sensitive headers/cookies are redacted before emission
|
|
10
|
-
* - Individual fields are capped to prevent unbounded output
|
|
11
|
-
* - Network response bodies from authenticated requests are stripped
|
|
12
|
-
* - Total output is capped to MAX_DIAGNOSTIC_BYTES
|
|
13
|
-
*/
|
|
14
|
-
import type { IPage } from './types.js';
|
|
15
|
-
import type { InternalCliCommand } from './registry.js';
|
|
16
|
-
/** Maximum bytes for the entire diagnostic JSON output. */
|
|
17
|
-
export declare const MAX_DIAGNOSTIC_BYTES: number;
|
|
18
|
-
export interface RepairContext {
|
|
19
|
-
error: {
|
|
20
|
-
code: string;
|
|
21
|
-
message: string;
|
|
22
|
-
hint?: string;
|
|
23
|
-
stack?: string;
|
|
24
|
-
};
|
|
25
|
-
adapter: {
|
|
26
|
-
site: string;
|
|
27
|
-
command: string;
|
|
28
|
-
sourcePath?: string;
|
|
29
|
-
source?: string;
|
|
30
|
-
};
|
|
31
|
-
page?: {
|
|
32
|
-
url: string;
|
|
33
|
-
snapshot: string;
|
|
34
|
-
networkRequests: unknown[];
|
|
35
|
-
capturedPayloads?: unknown[];
|
|
36
|
-
consoleErrors: unknown[];
|
|
37
|
-
};
|
|
38
|
-
timestamp: string;
|
|
39
|
-
}
|
|
40
|
-
/** Truncate a string to maxLen, appending a truncation marker. */
|
|
41
|
-
export declare function truncate(str: string, maxLen: number): string;
|
|
42
|
-
/** Redact sensitive query parameters from a URL. */
|
|
43
|
-
export declare function redactUrl(url: string): string;
|
|
44
|
-
/** Redact inline secrets from free-text strings (error messages, stack traces, console output, DOM). */
|
|
45
|
-
export declare function redactText(text: string): string;
|
|
46
|
-
/**
|
|
47
|
-
* Resolve the editable source file path for an adapter.
|
|
48
|
-
*
|
|
49
|
-
* Priority:
|
|
50
|
-
* 1. cmd.source (set for FS-scanned JS and manifest lazy-loaded JS)
|
|
51
|
-
* 2. cmd._modulePath (set for manifest lazy-loaded JS)
|
|
52
|
-
*
|
|
53
|
-
* Skip manifest: prefixed pseudo-paths (YAML commands inlined in manifest).
|
|
54
|
-
*/
|
|
55
|
-
export declare function resolveAdapterSourcePath(cmd: InternalCliCommand): string | undefined;
|
|
56
|
-
/** Whether diagnostic mode is enabled. */
|
|
57
|
-
export declare function isDiagnosticEnabled(): boolean;
|
|
58
|
-
/** Build a RepairContext from an error, command metadata, and optional page state. */
|
|
59
|
-
export declare function buildRepairContext(err: unknown, cmd: InternalCliCommand, pageState?: RepairContext['page']): RepairContext;
|
|
60
|
-
/** Collect full diagnostic context including page state (with timeout). */
|
|
61
|
-
export declare function collectDiagnostic(err: unknown, cmd: InternalCliCommand, page: IPage | null): Promise<RepairContext>;
|
|
62
|
-
/** Emit diagnostic JSON to stderr, enforcing total size cap. */
|
|
63
|
-
export declare function emitDiagnostic(ctx: RepairContext): void;
|