@remixmate/cli 0.9.25 → 0.9.27
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 +11 -4
- package/README.zh-CN.md +8 -4
- package/dist/handlers/gen-voice.d.ts +11 -1
- package/dist/handlers/gen-voice.js +17 -1
- package/dist/manifest.json +166 -10
- package/package.json +3 -1
- package/skills/gen-script/SKILL.md +1 -0
- package/skills/gen-script/scripts/gen_script.py +52 -3
- package/skills/gen-script/skill.json +5 -0
- package/skills/gen-script/version.json +1 -1
- package/skills/gen-voice/SKILL.md +5 -3
- package/skills/gen-voice/skill.json +3 -8
- package/skills/render-video/scripts/render_video.py +32 -0
- package/skills/render-video/version.json +1 -1
- package/skills/web-read/SKILL.md +146 -0
- package/skills/web-read/skill.json +131 -0
- package/skills/web-screenshot/scripts/_media_screenshot/__init__.py +2 -0
- package/skills/web-screenshot/scripts/_media_screenshot/js/extract_article.js +373 -0
- package/skills/web-screenshot/scripts/_media_screenshot/reader.py +245 -0
- package/skills/web-screenshot/scripts/_media_screenshot/urlguard.py +90 -0
- package/skills/web-screenshot/scripts/read_page.py +136 -0
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"voice_id": {
|
|
27
27
|
"type": "string",
|
|
28
|
-
"description": "Voice id. Default 'Chinese (Mandarin)_Male_Announcer'. When unsure, call with list_voices=true first to see what's available — do not invent ids."
|
|
28
|
+
"description": "Voice id. Default 'Chinese (Mandarin)_Male_Announcer'. When unsure, call with list_voices=true first to see what's available — do not invent ids, and do not declare a voice unavailable unless it is missing from that list."
|
|
29
29
|
},
|
|
30
30
|
"speed": {
|
|
31
31
|
"type": "number",
|
|
@@ -33,11 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"list_voices": {
|
|
35
35
|
"type": "boolean",
|
|
36
|
-
"description": "List available voices and exit"
|
|
37
|
-
},
|
|
38
|
-
"local": {
|
|
39
|
-
"type": "boolean",
|
|
40
|
-
"description": "Used together with list_voices=true: print the voice-resolver fallback catalog with language tags (no remote /voice/page call). Output is one '<id>\\t<lang>\\t<name>' line per voice."
|
|
36
|
+
"description": "List the available voices and exit. This queries the live voice service and is the authoritative catalog — one call is enough, and its absence from this list is the only evidence that a voice id is invalid."
|
|
41
37
|
},
|
|
42
38
|
"json_output": {
|
|
43
39
|
"type": "boolean",
|
|
@@ -56,8 +52,7 @@
|
|
|
56
52
|
],
|
|
57
53
|
"hidden": [
|
|
58
54
|
"json_output",
|
|
59
|
-
"list_voices"
|
|
60
|
-
"local"
|
|
55
|
+
"list_voices"
|
|
61
56
|
]
|
|
62
57
|
}
|
|
63
58
|
}
|
|
@@ -159,6 +159,22 @@ RESOLUTION_MAP = {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
|
|
162
|
+
def _narration_speed(narration: dict) -> Optional[float]:
|
|
163
|
+
"""Read a narration block's speech-rate multiplier, or None when unset.
|
|
164
|
+
|
|
165
|
+
Tolerant on purpose: the DSL is hand-editable, and a malformed speed must
|
|
166
|
+
not take down a render that would otherwise be fine — it falls back to the
|
|
167
|
+
voice's own pace. 0 and negatives are treated as unset for the same reason
|
|
168
|
+
ab-api does (`speed: 0` there means "follow the global setting").
|
|
169
|
+
"""
|
|
170
|
+
if not isinstance(narration, dict):
|
|
171
|
+
return None
|
|
172
|
+
raw = narration.get("speed")
|
|
173
|
+
if isinstance(raw, bool) or not isinstance(raw, (int, float)):
|
|
174
|
+
return None
|
|
175
|
+
return float(raw) if raw > 0 else None
|
|
176
|
+
|
|
177
|
+
|
|
162
178
|
def extract_narration_lines(narration: dict) -> Optional[tuple[list[str], int, list[Optional[float]]]]:
|
|
163
179
|
"""If narration uses the structured {intro, items, outro} form, return
|
|
164
180
|
(lines, intro_line_count, at_sec_list). `at_sec_list` is parallel to
|
|
@@ -621,6 +637,8 @@ def build_render_plan(dsl: dict, binding: dict) -> dict:
|
|
|
621
637
|
# so adjust_timeline_to_audio can later auto-derive highlightMap from
|
|
622
638
|
# per-line TTS timestamps.
|
|
623
639
|
dsl_assets_by_id = {a["assetId"]: a for a in dsl.get("assets", [])}
|
|
640
|
+
global_narration = (dsl.get("global") or {}).get("narration") or {}
|
|
641
|
+
global_speed = _narration_speed(global_narration)
|
|
624
642
|
for scene in dsl.get("scenes", []):
|
|
625
643
|
narration = (scene.get("audio") or {}).get("narration") or {}
|
|
626
644
|
ref = narration.get("assetRef")
|
|
@@ -628,6 +646,15 @@ def build_render_plan(dsl: dict, binding: dict) -> dict:
|
|
|
628
646
|
if not asset:
|
|
629
647
|
continue
|
|
630
648
|
payload = asset.setdefault("payload", {})
|
|
649
|
+
# Speech rate follows the same route as the narration text: single source
|
|
650
|
+
# of truth on the DSL, copied down here because resolve_asset_audio only
|
|
651
|
+
# ever sees the asset. Scene-level overrides global (mirrors the narration
|
|
652
|
+
# editor's "行级覆盖 > 全局"); neither set = gen-voice's own 1.0 default.
|
|
653
|
+
speed = _narration_speed(narration)
|
|
654
|
+
if speed is None:
|
|
655
|
+
speed = global_speed
|
|
656
|
+
if speed is not None:
|
|
657
|
+
payload["speed"] = speed
|
|
631
658
|
extracted = extract_narration_lines(narration)
|
|
632
659
|
if extracted:
|
|
633
660
|
lines, intro_lines, _ = extracted
|
|
@@ -862,6 +889,11 @@ def resolve_asset_audio(asset: dict, private_token: str, timeout: int) -> dict:
|
|
|
862
889
|
cmd.extend(["--text", tts_text, "--json-output"])
|
|
863
890
|
if payload.get("voiceId"):
|
|
864
891
|
cmd.extend(["--voice-id", payload["voiceId"]])
|
|
892
|
+
# Injected by build_render_plan from the DSL (scene narration > global).
|
|
893
|
+
# Absent = let gen-voice apply its own default rather than pinning 1.0 here.
|
|
894
|
+
speed = _narration_speed(payload)
|
|
895
|
+
if speed is not None:
|
|
896
|
+
cmd.extend(["--speed", str(speed)])
|
|
865
897
|
if private_token:
|
|
866
898
|
cmd.extend(["--priv-token", private_token])
|
|
867
899
|
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"skillName": "render-video",
|
|
3
3
|
"repoName": "agent-skill-media-maker",
|
|
4
4
|
"skillId": "473",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "V20",
|
|
6
6
|
"skillDescription": "Final-render skill: loads a persisted RenderPlan by `job_id` and drives the Remotion engine to produce the final video.\n\nUse this skill as soon as the user mentions any of these intents (after assets are already prepared):\n- Render the video, composite the video, export the video\n- Turn the prepared assets into the final clip\n- Render with Remotion\n\nPrerequisite: assets must already be generated via `prepare_video_assets`. This skill never resolves or regenerates assets — pass it a `job_id` from a previous `prepare_video_assets` call.\n\n⚠️ Stop-and-confirm gate: never call this skill until the user has explicitly confirmed the assets prepared by `prepare_video_assets`. If those assets were prepared in the current turn and the user has not replied since, stop and ask instead of rendering."
|
|
7
7
|
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-read
|
|
3
|
+
description: |
|
|
4
|
+
Web-page reading skill — open a URL in a headless browser (Playwright Python) and get back the page's **main text**: title, headings, paragraphs, lists, code blocks and tables, as Markdown / plain text / structured JSON.
|
|
5
|
+
Boilerplate (nav, sidebar, comments, ads, footer) is stripped by a Readability-style pass, and JS-rendered pages work because a real browser runs the page first.
|
|
6
|
+
|
|
7
|
+
Text only. For a still screenshot (`.png` / `.jpg`) use web-screenshot / `web_screenshot`; for a recording (`.mp4` / `.webm`) use web-record / `web_record`.
|
|
8
|
+
|
|
9
|
+
Use this skill immediately whenever the user asks for any of:
|
|
10
|
+
- Read this link / what does this page say / summarize this article
|
|
11
|
+
- Fetch page content, extract the article text, get the text of a URL
|
|
12
|
+
- Use a web page as source material for a script, outline, or video
|
|
13
|
+
- Read a README / docs page / changelog / blog post
|
|
14
|
+
- Pull the code samples or the table out of a page
|
|
15
|
+
- Check what is behind a link before acting on it
|
|
16
|
+
|
|
17
|
+
Even when the user does not say "read", any request that needs the *content* of a URL (rather than a picture of it) should route here.
|
|
18
|
+
triggers:
|
|
19
|
+
- Read this link / what does this page say / summarize this article
|
|
20
|
+
- Fetch page content, extract article text, get the text of a URL
|
|
21
|
+
- Use a web page as source material for a script or video
|
|
22
|
+
- Read a README / docs page / changelog / blog post
|
|
23
|
+
- Pull code samples or tables out of a page
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Web Read Skill (`web_read`)
|
|
27
|
+
|
|
28
|
+
Turns a URL into text. Entry script **`read_page.py`**, pure Python, prints to **stdout**.
|
|
29
|
+
|
|
30
|
+
> **Text only.** A screenshot is `web_screenshot`, a recording is `web_record`. Those two produce *files*; this one produces *content you can reason about*.
|
|
31
|
+
|
|
32
|
+
**Script location**: this skill has no `scripts/` of its own — it reuses `read_page.py` and the `_media_screenshot/` package from the web-screenshot directory (`skill.json`'s `entry.scriptPath` points relatively at `../web-screenshot/scripts/read_page.py`). Everywhere the commands below say **`<ReadScript>`**, substitute:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
<SkillDir>/../web-screenshot/scripts/read_page.py
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
> Path convention: read the system-injected `Base directory for this skill: <path>` as `<SkillDir>`. Never hardcode an absolute path.
|
|
39
|
+
|
|
40
|
+
## Prerequisites
|
|
41
|
+
|
|
42
|
+
- **Python 3.9+**
|
|
43
|
+
- **The `playwright` pip package + the chromium engine**: the first run **bootstraps automatically** (`pip install playwright` + `playwright install chromium`).
|
|
44
|
+
|
|
45
|
+
## Basic usage
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python3 <ReadScript> --url "https://example.com/article/123"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Prints a Markdown document: an `# title` line, a `site · author · date · url` line, then the body. A one-line extraction diagnostic (`blocks / chars / container`) goes to **stderr**, so piping stdout gives you clean text.
|
|
52
|
+
|
|
53
|
+
## Output formats
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Markdown (default) — headings, lists, ``` code fences, | tables |
|
|
57
|
+
python3 <ReadScript> --url "https://docs.python.org/3/tutorial/introduction.html"
|
|
58
|
+
|
|
59
|
+
# Plain text — no markup, for TTS or keyword work
|
|
60
|
+
python3 <ReadScript> --url "https://example.com/post" --format text
|
|
61
|
+
|
|
62
|
+
# JSON — typed blocks + metadata, for programmatic consumption
|
|
63
|
+
python3 <ReadScript> --url "https://example.com/post" --format json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The JSON shape is `{url, status, metadata{title,byline,siteName,publishedTime,description,lang}, container, charCount, blocks[]}`, where each block is one of `heading` / `paragraph` / `quote` / `code` / `list` / `table` / `image` / `rule`. JSON is **never truncated** (half a JSON document is not a JSON document) — cap it with `--selector` instead.
|
|
67
|
+
|
|
68
|
+
## Length control (read this before pointing it at a long page)
|
|
69
|
+
|
|
70
|
+
`--max-chars` defaults to **20000** and cuts on a block boundary, appending an explicit `[truncated] 已显示 N / M 字符` notice. Nothing is silently dropped.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Keep the whole document on disk, read a bounded slice now
|
|
74
|
+
python3 <ReadScript> \
|
|
75
|
+
--url "https://example.com/very-long-guide" \
|
|
76
|
+
--max-chars 8000 \
|
|
77
|
+
--output "./guide.md"
|
|
78
|
+
|
|
79
|
+
# No cap at all
|
|
80
|
+
python3 <ReadScript> --url "https://example.com/post" --max-chars 0
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## When the automatic extraction misses
|
|
84
|
+
|
|
85
|
+
The container is picked by paragraph-density scoring, which is right on ordinary article/docs/blog pages and can miss on unusual layouts. In order of what to try:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# 1. Content renders late (SPA): wait for the real element
|
|
89
|
+
python3 <ReadScript> --url "https://app.example.com/doc/1" --wait-for-selector "article.body"
|
|
90
|
+
|
|
91
|
+
# 2. Still short: give it a fixed settle window
|
|
92
|
+
python3 <ReadScript> --url "https://example.com/x" --settle-ms 3000
|
|
93
|
+
|
|
94
|
+
# 3. Wrong part of the page: name the container yourself
|
|
95
|
+
python3 <ReadScript> --url "https://example.com/x" --selector "#main-content"
|
|
96
|
+
|
|
97
|
+
# 4. Behind a login
|
|
98
|
+
python3 <ReadScript> --url "https://example.com/x" --storage-state "./auth.json"
|
|
99
|
+
python3 <ReadScript> --url "https://example.com/x" --cookies '[{"name":"sid","value":"…","domain":"example.com","path":"/"}]'
|
|
100
|
+
|
|
101
|
+
# 5. Site serves headless browsers a stub page
|
|
102
|
+
python3 <ReadScript> --url "https://example.com/x" --user-agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The stderr diagnostics tell you which case you are in: `⚠️ 整页有 N 字符,却只抽到 M` means the wrong container was chosen (→ `--selector`), while `⚠️ 这个页面几乎没有文本` means the page itself never rendered text (→ waiting, cookies, or user-agent).
|
|
106
|
+
|
|
107
|
+
## Links and images
|
|
108
|
+
|
|
109
|
+
Both are dropped by default, because they are noise for a summarize/rewrite task and they inflate the character budget.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Keep links as [text](url) — when you need to follow them
|
|
113
|
+
python3 <ReadScript> --url "https://example.com/index" --include-links
|
|
114
|
+
|
|
115
|
+
# Keep images as  — when harvesting illustration URLs
|
|
116
|
+
python3 <ReadScript> --url "https://example.com/post" --include-images
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Private addresses are refused
|
|
120
|
+
|
|
121
|
+
`web_read` hands page text to a model, so by default it refuses URLs that resolve to private / loopback / link-local addresses (`localhost`, `10.*`, `169.254.169.254`, …). Reading an intranet page or a local dev server on purpose:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
WEB_CAPTURE_ALLOW_PRIVATE_HOSTS=1 python3 <ReadScript> --url "http://localhost:5173/"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Full flag list
|
|
128
|
+
|
|
129
|
+
| Flag | Meaning |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `-u, --url` | Target URL (required, http/https) |
|
|
132
|
+
| `--format` | `markdown` (default) / `text` / `json` |
|
|
133
|
+
| `--max-chars` | stdout cap, block-aligned (default 20000, `0` = unlimited) |
|
|
134
|
+
| `--selector` | Extract only inside this CSS selector |
|
|
135
|
+
| `--include-links` / `--include-images` | Keep `[text](url)` / `` |
|
|
136
|
+
| `-o, --output` | Write the **full** text to a file (stdout stays capped) |
|
|
137
|
+
| `--settle-ms` | Extra wait before extracting |
|
|
138
|
+
| `--quiet` | Suppress the stderr diagnostic line |
|
|
139
|
+
| `-b, --browser` | `chromium` (default) / `firefox` / `webkit` |
|
|
140
|
+
| `--device`, `--viewport`, `--color-scheme`, `--user-agent` | Emulation |
|
|
141
|
+
| `--wait-for-selector`, `--wait-for-timeout`, `--timeout` | Waiting |
|
|
142
|
+
| `--storage-state`, `--cookies`, `--ignore-https-errors` | Session |
|
|
143
|
+
|
|
144
|
+
## Exit codes
|
|
145
|
+
|
|
146
|
+
`0` on success — including a page that legitimately has little text. Non-zero only for a refused URL, an unresolvable selector, or a navigation failure; each prints a single actionable line rather than a Python traceback.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "web-read",
|
|
3
|
+
"toolName": "web_read",
|
|
4
|
+
"tier": "tool",
|
|
5
|
+
"category": "consuming",
|
|
6
|
+
"title": "Web Page Reader",
|
|
7
|
+
"description": "Open any URL in a headless browser (Playwright Python) and return the page's MAIN TEXT — title, headings, paragraphs, lists, code blocks and tables — as Markdown, plain text, or structured JSON. Boilerplate (nav / sidebar / comments / ads / footer) is stripped by a Readability-style pass, and JS-rendered pages work because a real browser runs the page. This is the tool to use whenever you need to KNOW WHAT A PAGE SAYS: summarizing an article, pulling source material for a script, reading a README or docs page, checking what a link contains. It returns text, not pictures — for a screenshot (png/jpg) use web_screenshot, for a recording (mp4/webm) use web_record. Output is capped by max_chars (default 20000) and truncated on a block boundary; pass an `output` path to keep the full text on disk.",
|
|
8
|
+
"auth": "none",
|
|
9
|
+
"envVars": [
|
|
10
|
+
"WEB_CAPTURE_BROWSER",
|
|
11
|
+
"WEB_CAPTURE_ALLOW_PRIVATE_HOSTS",
|
|
12
|
+
"PLAYWRIGHT_BROWSERS_PATH"
|
|
13
|
+
],
|
|
14
|
+
"entry": {
|
|
15
|
+
"type": "python",
|
|
16
|
+
"scriptPath": "../web-screenshot/scripts/read_page.py"
|
|
17
|
+
},
|
|
18
|
+
"parameters": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"properties": {
|
|
21
|
+
"url": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Target page URL (http/https). Private / loopback / link-local addresses are refused unless WEB_CAPTURE_ALLOW_PRIVATE_HOSTS=1."
|
|
24
|
+
},
|
|
25
|
+
"format": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": ["markdown", "text", "json"],
|
|
28
|
+
"description": "markdown (default: keeps headings, lists, code fences, tables) | text (plain) | json (structured blocks + metadata, not truncated)"
|
|
29
|
+
},
|
|
30
|
+
"max_chars": {
|
|
31
|
+
"type": "number",
|
|
32
|
+
"description": "Cap on the printed text, cut at a block boundary with an explicit [truncated] notice (default 20000, 0 = unlimited). Raise it when you need the whole document; a very long page will otherwise fill your context."
|
|
33
|
+
},
|
|
34
|
+
"selector": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "Read only inside this CSS selector. Leave empty to auto-detect the article container — only reach for this when the auto-detected container was wrong."
|
|
37
|
+
},
|
|
38
|
+
"include_links": {
|
|
39
|
+
"type": "boolean",
|
|
40
|
+
"description": "Keep hyperlinks as [text](url) instead of plain text. Useful when you need to follow links from the page."
|
|
41
|
+
},
|
|
42
|
+
"include_images": {
|
|
43
|
+
"type": "boolean",
|
|
44
|
+
"description": "Keep images as . Useful for harvesting illustration URLs out of an article."
|
|
45
|
+
},
|
|
46
|
+
"output": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "Also write the FULL (untruncated) text to this local path. stdout still respects max_chars — use this when a long page must be kept for later steps."
|
|
49
|
+
},
|
|
50
|
+
"settle_ms": {
|
|
51
|
+
"type": "number",
|
|
52
|
+
"description": "Extra wait before extracting, in ms. Raise for pages that render content late."
|
|
53
|
+
},
|
|
54
|
+
"wait_for_selector": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Wait for this CSS selector before extracting (the reliable fix for JS-rendered content)"
|
|
57
|
+
},
|
|
58
|
+
"wait_for_timeout": {
|
|
59
|
+
"type": "number",
|
|
60
|
+
"description": "Fixed wait before extracting, in ms"
|
|
61
|
+
},
|
|
62
|
+
"device": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Device emulation name, e.g. 'iPhone 15 Pro' — some sites serve a leaner page to mobile"
|
|
65
|
+
},
|
|
66
|
+
"viewport": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Viewport as 'width,height', e.g. '1280,800'"
|
|
69
|
+
},
|
|
70
|
+
"color_scheme": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"enum": ["light", "dark", "no-preference"],
|
|
73
|
+
"description": "Emulate prefers-color-scheme"
|
|
74
|
+
},
|
|
75
|
+
"user_agent": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Override the User-Agent (try this when a site blocks headless browsers)"
|
|
78
|
+
},
|
|
79
|
+
"timeout": {
|
|
80
|
+
"type": "number",
|
|
81
|
+
"description": "Global Playwright action timeout in ms"
|
|
82
|
+
},
|
|
83
|
+
"ignore_https_errors": {
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"description": "Ignore HTTPS certificate errors"
|
|
86
|
+
},
|
|
87
|
+
"storage_state": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"description": "Path to a Playwright storageState JSON file (logged-in session)"
|
|
90
|
+
},
|
|
91
|
+
"cookies": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"description": "Playwright cookies as a JSON string or a path to a JSON file (top level is an array)"
|
|
94
|
+
},
|
|
95
|
+
"browser": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"enum": ["chromium", "firefox", "webkit"],
|
|
98
|
+
"description": "Browser engine (default chromium)"
|
|
99
|
+
},
|
|
100
|
+
"quiet": {
|
|
101
|
+
"type": "boolean",
|
|
102
|
+
"description": "Suppress the extraction diagnostics on stderr"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"required": ["url"]
|
|
106
|
+
},
|
|
107
|
+
"ui": {
|
|
108
|
+
"primary": ["url", "format", "max_chars"],
|
|
109
|
+
"advanced": [
|
|
110
|
+
"selector",
|
|
111
|
+
"include_links",
|
|
112
|
+
"include_images",
|
|
113
|
+
"wait_for_selector",
|
|
114
|
+
"settle_ms",
|
|
115
|
+
"device",
|
|
116
|
+
"viewport",
|
|
117
|
+
"color_scheme",
|
|
118
|
+
"timeout"
|
|
119
|
+
],
|
|
120
|
+
"hidden": [
|
|
121
|
+
"output",
|
|
122
|
+
"quiet",
|
|
123
|
+
"user_agent",
|
|
124
|
+
"ignore_https_errors",
|
|
125
|
+
"storage_state",
|
|
126
|
+
"cookies",
|
|
127
|
+
"browser",
|
|
128
|
+
"wait_for_timeout"
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -6,12 +6,14 @@ package is implementation detail.
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
from . import cli_args, scenes, template, trim
|
|
9
|
+
from .reader import do_read
|
|
9
10
|
from .recording import do_record
|
|
10
11
|
from .screenshot import do_screenshot
|
|
11
12
|
from .storyboard import do_storyboard
|
|
12
13
|
|
|
13
14
|
__all__ = [
|
|
14
15
|
"cli_args",
|
|
16
|
+
"do_read",
|
|
15
17
|
"do_record",
|
|
16
18
|
"do_screenshot",
|
|
17
19
|
"do_storyboard",
|