dsh-moli 1.0.2 → 1.0.5
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 +136 -113
- package/README.zh.md +123 -119
- package/index.js +69 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,143 +3,101 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/dsh-moli)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
browser for AI agents
|
|
6
|
+
**Two tools that let a DeepSeek Harness agent drive a real headless browser.** They wrap
|
|
7
|
+
[Moli](https://github.com/lexmount/moli) — a Rust headless browser built for AI agents — so an agent can
|
|
8
|
+
read pages that only exist after JavaScript runs, and can produce pictures of them.
|
|
8
9
|
|
|
9
10
|
English | [中文](README.zh.md)
|
|
10
11
|
|
|
11
|
-
##
|
|
12
|
+
## What it does, and when you want it
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
A plain HTTP fetch returns the HTML the server sent. That is enough for articles, docs and APIs, and
|
|
15
|
+
DSH already covers it with `web_fetch`. It is not enough for anything a browser has to build:
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
straight from the repository works too, and needs GitHub to be reachable:
|
|
17
|
+
- **Single-page apps** — a client-rendered news site, dashboard or docs site. The response is an empty
|
|
18
|
+
shell; the content appears only after scripts run.
|
|
19
|
+
- **Logins and consent walls** — a page that needs a session or cookie before it shows anything.
|
|
20
|
+
- **Pictures** — a screenshot to see what a page looks like, or a PDF to keep.
|
|
21
|
+
- **One value from deep inside a page** — a price, a count, a title, read with a selector instead of
|
|
22
|
+
pulling the whole document.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
dsh plugin --profile web add github:27painter/dsh-moli
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Either way, restart DSH, then check the engine and fetch a page:
|
|
28
|
-
|
|
29
|
-
```
|
|
30
|
-
moli_probe
|
|
31
|
-
moli_fetch url=https://example.com dump=markdown
|
|
32
|
-
```
|
|
24
|
+
For those jobs this plugin gives the agent two tools:
|
|
33
25
|
|
|
34
|
-
|
|
35
|
-
`moli_probe action=install` can fetch it. See [Installation](#installation).
|
|
36
|
-
|
|
37
|
-
## What it provides
|
|
38
|
-
|
|
39
|
-
| Tool | Purpose |
|
|
26
|
+
| Tool | What it does |
|
|
40
27
|
|---|---|
|
|
41
|
-
| `moli_fetch` |
|
|
42
|
-
| `moli_probe` |
|
|
28
|
+
| `moli_fetch` | Renders a URL and returns Markdown, HTML, a semantic tree, or a JSON envelope carrying the HTTP status; evaluates a JavaScript expression; writes a PNG screenshot or a PDF |
|
|
29
|
+
| `moli_probe` | Reports whether the engine is installed, which version, and whether HTTPS works — and installs Moli when it is missing |
|
|
43
30
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
`noCss`, `resources`, `withFrames`, `insecureTls`, `profileDir`, `cookieFile`.
|
|
31
|
+
The practical question is whether the agent needs the page as a **browser** would see it. If a plain
|
|
32
|
+
fetch already returns the text you want, `web_fetch` is lighter and faster.
|
|
47
33
|
|
|
48
34
|
```
|
|
49
|
-
moli_fetch
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
35
|
+
agent ──moli_fetch──▶ dsh-moli plugin ──spawns──▶ moli.exe
|
|
36
|
+
▲ │
|
|
37
|
+
│ renders the page,
|
|
38
|
+
│ runs its JavaScript
|
|
39
|
+
│ │
|
|
40
|
+
└──markdown / json / png / pdf◀┘
|
|
54
41
|
```
|
|
55
42
|
|
|
56
|
-
##
|
|
43
|
+
## Install
|
|
57
44
|
|
|
58
|
-
|
|
59
|
-
[`moli-websearch`](https://github.com/lexmount/moli/tree/main/skills/moli-websearch), and
|
|
60
|
-
[`moli-cdp-server`](https://github.com/lexmount/moli/tree/main/skills/moli-cdp-server) — and their
|
|
61
|
-
README's quick start is to have an agent install them. If your agent loads skills, the simplest path
|
|
62
|
-
is to point it at those; they are maintained upstream and cover web search and a CDP server too.
|
|
63
|
-
|
|
64
|
-
This plugin exists because it is a different trade-off, not a replacement:
|
|
65
|
-
|
|
66
|
-
- **Always-on tool schemas instead of an on-demand skill.** The tools are registered at Host startup,
|
|
67
|
-
so the model sees them every turn with no discovery step.
|
|
68
|
-
- **DSH-specific failure handling.** The three traps below (sandbox pipe capture, UTF-16 mangling of
|
|
69
|
-
binary output, bare-specifier resolution for a `link:`ed plugin) plus sandbox/revocation/proxy
|
|
70
|
-
classification are solved here, because they are DSH-on-Windows problems.
|
|
71
|
-
- **Smaller surface.** Only `fetch` is wrapped; the official skills also cover web search and the CDP
|
|
72
|
-
server, which this plugin does not.
|
|
73
|
-
|
|
74
|
-
Both can coexist: install the skills if you want upstream coverage, keep this plugin if you want the
|
|
75
|
-
capabilities always visible to the model.
|
|
76
|
-
|
|
77
|
-
## Installation
|
|
45
|
+
Two routes. Both install the same plugin; pick by what your network reaches.
|
|
78
46
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
### Route A — Moli is already installed
|
|
82
|
-
|
|
83
|
-
Nothing else to fetch. The plugin finds `moli.exe` on its own and both tools work immediately.
|
|
47
|
+
**Route 1 — from npm (recommended).** Resolves through the npm registry, so it works where GitHub is
|
|
48
|
+
slow or blocked, and DSH's install dialog can fall back to a regional mirror:
|
|
84
49
|
|
|
85
50
|
```powershell
|
|
86
51
|
dsh plugin --profile web add dsh-moli
|
|
87
52
|
```
|
|
88
53
|
|
|
89
|
-
|
|
90
|
-
unreachable for you:
|
|
54
|
+
**Route 2 — straight from the repository.** Tracks the source directly; needs GitHub to be reachable:
|
|
91
55
|
|
|
92
56
|
```powershell
|
|
93
57
|
dsh plugin --profile web add github:27painter/dsh-moli
|
|
94
58
|
```
|
|
95
59
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
60
|
+
> [!IMPORTANT]
|
|
61
|
+
> **This package is the plugin only — it does not include the Moli engine.** It is 26 kB of
|
|
62
|
+
> JavaScript; `moli.exe` is a separate ~101 MB Rust binary with its own release process. Installing the
|
|
63
|
+
> plugin does not install Moli, and `moli_fetch` reports that the engine is missing until you install
|
|
64
|
+
> it.
|
|
65
|
+
>
|
|
66
|
+
> **There is no npm package for the engine.** The registry names `moli` and `moli-cli` belong to
|
|
67
|
+
> unrelated projects, and `@lexmount/moli` does not exist. Moli ships as prebuilt binaries on
|
|
68
|
+
> [GitHub Releases](https://github.com/lexmount/moli/releases/latest) — do not install the engine by
|
|
69
|
+
> guessing a package name.
|
|
99
70
|
|
|
100
|
-
|
|
71
|
+
Either route ends the same way. Restart DSH, then check the engine and fetch a page:
|
|
101
72
|
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
moli_probe action=install
|
|
73
|
+
```
|
|
74
|
+
moli_probe
|
|
75
|
+
moli_fetch url=https://example.com dump=markdown
|
|
106
76
|
```
|
|
107
77
|
|
|
108
|
-
|
|
109
|
-
filtered network can block the release host completely. It reports the SHA256 of the exact bytes it
|
|
110
|
-
ran, and `expectedSha256` turns that report into an enforced gate — see
|
|
111
|
-
[Verifying the download](#verifying-the-download). Installation only ever runs when a call asks for
|
|
112
|
-
it; it is never a side effect of using `moli_fetch`.
|
|
113
|
-
|
|
114
|
-
### Installing into the desktop profile
|
|
115
|
-
|
|
116
|
-
`dsh plugin --profile desktop …` is refused — the desktop profile belongs to the Electron app. Either
|
|
117
|
-
edit its `package.json` directly (add a `link:` dependency **and** the bundle entry, then run
|
|
118
|
-
`pnpm install`), or use the in-app plugin page (sidebar → **Plugins** → **Add plugin**), which goes
|
|
119
|
-
through the same pnpm path.
|
|
78
|
+
### Getting the Moli engine
|
|
120
79
|
|
|
121
|
-
|
|
122
|
-
the other leaves the plugin invisible to the loader, and an unresolvable bundle is **skipped
|
|
123
|
-
silently** apart from one stderr line (`skipping profile bundle …`). If the tools never appear, that
|
|
124
|
-
line is the first thing to look for.
|
|
80
|
+
`moli_probe` reports whether the engine is present. If it is not, pick one of:
|
|
125
81
|
|
|
126
|
-
|
|
82
|
+
**1. Let the plugin install it** — tries several download routes and reports a SHA256 of what it ran:
|
|
127
83
|
|
|
128
|
-
|
|
84
|
+
```
|
|
85
|
+
moli_probe action=install
|
|
86
|
+
```
|
|
129
87
|
|
|
130
|
-
|
|
88
|
+
**2. Official one-line installer** (Moli's own documented commands):
|
|
131
89
|
|
|
132
90
|
```powershell
|
|
91
|
+
# Windows
|
|
133
92
|
powershell -ExecutionPolicy ByPass -c "irm https://github.com/lexmount/moli/releases/latest/download/moli-installer.ps1 | iex"
|
|
134
93
|
```
|
|
135
94
|
|
|
136
|
-
Linux / macOS:
|
|
137
|
-
|
|
138
95
|
```sh
|
|
96
|
+
# Linux / macOS
|
|
139
97
|
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/lexmount/moli/releases/latest/download/moli-installer.sh | sh
|
|
140
98
|
```
|
|
141
99
|
|
|
142
|
-
|
|
100
|
+
**3. Direct binary,** if you would rather not run an installer:
|
|
143
101
|
|
|
144
102
|
```powershell
|
|
145
103
|
# pick the asset matching your architecture from the releases page
|
|
@@ -147,14 +105,17 @@ curl.exe -L -o moli.zip https://github.com/lexmount/moli/releases/latest/downloa
|
|
|
147
105
|
Expand-Archive moli.zip -DestinationPath "$env:LOCALAPPDATA\Moli" -Force
|
|
148
106
|
```
|
|
149
107
|
|
|
150
|
-
|
|
108
|
+
Those `releases/latest/download/...` URLs always resolve to the newest release, so they stay valid
|
|
109
|
+
without pinning a version.
|
|
110
|
+
|
|
111
|
+
After any of them, point the plugin at the result if it landed somewhere unusual:
|
|
151
112
|
|
|
152
113
|
```yaml
|
|
153
114
|
config:
|
|
154
115
|
exePath: 'C:\path\to\moli.exe'
|
|
155
116
|
```
|
|
156
117
|
|
|
157
|
-
|
|
118
|
+
#### Verifying the download
|
|
158
119
|
|
|
159
120
|
Moli's README documents no checksum or signature, and the installer publishes no checksum file. What
|
|
160
121
|
does exist is GitHub's own per-asset `sha256` digest, readable from the release API:
|
|
@@ -177,12 +138,69 @@ Compare it against the file you downloaded:
|
|
|
177
138
|
```
|
|
178
139
|
|
|
179
140
|
The plugin follows the same discipline: `moli_probe action=install` reports the SHA256 of the bytes it
|
|
180
|
-
ran, and `expectedSha256`
|
|
181
|
-
|
|
141
|
+
ran, and `expectedSha256` turns that report into an enforced gate. It does not invent a trusted
|
|
142
|
+
default, because a digest only means something when compared against the release page's own value.
|
|
143
|
+
|
|
144
|
+
This is a checked property rather than a claim: downloading `v1.1.17`'s installer through the plugin's
|
|
145
|
+
own `downloadInstaller` reproduced `e002f7a6…964d` exactly — the digest GitHub publishes — and
|
|
146
|
+
re-hashing the file from disk matched as well.
|
|
147
|
+
|
|
148
|
+
### Installing into a desktop profile
|
|
149
|
+
|
|
150
|
+
`dsh plugin --profile desktop …` is refused — the desktop profile belongs to the Electron app. Either
|
|
151
|
+
edit its `package.json` directly, or use the in-app plugin page (sidebar → **Plugins** → **Add
|
|
152
|
+
plugin**), which installs through the same pnpm path.
|
|
153
|
+
|
|
154
|
+
A profile plugin needs both halves: a dependency edge (`dependencies`) and a
|
|
155
|
+
`dsh.profile.bundles` entry. One without the other leaves the plugin invisible to the loader. From a
|
|
156
|
+
local checkout the four steps are:
|
|
157
|
+
|
|
158
|
+
1. Put this directory anywhere, e.g. `D:\dsh_plugins\dsh-moli`.
|
|
159
|
+
2. Add both entries to the profile's `package.json`:
|
|
160
|
+
- `dependencies`: `"dsh-moli": "link:D:/dsh_plugins/dsh-moli"`
|
|
161
|
+
- `dsh.profile.bundles`: `"dsh-moli"`
|
|
162
|
+
3. Run `pnpm install` in the profile directory (creates `node_modules/dsh-moli`).
|
|
163
|
+
4. Restart DSH.
|
|
164
|
+
|
|
165
|
+
An unresolvable bundle is **skipped silently** apart from one stderr line
|
|
166
|
+
(`skipping profile bundle …`). If the tools never appear, that line is the first thing to look for.
|
|
167
|
+
|
|
168
|
+
## Usage
|
|
169
|
+
|
|
170
|
+
`moli_fetch` parameters: `url` (required), `dump`, `writeTo`, `eval`, `wait`, `waitSelector`,
|
|
171
|
+
`delayMs`, `timeoutMs`, `maxChars`, `headers`, `userAgent`, `layout`, `scrollbars`, `noJs`,
|
|
172
|
+
`noCss`, `resources`, `withFrames`, `insecureTls`, `profileDir`, `cookieFile`.
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
moli_fetch url=https://example.com dump=markdown # token-efficient text
|
|
176
|
+
moli_fetch url=https://example.com dump=semantic_tree_text # nodes with backend ids
|
|
177
|
+
moli_fetch url=https://example.com eval="document.title" # one computed value
|
|
178
|
+
moli_fetch url=https://example.com dump=screenshot writeTo=/abs/path/a.png
|
|
179
|
+
moli_fetch url=https://example.com dump=pdf writeTo=/abs/path/a.pdf
|
|
180
|
+
```
|
|
182
181
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
182
|
+
Screenshot and PDF dumps need `writeTo`; the bytes are written verbatim rather than printed.
|
|
183
|
+
|
|
184
|
+
## Relationship to Moli's own agent skills
|
|
185
|
+
|
|
186
|
+
Moli ships official agent skills in its repository — [`moli-webfetch`](https://github.com/lexmount/moli/tree/main/skills/moli-webfetch),
|
|
187
|
+
[`moli-websearch`](https://github.com/lexmount/moli/tree/main/skills/moli-websearch), and
|
|
188
|
+
[`moli-cdp-server`](https://github.com/lexmount/moli/tree/main/skills/moli-cdp-server) — and their
|
|
189
|
+
README's quick start is to have an agent install them. If your agent loads skills, the simplest path
|
|
190
|
+
is to point it at those; they are maintained upstream and cover web search and a CDP server too.
|
|
191
|
+
|
|
192
|
+
This plugin exists because it is a different trade-off, not a replacement:
|
|
193
|
+
|
|
194
|
+
- **Always-on tool schemas instead of an on-demand skill.** The tools are registered at Host startup,
|
|
195
|
+
so the model sees them every turn with no discovery step.
|
|
196
|
+
- **DSH-specific failure handling.** The three traps below (sandbox pipe capture, UTF-16 mangling of
|
|
197
|
+
binary output, bare-specifier resolution for a `link:`ed plugin) plus sandbox/revocation/proxy
|
|
198
|
+
classification are solved here, because they are DSH-on-Windows problems.
|
|
199
|
+
- **Smaller surface.** Only `fetch` is wrapped; the official skills also cover web search and the CDP
|
|
200
|
+
server, which this plugin does not.
|
|
201
|
+
|
|
202
|
+
Both can coexist: install the skills if you want upstream coverage, keep this plugin if you want the
|
|
203
|
+
capabilities always visible to the model.
|
|
186
204
|
|
|
187
205
|
## Three design points
|
|
188
206
|
|
|
@@ -210,7 +228,7 @@ Override any field under the plugin's `config` entry in the profile patch layer.
|
|
|
210
228
|
defaultTimeoutMs: 30000 # per-fetch readiness deadline
|
|
211
229
|
maxChars: 200000 # inline text truncation
|
|
212
230
|
proxy: 'http://127.0.0.1:7890' # forward proxy for moli and downloads
|
|
213
|
-
insecureTls: true # see TLS notes below
|
|
231
|
+
insecureTls: true # see the TLS notes below
|
|
214
232
|
```
|
|
215
233
|
|
|
216
234
|
Without `exePath`, the plugin probes `exePath` → `MOLI_BIN` → `%LOCALAPPDATA%\Moli\bin\moli.exe` →
|
|
@@ -249,20 +267,25 @@ installation under a versioned subdirectory is still found.
|
|
|
249
267
|
|
|
250
268
|
## Verification
|
|
251
269
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
270
|
+
Two suites live in [`verify/`](verify/), and both are runnable against a working tree:
|
|
271
|
+
|
|
272
|
+
- `schema-verify.mjs` checks the tool definitions with the registry's own validator, including
|
|
273
|
+
controls that assert the two invalid schema shapes still fail.
|
|
274
|
+
- `install-verify.mjs` drives the install pipeline against a loopback HTTP server: route ordering,
|
|
275
|
+
the SHA256 of served bytes, refusal to execute on a checksum mismatch, actual execution when the
|
|
276
|
+
digest matches, and the all-routes-failed diagnostic.
|
|
277
|
+
|
|
278
|
+
Beyond those, `lib/moli.js` and the tool layer were exercised end to end against Moli 1.1.16 on
|
|
279
|
+
Windows: registration, probe, Markdown and JSON dumps, `eval` (including a tight-timeout regression
|
|
280
|
+
guard for the `-t` argument position), PNG and PDF artifacts with valid signatures, truncation, every
|
|
281
|
+
rejection path (binary dump without `writeTo`, unknown `dump`, unknown `wait` stage, missing
|
|
256
282
|
destination directory), failure classification (unreachable host, HTTP status, sandbox TLS block,
|
|
257
283
|
revocation block), and the concurrency claims. The blocked-host classifier is covered by pure
|
|
258
284
|
function tests using stderr text captured from real runs.
|
|
259
285
|
|
|
260
|
-
Confirmed at runtime
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
The install pipeline is covered against a loopback HTTP server, which proves the mechanics without
|
|
264
|
-
depending on GitHub: route ordering, the SHA256 of served bytes, refusal to execute on a checksum
|
|
265
|
-
mismatch, actual execution when the digest matches, and the all-routes-failed diagnostic.
|
|
286
|
+
Confirmed at runtime too: a JavaScript-rendered page (GitHub search) returned 14,560 characters of
|
|
287
|
+
Markdown containing 30 real repository matches when fetched through a local proxy. A throwaway
|
|
288
|
+
profile with the plugin installed composes its config with no `JsonSchemaError` and no skipped bundle.
|
|
266
289
|
|
|
267
290
|
## License
|
|
268
291
|
|
package/README.zh.md
CHANGED
|
@@ -1,137 +1,104 @@
|
|
|
1
1
|
# dsh-moli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**两个工具,让 DeepSeek Harness 的 agent 能驱动真正的无头浏览器。** 它们封装
|
|
4
|
+
[Moli](https://github.com/lexmount/moli)——一个专为 AI agent 打造的 Rust 无头浏览器——所以 agent 能看到
|
|
5
|
+
那些"必须跑完 JavaScript 才存在"的页面内容,也能把它们拍成图。
|
|
4
6
|
|
|
5
7
|
[English](README.md) | 中文
|
|
6
8
|
|
|
7
|
-
##
|
|
9
|
+
## 它做什么,什么时候需要它
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
普通的 HTTP 抓取拿回的是服务器发来的 HTML。对文章、文档、API 来说这足够了,DSH 的 `web_fetch` 已经覆盖
|
|
12
|
+
这种场景。但它拿不到任何**需要浏览器构建出来**的内容:
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
**推荐走这条**:它经 npm registry 解析,所以在 GitHub 慢或不通的网络里照样能装,而且 DSH 的安装对话框能
|
|
16
|
-
回退到国内镜像。直接从仓库装也可以,但需要 GitHub 可达:
|
|
17
|
-
|
|
18
|
-
```powershell
|
|
19
|
-
dsh plugin --profile web add github:27painter/dsh-moli
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
两种方式都要重启 DSH,然后自检并抓一个页面:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
moli_probe
|
|
26
|
-
moli_fetch url=https://example.com dump=markdown
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Moli 本体是另外下载的。`moli_probe` 会报告它是否在场,`moli_probe action=install` 可以替你拉取。
|
|
30
|
-
详见[安装](#安装)。
|
|
31
|
-
|
|
32
|
-
## 与 Moli 官方 agent skill 的关系
|
|
33
|
-
|
|
34
|
-
Moli 仓库自带官方 agent skill:[`moli-webfetch`](https://github.com/lexmount/moli/tree/main/skills/moli-webfetch)、
|
|
35
|
-
[`moli-websearch`](https://github.com/lexmount/moli/tree/main/skills/moli-websearch)、
|
|
36
|
-
[`moli-cdp-server`](https://github.com/lexmount/moli/tree/main/skills/moli-cdp-server),其 README 的快速开始
|
|
37
|
-
就是让 agent 去安装它们。如果你的 agent 能加载 skill,最省事的路就是直接用官方那套——上游维护,而且额外覆盖网页
|
|
38
|
-
搜索与 CDP 服务。
|
|
39
|
-
|
|
40
|
-
本插件的存在是因为它是另一种取舍,不是替代品:
|
|
41
|
-
|
|
42
|
-
- **常驻工具 schema,而非按需 skill。** 工具在 Host 启动时注册,模型每回合都能看到,不需要发现步骤。
|
|
43
|
-
- **针对 DSH 的失败处理。** 下面那三个坑(沙箱管道捕获、二进制被 UTF-16 破坏、`link:` 插件的裸包名解析)
|
|
44
|
-
以及沙箱/吊销/代理三类失败分类,都在这里解决了——因为它们本质是"DSH on Windows"的问题。
|
|
45
|
-
- **面更窄。** 只封装了 `fetch`;官方 skill 还覆盖网页搜索和 CDP 服务,本插件没有。
|
|
46
|
-
|
|
47
|
-
两者可以共存:想要上游覆盖就装 skill,想要能力始终对模型可见就留这个插件。
|
|
14
|
+
- **单页应用(SPA)**——客户端渲染的新闻站、仪表盘、文档站。响应只是一个空壳,内容要等脚本跑完才出现。
|
|
15
|
+
- **登录与同意墙**——必须先有会话或 cookie 才肯显示内容的页面。
|
|
16
|
+
- **图**——想看一眼页面长什么样(截图),或想存档(PDF)。
|
|
17
|
+
- **页面深处的一个值**——价格、计数、标题,用选择器直接取,而不是把整篇文档拉回来。
|
|
48
18
|
|
|
49
|
-
|
|
19
|
+
针对这些场景,本插件给 agent 两个工具:
|
|
50
20
|
|
|
51
21
|
| 工具 | 作用 |
|
|
52
22
|
|---|---|
|
|
53
|
-
| `moli_fetch` |
|
|
54
|
-
| `moli_probe` |
|
|
23
|
+
| `moli_fetch` | 渲染 URL 并返回 Markdown / HTML / 语义树 / 带 HTTP 状态的 JSON;执行 JS 表达式取值;写出 PNG 截图或 PDF |
|
|
24
|
+
| `moli_probe` | 报告引擎是否安装、什么版本、HTTPS 是否可用;没装时还能替你装上 |
|
|
55
25
|
|
|
56
|
-
`
|
|
57
|
-
|
|
58
|
-
`resources`、`withFrames`、`insecureTls`、`profileDir`、`cookieFile`。
|
|
26
|
+
判断标准很简单:**agent 需要的是"浏览器眼里的页面"吗?** 如果普通抓取已经能拿到你要的文字,`web_fetch`
|
|
27
|
+
更轻更快。
|
|
59
28
|
|
|
60
29
|
```
|
|
61
|
-
moli_fetch
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
30
|
+
agent ──moli_fetch──▶ dsh-moli 插件 ──启动──▶ moli.exe
|
|
31
|
+
▲ │
|
|
32
|
+
│ 渲染页面、
|
|
33
|
+
│ 执行其中 JavaScript
|
|
34
|
+
│ │
|
|
35
|
+
└──markdown / json / png / pdf◀┘
|
|
66
36
|
```
|
|
67
37
|
|
|
68
38
|
## 安装
|
|
69
39
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### 路线 A —— 已经装了 Moli
|
|
40
|
+
两条路,装的是同一个插件,按你的网络情况选。
|
|
73
41
|
|
|
74
|
-
|
|
42
|
+
**路线 1 —— 从 npm 装(推荐)。** 经 npm registry 解析,所以在 GitHub 慢或不通的网络里照样能装,DSH 的
|
|
43
|
+
安装对话框还能回退到国内镜像:
|
|
75
44
|
|
|
76
45
|
```powershell
|
|
77
46
|
dsh plugin --profile web add dsh-moli
|
|
78
47
|
```
|
|
79
48
|
|
|
80
|
-
|
|
49
|
+
**路线 2 —— 直接从仓库装。** 直接跟踪源码,需要 GitHub 可达:
|
|
81
50
|
|
|
82
51
|
```powershell
|
|
83
52
|
dsh plugin --profile web add github:27painter/dsh-moli
|
|
84
53
|
```
|
|
85
54
|
|
|
86
|
-
|
|
55
|
+
> [!IMPORTANT]
|
|
56
|
+
> **这个包只有插件,不含 Moli 引擎。** 它是 26 kB 的 JavaScript;`moli.exe` 是另一个约 101 MB 的 Rust
|
|
57
|
+
> 二进制、有自己的发布流程。装插件**不会**顺带装上 Moli,在你装引擎之前 `moli_fetch` 会一直报"引擎缺失"。
|
|
58
|
+
>
|
|
59
|
+
> **引擎没有 npm 包。** registry 上的 `moli` 和 `moli-cli` 属于无关项目,`@lexmount/moli` 并不存在。
|
|
60
|
+
> Moli 以预编译二进制形式发布在
|
|
61
|
+
> [GitHub Releases](https://github.com/lexmount/moli/releases/latest)——**不要靠猜包名去装引擎**。
|
|
87
62
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
同样方式装插件、重启,然后让它替你把 Moli 拉下来:
|
|
63
|
+
两种方式都要重启 DSH,然后自检并抓一个页面:
|
|
91
64
|
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
moli_probe action=install
|
|
65
|
+
```
|
|
66
|
+
moli_probe
|
|
67
|
+
moli_fetch url=https://example.com dump=markdown
|
|
96
68
|
```
|
|
97
69
|
|
|
98
|
-
|
|
99
|
-
实际执行的字节的 SHA256,而 `expectedSha256` 能把这份报告变成强制校验门(见
|
|
100
|
-
[校验下载](#校验下载))。安装**只在调用明确要求时**发生,使用 `moli_fetch` 永远不会触发它。
|
|
101
|
-
|
|
102
|
-
### 装进 desktop profile
|
|
103
|
-
|
|
104
|
-
`dsh plugin --profile desktop …` 会被拒绝——desktop profile 归 Electron 应用所有。直接改它的
|
|
105
|
-
`package.json`(加 `link:` 依赖**和** bundle 条目,再跑 `pnpm install`),或用应用内插件页
|
|
106
|
-
(侧边栏 →**插件**→**添加插件**),那条路径同样走 pnpm。
|
|
70
|
+
### 获取 Moli 引擎
|
|
107
71
|
|
|
108
|
-
|
|
109
|
-
bundle 会被**静默跳过**,只在 stderr 留一行 `skipping profile bundle …`。工具迟迟不出现时先找这行。
|
|
72
|
+
`moli_probe` 会报告引擎是否在场。如果不在,三种方式任选:
|
|
110
73
|
|
|
111
|
-
|
|
74
|
+
**1. 让插件替你装**——多路径下载,并报告实际执行字节的 SHA256:
|
|
112
75
|
|
|
113
|
-
|
|
76
|
+
```
|
|
77
|
+
moli_probe action=install
|
|
78
|
+
```
|
|
114
79
|
|
|
115
|
-
|
|
80
|
+
**2. 官方一行安装**(Moli 自己的文档命令):
|
|
116
81
|
|
|
117
82
|
```powershell
|
|
83
|
+
# Windows
|
|
118
84
|
powershell -ExecutionPolicy ByPass -c "irm https://github.com/lexmount/moli/releases/latest/download/moli-installer.ps1 | iex"
|
|
119
85
|
```
|
|
120
86
|
|
|
121
|
-
Linux / macOS:
|
|
122
|
-
|
|
123
87
|
```sh
|
|
88
|
+
# Linux / macOS
|
|
124
89
|
curl --proto '=https' --tlsv1.2 -fsSL https://github.com/lexmount/moli/releases/latest/download/moli-installer.sh | sh
|
|
125
90
|
```
|
|
126
91
|
|
|
127
|
-
|
|
92
|
+
**3. 直接下二进制**(不想跑安装器的话):
|
|
128
93
|
|
|
129
94
|
```powershell
|
|
130
|
-
# 从 releases
|
|
95
|
+
# 从 releases 页挑与你架构匹配的资产
|
|
131
96
|
curl.exe -L -o moli.zip https://github.com/lexmount/moli/releases/latest/download/moli-x86_64-pc-windows-msvc.zip
|
|
132
97
|
Expand-Archive moli.zip -DestinationPath "$env:LOCALAPPDATA\Moli" -Force
|
|
133
98
|
```
|
|
134
99
|
|
|
100
|
+
这些 `releases/latest/download/...` 链接始终指向最新发布,所以不用钉版本号也不会失效。
|
|
101
|
+
|
|
135
102
|
装完若位置不常规,把插件指过去:
|
|
136
103
|
|
|
137
104
|
```yaml
|
|
@@ -139,7 +106,7 @@ config:
|
|
|
139
106
|
exePath: 'C:\path\to\moli.exe'
|
|
140
107
|
```
|
|
141
108
|
|
|
142
|
-
|
|
109
|
+
#### 校验下载
|
|
143
110
|
|
|
144
111
|
Moli 的 README 没有记录任何校验和或签名,安装器也不发布校验和文件。**存在的是 GitHub 自己给每个资产的
|
|
145
112
|
`sha256` 摘要**,可以从 release API 读到:
|
|
@@ -162,7 +129,62 @@ moli-x86_64-pc-windows-msvc.zip 43.8 MB sha256:5247309837b6eaf6e73bfa18f2a8d8d
|
|
|
162
129
|
```
|
|
163
130
|
|
|
164
131
|
插件遵循同样的纪律:`moli_probe action=install` 会报告它实际执行的那份字节的 SHA256,而
|
|
165
|
-
`expectedSha256`
|
|
132
|
+
`expectedSha256` 能把这份报告变成强制校验门。它**不会**编造一个可信默认值——因为摘要只有在与发布页自己
|
|
133
|
+
的值比对时才有意义。
|
|
134
|
+
|
|
135
|
+
这是**验证过的性质,不是声明**:用插件自己的 `downloadInstaller` 下载 `v1.1.17` 的安装器,复现出的正是
|
|
136
|
+
GitHub 公布的那个摘要 `e002f7a6…964d`,从磁盘重新哈希也对得上。
|
|
137
|
+
|
|
138
|
+
### 装进 desktop profile
|
|
139
|
+
|
|
140
|
+
`dsh plugin --profile desktop …` 会被拒绝——desktop profile 归 Electron 应用所有。直接改它的
|
|
141
|
+
`package.json`,或用应用内插件页(侧边栏 →**插件**→**添加插件**),那条路径同样走 pnpm。
|
|
142
|
+
|
|
143
|
+
profile 插件需要两半都齐:依赖边(`dependencies`)+ `dsh.profile.bundles` 条目。缺一个 loader 就看不到
|
|
144
|
+
它。从本地目录安装的完整四步是:
|
|
145
|
+
|
|
146
|
+
1. 把本目录放到任意位置,例如 `D:\dsh_plugins\dsh-moli`。
|
|
147
|
+
2. 在该 profile 的 `package.json` 中加入两项:
|
|
148
|
+
- `dependencies`: `"dsh-moli": "link:D:/dsh_plugins/dsh-moli"`
|
|
149
|
+
- `dsh.profile.bundles`: `"dsh-moli"`
|
|
150
|
+
3. 在 profile 目录执行 `pnpm install`(生成 `node_modules/dsh-moli`)。
|
|
151
|
+
4. 重启 DSH。
|
|
152
|
+
|
|
153
|
+
无法解析的 bundle 会被**静默跳过**,只在 stderr 留一行 `skipping profile bundle …`。工具迟迟不出现时先找
|
|
154
|
+
这行。
|
|
155
|
+
|
|
156
|
+
## 用法
|
|
157
|
+
|
|
158
|
+
`moli_fetch` 参数:`url`(必填)、`dump`、`writeTo`、`eval`、`wait`、`waitSelector`、`delayMs`、
|
|
159
|
+
`timeoutMs`、`maxChars`、`headers`、`userAgent`、`layout`、`scrollbars`、`noJs`、`noCss`、
|
|
160
|
+
`resources`、`withFrames`、`insecureTls`、`profileDir`、`cookieFile`。
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
moli_fetch url=https://example.com dump=markdown # 省 token 的正文
|
|
164
|
+
moli_fetch url=https://example.com dump=semantic_tree_text # 带节点 id 的结构
|
|
165
|
+
moli_fetch url=https://example.com eval="document.title" # 取一个值
|
|
166
|
+
moli_fetch url=https://example.com dump=screenshot writeTo=/绝对路径/a.png
|
|
167
|
+
moli_fetch url=https://example.com dump=pdf writeTo=/绝对路径/a.pdf
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
截图与 PDF 必须给 `writeTo`;字节是原样落盘的,不会打印到输出里。
|
|
171
|
+
|
|
172
|
+
## 与 Moli 官方 agent skill 的关系
|
|
173
|
+
|
|
174
|
+
Moli 仓库自带官方 agent skill:[`moli-webfetch`](https://github.com/lexmount/moli/tree/main/skills/moli-webfetch)、
|
|
175
|
+
[`moli-websearch`](https://github.com/lexmount/moli/tree/main/skills/moli-websearch)、
|
|
176
|
+
[`moli-cdp-server`](https://github.com/lexmount/moli/tree/main/skills/moli-cdp-server),其 README 的快速开始
|
|
177
|
+
就是让 agent 去安装它们。如果你的 agent 能加载 skill,最省事的路就是直接用官方那套——上游维护,而且额外覆盖
|
|
178
|
+
网页搜索与 CDP 服务。
|
|
179
|
+
|
|
180
|
+
本插件的存在是因为它是另一种取舍,不是替代品:
|
|
181
|
+
|
|
182
|
+
- **常驻工具 schema,而非按需 skill。** 工具在 Host 启动时注册,模型每回合都能看到,不需要发现步骤。
|
|
183
|
+
- **针对 DSH 的失败处理。** 下面那三个坑(沙箱管道捕获、二进制被 UTF-16 破坏、`link:` 插件的裸包名解析)
|
|
184
|
+
以及沙箱/吊销/代理三类失败分类,都在这里解决了——因为它们本质是"DSH on Windows"的问题。
|
|
185
|
+
- **面更窄。** 只封装了 `fetch`;官方 skill 还覆盖网页搜索和 CDP 服务,本插件没有。
|
|
186
|
+
|
|
187
|
+
两者可以共存:想要上游覆盖就装 skill,想要能力始终对模型可见就留这个插件。
|
|
166
188
|
|
|
167
189
|
## 三个设计要点
|
|
168
190
|
|
|
@@ -192,39 +214,14 @@ moli-x86_64-pc-windows-msvc.zip 43.8 MB sha256:5247309837b6eaf6e73bfa18f2a8d8d
|
|
|
192
214
|
```
|
|
193
215
|
|
|
194
216
|
未设置 `exePath` 时探测顺序:`exePath` → 环境变量 `MOLI_BIN` → `%LOCALAPPDATA%\Moli\bin\moli.exe`
|
|
195
|
-
→ `%USERPROFILE%\.local\bin\moli.exe
|
|
196
|
-
|
|
197
|
-
## 安装
|
|
198
|
-
|
|
199
|
-
先装 Moli 本体——本插件只负责驱动它,不分发它。Windows 上:
|
|
200
|
-
|
|
201
|
-
```powershell
|
|
202
|
-
powershell -ExecutionPolicy ByPass -c "irm https://github.com/lexmount/moli/releases/latest/download/moli-installer.ps1 | iex"
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
(Linux/macOS 用对应的 `moli-installer.sh`,见 [Moli README](https://github.com/lexmount/moli#quick-start)。)
|
|
206
|
-
|
|
207
|
-
然后插件自身必须**同时**是 profile 依赖与已声明的 bundle,缺一个 loader 就看不到它:
|
|
208
|
-
|
|
209
|
-
1. 把本目录放到任意位置,例如 `D:\dsh_plugins\dsh-moli`。
|
|
210
|
-
2. 在该 profile 的 `package.json` 中加入:
|
|
211
|
-
- `dependencies`: `"dsh-moli": "link:D:/dsh_plugins/dsh-moli"`
|
|
212
|
-
- `dsh.profile.bundles`: `"dsh-moli"`
|
|
213
|
-
3. 在 profile 目录执行 `pnpm install`(生成 `node_modules/dsh-moli`)。
|
|
214
|
-
4. 重启 DSH。
|
|
215
|
-
|
|
216
|
-
注意:
|
|
217
|
-
|
|
218
|
-
- `dsh plugin --profile desktop …` 会被拒绝:desktop profile 归 Electron 应用所有。直接改它的
|
|
219
|
-
`package.json`,或用应用内插件页(侧边栏 →**插件**→**添加插件**),那条路径同样走 pnpm。
|
|
220
|
-
- bundle 无法解析或未通过兼容性检查时,loader 会**静默跳过**,只在 stderr 留一行
|
|
221
|
-
`skipping profile bundle …`。工具迟迟不出现时先找这行。
|
|
217
|
+
→ `%USERPROFILE%\.local\bin\moli.exe`,随后还会在 `%LOCALAPPDATA%\Moli` 内递归查找 `moli.exe`,
|
|
218
|
+
所以装在带版本号的子目录里也能找到。
|
|
222
219
|
|
|
223
220
|
## 已知限制
|
|
224
221
|
|
|
225
222
|
- **面向 Windows。** 开发与验证都在 Windows 上;可执行文件探测、文件描述符绕坑、Schannel 说明都
|
|
226
223
|
与 Windows 相关。移植到 POSIX 没有障碍,但未经验证。
|
|
227
|
-
- **不包含 Moli 本体。**
|
|
224
|
+
- **不包含 Moli 本体。** 需自行安装,或让 `moli_probe action=install` 替你拉取。
|
|
228
225
|
- **只封装了 `fetch`。** `moli serve`(CDP/WebDriver 服务器)与 `moli import`(会话导入)尚未做成工具。
|
|
229
226
|
- **不支持单次取消。** 引擎是同步执行的,被中断的回合无法中途终止抓取;已在进行的调用会跑完并
|
|
230
227
|
写出产物。
|
|
@@ -241,17 +238,24 @@ powershell -ExecutionPolicy ByPass -c "irm https://github.com/lexmount/moli/rele
|
|
|
241
238
|
- **部分网络下主机可达性会波动。** 开发机上观察到的现象:同一时刻,基于 curl 的客户端(moli)访问
|
|
242
239
|
`github.com` 超时,而 `git` over HTTPS 与系统浏览器几秒内就能通;`api.github.com` 正常而
|
|
243
240
|
`github.com` 不通。所以超时可能是暂时性的——重试,或设置 `proxy`。正因裸超时含义不唯一,它被
|
|
244
|
-
上报为 `possiblyUnreachable`
|
|
241
|
+
上报为 `possiblyUnreachable` 而不当作定论。安装动作的多路径回退与上面的手动命令正是为这种情况准备的。
|
|
245
242
|
|
|
246
243
|
## 验证情况
|
|
247
244
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
245
|
+
[`verify/`](verify/) 下有两个可直接对工作区运行的测试:
|
|
246
|
+
|
|
247
|
+
- `schema-verify.mjs` 用注册表自己的校验器检查工具定义,并带有断言"两种非法 schema 形状仍会被拒"的对照组。
|
|
248
|
+
- `install-verify.mjs` 用本地回环 HTTP 服务器驱动安装链路:路由顺序、被提供字节的 SHA256、校验不匹配时
|
|
249
|
+
拒绝执行、匹配时真正执行、以及全部路径失败的诊断。
|
|
250
|
+
|
|
251
|
+
此外,`lib/moli.js` 与工具层在 Windows 上对 Moli 1.1.16 做了端到端验证:注册、probe、Markdown 与 JSON
|
|
252
|
+
dump、`eval`(含针对 `-t` 参数位置的紧超时回归防护)、PNG 与 PDF 产物签名、截断、全部拒绝路径(二元 dump
|
|
253
|
+
缺 `writeTo`、非法 `dump`、非法 `wait`、目标目录不存在)、失败分类(不可达主机、HTTP 状态、沙箱 TLS 阻断、
|
|
254
|
+
吊销阻断)以及并发声明。被阻断主机的分类器用真实运行捕获的 stderr 文本做纯函数测试。
|
|
252
255
|
|
|
253
|
-
运行时也确认过:走本地代理抓取 JavaScript 渲染页面(GitHub 搜索)返回 14,560 字符 Markdown
|
|
254
|
-
|
|
256
|
+
运行时也确认过:走本地代理抓取 JavaScript 渲染页面(GitHub 搜索)返回 14,560 字符 Markdown,其中包含
|
|
257
|
+
30 处真实结果匹配。另有一个装了本插件的一次性 profile,组合其配置时既无 `JsonSchemaError` 也无被跳过的
|
|
258
|
+
bundle。
|
|
255
259
|
|
|
256
260
|
## 许可
|
|
257
261
|
|
package/index.js
CHANGED
|
@@ -30,49 +30,64 @@ const DEFAULTS = {
|
|
|
30
30
|
/**
|
|
31
31
|
* Parameter schema of `moli_fetch`.
|
|
32
32
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
33
|
+
* Both schema layers must be RAW JSON Schema here — object root, with `required`
|
|
34
|
+
* as an object-level array — because this plugin registers plain definitions with
|
|
35
|
+
* `ctx.tools.register` instead of going through `defineTool`.
|
|
36
|
+
*
|
|
37
|
+
* That choice is forced: `defineTool` lives in `@deepseek-ai/dsh-tools`, a bare
|
|
38
|
+
* specifier, and a profile plugin is loaded from its real path on disk, so the
|
|
39
|
+
* specifier does not resolve. `schemaOf` then projects `definition.parameters`
|
|
40
|
+
* verbatim to the provider — it is NOT converted — so a parameter left in the
|
|
41
|
+
* author DSL reaches the model without a root `type`, and the provider rejects the
|
|
42
|
+
* request with `schema must be a JSON Schema of 'type: "object"', got 'type: null'`.
|
|
43
|
+
*
|
|
44
|
+
* The two entry points disagree, which is why one shape cannot serve both:
|
|
45
|
+
* - a raw `output.schema` must use an object-level `required` array; a
|
|
46
|
+
* property-level `required: true` fails `assertSupportedJsonSchema` at registration
|
|
47
|
+
* - `defineTool` is the opposite: its DSL rejects an object-level `required` and
|
|
48
|
+
* expects `required: true` on each property instead
|
|
49
|
+
* Registering raw means the raw rules apply to parameters and outputs alike.
|
|
40
50
|
*/
|
|
41
51
|
const FETCH_PARAMETERS = {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
type: 'object',
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
required: ['url'],
|
|
55
|
+
properties: {
|
|
56
|
+
url: { type: 'string', description: 'Absolute http:// or https:// URL to fetch.' },
|
|
57
|
+
dump: {
|
|
58
|
+
type: 'string',
|
|
59
|
+
enum: ['html', 'markdown', 'json', 'semantic_tree', 'semantic_tree_text', 'screenshot', 'screenshot_full', 'pdf'],
|
|
60
|
+
description: 'Output format. Omit for rendered HTML. `markdown` and `semantic_tree_text` are the token-efficient choices for reading a page; `json` carries status and final_url; screenshot/pdf need writeTo.',
|
|
61
|
+
},
|
|
62
|
+
writeTo: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
description: 'Absolute path to save the output. Required for screenshot/pdf; optional for text dumps larger than maxChars.',
|
|
65
|
+
},
|
|
66
|
+
eval: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'JavaScript expression evaluated once the page is ready; its value is returned as text or JSON instead of the page.',
|
|
69
|
+
},
|
|
70
|
+
wait: {
|
|
71
|
+
type: 'string',
|
|
72
|
+
enum: ['domcontentloaded', 'load', 'networkidle', 'domstable', 'done'],
|
|
73
|
+
description: 'Readiness stage to wait for. Defaults to `done`.',
|
|
74
|
+
},
|
|
75
|
+
waitSelector: { type: 'string', description: 'Wait until this CSS selector matches.' },
|
|
76
|
+
delayMs: { type: 'integer', description: 'Extra milliseconds to wait after readiness.' },
|
|
77
|
+
timeoutMs: { type: 'integer', description: 'Total readiness deadline in milliseconds. Defaults to the plugin configuration.' },
|
|
78
|
+
maxChars: { type: 'integer', description: 'Truncate inline text output to this many characters. Defaults to the plugin configuration.' },
|
|
79
|
+
headers: { type: 'array', items: { type: 'string' }, description: 'Extra request headers, each as "Name: value".' },
|
|
80
|
+
userAgent: { type: 'string', description: 'Override the User-Agent.' },
|
|
81
|
+
layout: { type: 'boolean', description: 'Force the real layout renderer on. Implied by screenshot and pdf.' },
|
|
82
|
+
scrollbars: { type: 'boolean', description: 'Show native scrollbars in rendered output.' },
|
|
83
|
+
noJs: { type: 'boolean', description: 'Disable page-authored JavaScript.' },
|
|
84
|
+
noCss: { type: 'boolean', description: 'Disable page-authored CSS.' },
|
|
85
|
+
resources: { type: 'boolean', description: 'Also fetch images, fonts, audio, video, and text tracks.' },
|
|
86
|
+
withFrames: { type: 'boolean', description: 'Include subframes in the output.' },
|
|
87
|
+
insecureTls: { type: 'boolean', description: 'Skip TLS host verification. Use only for a known-broken local endpoint.' },
|
|
88
|
+
profileDir: { type: 'string', description: 'Moli profile directory carrying imported cookies or storage.' },
|
|
89
|
+
cookieFile: { type: 'string', description: 'Netscape/curl cookie-jar file to send.' },
|
|
60
90
|
},
|
|
61
|
-
waitSelector: { type: 'string', description: 'Wait until this CSS selector matches.' },
|
|
62
|
-
delayMs: { type: 'integer', description: 'Extra milliseconds to wait after readiness.' },
|
|
63
|
-
timeoutMs: { type: 'integer', description: 'Total readiness deadline in milliseconds. Defaults to the plugin configuration.' },
|
|
64
|
-
maxChars: { type: 'integer', description: 'Truncate inline text output to this many characters. Defaults to the plugin configuration.' },
|
|
65
|
-
headers: { type: 'array', items: { type: 'string' }, description: 'Extra request headers, each as "Name: value".' },
|
|
66
|
-
userAgent: { type: 'string', description: 'Override the User-Agent.' },
|
|
67
|
-
layout: { type: 'boolean', description: 'Force the real layout renderer on. Implied by screenshot and pdf.' },
|
|
68
|
-
scrollbars: { type: 'boolean', description: 'Show native scrollbars in rendered output.' },
|
|
69
|
-
noJs: { type: 'boolean', description: 'Disable page-authored JavaScript.' },
|
|
70
|
-
noCss: { type: 'boolean', description: 'Disable page-authored CSS.' },
|
|
71
|
-
resources: { type: 'boolean', description: 'Also fetch images, fonts, audio, video, and text tracks.' },
|
|
72
|
-
withFrames: { type: 'boolean', description: 'Include subframes in the output.' },
|
|
73
|
-
insecureTls: { type: 'boolean', description: 'Skip TLS host verification. Use only for a known-broken local endpoint.' },
|
|
74
|
-
profileDir: { type: 'string', description: 'Moli profile directory carrying imported cookies or storage.' },
|
|
75
|
-
cookieFile: { type: 'string', description: 'Netscape/curl cookie-jar file to send.' },
|
|
76
91
|
};
|
|
77
92
|
|
|
78
93
|
/**
|
|
@@ -266,14 +281,20 @@ export function apply(ctx, config) {
|
|
|
266
281
|
+ ' reports the executable and the SHA256 of the installer it ran. Use "install" only when moli_fetch'
|
|
267
282
|
+ ' reports that moli.exe is missing; it downloads and executes third-party code.',
|
|
268
283
|
parameters: {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
284
|
+
type: 'object',
|
|
285
|
+
additionalProperties: false,
|
|
286
|
+
// No required entries: every parameter is optional, and each execution path
|
|
287
|
+
// validates what it actually needs.
|
|
288
|
+
properties: {
|
|
289
|
+
action: {
|
|
290
|
+
type: 'string',
|
|
291
|
+
enum: ['probe', 'install'],
|
|
292
|
+
description: '`probe` (default) only inspects; `install` downloads and runs the official release installer.',
|
|
293
|
+
},
|
|
294
|
+
expectedSha256: {
|
|
295
|
+
type: 'string',
|
|
296
|
+
description: 'With action "install": abort unless the downloaded installer matches this SHA256.',
|
|
297
|
+
},
|
|
277
298
|
},
|
|
278
299
|
},
|
|
279
300
|
output: { schema: PROBE_OUTPUT_SCHEMA, render: renderProbe },
|
package/package.json
CHANGED