webforai 4.0.0 → 4.1.1
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 +74 -69
- package/dist/bin.js +1895 -74
- package/dist/cjs/extract-mdast.js +58 -0
- package/dist/cjs/extractors/index.js +5 -0
- package/dist/cjs/extractors/lib/block-features.js +465 -0
- package/dist/cjs/extractors/lib/block-model.generated.js +45 -0
- package/dist/cjs/extractors/lib/block-model.js +72 -0
- package/dist/cjs/extractors/lib/blocks.js +212 -0
- package/dist/cjs/extractors/lib/code-tabs.js +191 -0
- package/dist/cjs/extractors/lib/constants.js +1 -1
- package/dist/cjs/extractors/lib/layout-tables.js +123 -0
- package/dist/cjs/extractors/lib/sanitize.js +144 -28
- package/dist/cjs/extractors/lib/takumi-signal.js +76 -0
- package/dist/cjs/extractors/lib/ui-chrome.js +7 -0
- package/dist/cjs/extractors/presets/auto.js +3 -3
- package/dist/cjs/extractors/presets/kiwame.js +231 -0
- package/dist/cjs/extractors/presets/takumi.js +34 -3
- package/dist/cjs/html-to-markdown.js +58 -4
- package/dist/cjs/html-to-mdast.js +2 -2
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/mdast-handlers/custom-code-handler.js +16 -4
- package/dist/cjs/mdast-handlers/custom-div-handler.js +3 -3
- package/dist/cjs/mdast-handlers/custom-img-handler.js +10 -1
- package/dist/cjs/mdast-handlers/custom-table-handler.js +18 -1
- package/dist/cjs/mdast-handlers/table-cell-flatten.js +195 -0
- package/dist/cjs/mdast-handlers/twoslash.js +71 -0
- package/dist/cjs/metadata/index.js +4 -3
- package/dist/cjs/utils/hast-fast.js +1 -1
- package/dist/cjs/utils/parse-html.js +113 -0
- package/dist/cjs/utils/pre-text.js +104 -0
- package/dist/extract-mdast.js +58 -0
- package/dist/extractors/index.js +3 -0
- package/dist/extractors/lib/block-features.js +437 -0
- package/dist/extractors/lib/block-model.generated.js +21 -0
- package/dist/extractors/lib/block-model.js +48 -0
- package/dist/extractors/lib/blocks.js +185 -0
- package/dist/extractors/lib/code-tabs.js +168 -0
- package/dist/extractors/lib/constants.js +1 -1
- package/dist/extractors/lib/layout-tables.js +99 -0
- package/dist/extractors/lib/sanitize.js +142 -28
- package/dist/extractors/lib/takumi-signal.js +53 -0
- package/dist/extractors/lib/ui-chrome.js +5 -0
- package/dist/extractors/presets/auto.js +3 -3
- package/dist/extractors/presets/kiwame.js +206 -0
- package/dist/extractors/presets/takumi.js +34 -3
- package/dist/html-to-markdown.js +57 -4
- package/dist/html-to-mdast.js +2 -2
- package/dist/index.js +4 -0
- package/dist/mdast-handlers/custom-code-handler.js +15 -4
- package/dist/mdast-handlers/custom-div-handler.js +4 -4
- package/dist/mdast-handlers/custom-img-handler.js +10 -1
- package/dist/mdast-handlers/custom-table-handler.js +19 -2
- package/dist/mdast-handlers/table-cell-flatten.js +170 -0
- package/dist/mdast-handlers/twoslash.js +48 -0
- package/dist/metadata/index.js +4 -3
- package/dist/types/cli/commands/jobs/options.d.ts +2 -2
- package/dist/types/cli/commands/jobs/options.js.map +1 -1
- package/dist/types/cli/commands/webforai/options.js.map +1 -1
- package/dist/types/cli/commands/webforai/run.js.map +1 -1
- package/dist/types/cli/constants.d.ts +3 -1
- package/dist/types/cli/constants.js.map +1 -1
- package/dist/types/extract-mdast.js.map +1 -1
- package/dist/types/extractors/index.d.ts +1 -0
- package/dist/types/extractors/index.js.map +1 -1
- package/dist/types/extractors/lib/block-features.d.ts +43 -0
- package/dist/types/extractors/lib/block-features.js.map +1 -0
- package/dist/types/extractors/lib/block-model.d.ts +28 -0
- package/dist/types/extractors/lib/block-model.generated.d.ts +5 -0
- package/dist/types/extractors/lib/block-model.generated.js.map +1 -0
- package/dist/types/extractors/lib/block-model.js.map +1 -0
- package/dist/types/extractors/lib/blocks.d.ts +53 -0
- package/dist/types/extractors/lib/blocks.js.map +1 -0
- package/dist/types/extractors/lib/code-tabs.d.ts +30 -0
- package/dist/types/extractors/lib/code-tabs.js.map +1 -0
- package/dist/types/extractors/lib/constants.js.map +1 -1
- package/dist/types/extractors/lib/layout-tables.d.ts +17 -0
- package/dist/types/extractors/lib/layout-tables.js.map +1 -0
- package/dist/types/extractors/lib/sanitize.d.ts +33 -3
- package/dist/types/extractors/lib/sanitize.js.map +1 -1
- package/dist/types/extractors/lib/takumi-signal.d.ts +12 -0
- package/dist/types/extractors/lib/takumi-signal.js.map +1 -0
- package/dist/types/extractors/lib/ui-chrome.d.ts +8 -0
- package/dist/types/extractors/lib/ui-chrome.js.map +1 -1
- package/dist/types/extractors/presets/auto.d.ts +6 -1
- package/dist/types/extractors/presets/auto.js.map +1 -1
- package/dist/types/extractors/presets/kiwame.d.ts +31 -0
- package/dist/types/extractors/presets/kiwame.js.map +1 -0
- package/dist/types/extractors/presets/takumi.js.map +1 -1
- package/dist/types/html-to-markdown.d.ts +9 -0
- package/dist/types/html-to-markdown.js.map +1 -1
- package/dist/types/html-to-mdast.js.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/mdast-handlers/custom-code-handler.d.ts +7 -0
- package/dist/types/mdast-handlers/custom-code-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-div-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
- package/dist/types/mdast-handlers/table-cell-flatten.d.ts +18 -0
- package/dist/types/mdast-handlers/table-cell-flatten.js.map +1 -0
- package/dist/types/mdast-handlers/twoslash.d.ts +14 -0
- package/dist/types/mdast-handlers/twoslash.js.map +1 -0
- package/dist/types/metadata/index.js.map +1 -1
- package/dist/types/utils/hast-fast.d.ts +1 -1
- package/dist/types/utils/hast-fast.js.map +1 -1
- package/dist/types/utils/parse-html.d.ts +33 -0
- package/dist/types/utils/parse-html.js.map +1 -0
- package/dist/types/utils/pre-text.d.ts +12 -0
- package/dist/types/utils/pre-text.js.map +1 -0
- package/dist/utils/hast-fast.js +1 -1
- package/dist/utils/parse-html.js +87 -0
- package/dist/utils/pre-text.js +81 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -37,108 +37,113 @@ Everything is documented at **[webforai.dev](https://webforai.dev)**. Start from
|
|
|
37
37
|
| convert HTML in my own code (Node.js, browsers, Workers) | the `webforai` library | [Getting started](https://webforai.dev/getting-started) |
|
|
38
38
|
| get Markdown for a URL from the shell or an AI agent | the CLI, `npx webforai <url>` | [CLI](https://webforai.dev/cli) |
|
|
39
39
|
| call a hosted API that runs the browsers and proxies for me | webforai platform | [platform.webforai.dev](https://platform.webforai.dev) (sign-up, API keys, usage) · [platform docs](https://webforai.dev/platform) |
|
|
40
|
-
| run my own copy of that platform | [`apps/platform`](https://github.com/inaridiy/webforai/tree/main/apps/platform) | [Deploying your own instance](https://github.com/inaridiy/webforai/tree/main/apps/platform#deploying-your-own-instance) |
|
|
41
40
|
|
|
42
41
|
The library, the CLI and the typed platform client (`webforai/platform`) all ship in the one
|
|
43
|
-
`webforai` npm package
|
|
42
|
+
`webforai` npm package:
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
| Import | What it is |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| `webforai` | `htmlToMarkdown` and the conversion API |
|
|
47
|
+
| `webforai/platform` | typed client for the hosted platform |
|
|
48
|
+
| `webforai/loaders/fetch` | load HTML over `fetch` |
|
|
49
|
+
| `webforai/loaders/playwright` | load JavaScript-rendered pages (needs `playwright-core`) |
|
|
50
|
+
|
|
51
|
+
## Quick start
|
|
52
|
+
|
|
53
|
+
### CLI
|
|
46
54
|
|
|
47
55
|
```bash
|
|
48
56
|
# URL or local HTML file → Markdown on stdout (add -o out.md to write a file)
|
|
49
57
|
npx webforai@latest https://example.com/article
|
|
50
58
|
|
|
51
|
-
# machine-readable output
|
|
59
|
+
# machine-readable output
|
|
52
60
|
npx webforai@latest https://example.com --json
|
|
53
|
-
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
These commands use the [hosted platform](#platform-hosted-api) and need an API key:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx webforai@latest https://example.com --engine auto # renders JavaScript when needed
|
|
54
67
|
npx webforai@latest crawl https://docs.example.com -o docs --llms-txt # site → .md files + llms.txt
|
|
55
68
|
npx webforai@latest batch --file urls.txt -o pages # many URLs → one .md per page
|
|
56
|
-
npx webforai@latest skill --install # Agent Skill via `npx skills add`
|
|
57
69
|
```
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
import { htmlToMarkdown, htmlToMdast } from "webforai";
|
|
63
|
-
import { loadHtml } from "webforai/loaders/playwright";
|
|
71
|
+
To let an AI agent (Claude Code, Cursor, …) call the CLI, install it as an Agent Skill with
|
|
72
|
+
`npx webforai@latest skill --install`. Flags, exit codes and error output are covered in the
|
|
73
|
+
[CLI docs](https://webforai.dev/cli).
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
const url = "https://www.npmjs.com/package/webforai";
|
|
67
|
-
const html = await loadHtml(url);
|
|
75
|
+
### Library
|
|
68
76
|
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
```bash
|
|
78
|
+
npm i webforai
|
|
71
79
|
```
|
|
72
80
|
|
|
73
|
-
The CLI keeps Markdown/JSON on stdout and API failures on stderr, including the error code
|
|
74
|
-
and `retryAfter` when supplied; `invalid_api_key`, `payment_required` and `spend_cap_reached`
|
|
75
|
-
name the platform dashboard. `crawl` and `batch` run hosted jobs (API key required) and write
|
|
76
|
-
one Markdown file per page. `--engine` and `--region` select the platform loader; combining
|
|
77
|
-
them with an explicit local loader exits with usage error `2`. The interactive wizard applies
|
|
78
|
-
the same validation and honors `WEBFORAI_PLATFORM_URL`.
|
|
79
|
-
|
|
80
|
-
## What v3 changes
|
|
81
|
-
|
|
82
|
-
**Better extraction.** The main-content extractor scores candidate containers the way Readability
|
|
83
|
-
does — paragraph density, link density, class weighting, ancestor propagation — and adds signals
|
|
84
|
-
the 2010 heuristics predate: semantic markup (`<article>`, `<main>`, `role="main"`, schema.org
|
|
85
|
-
`articleBody`), the rendered geometry a browser loader can supply, and CJK-aware length
|
|
86
|
-
thresholds. Across a 60-page corpus of real sites, the share of output lines that were bare links
|
|
87
|
-
— the clearest sign navigation leaked in — dropped from 10.6% to 5.0%.
|
|
88
|
-
|
|
89
|
-
**Site adapters.** Pages that generic scoring cannot read are handled directly, matched by
|
|
90
|
-
hostname or by a platform fingerprint so self-hosted instances are covered too: GitHub, Stack
|
|
91
|
-
Overflow, npm, MDN, Zenn, Qiita, Medium, Substack, note, Hatena, WordPress, Wikipedia, Reddit,
|
|
92
|
-
YouTube, Hacker News, Docusaurus, VitePress, MkDocs, Read the Docs and GitBook. An adapter that
|
|
93
|
-
produces too little is ignored in favour of generic extraction, so a site redesign degrades
|
|
94
|
-
rather than breaks.
|
|
95
|
-
|
|
96
81
|
```ts
|
|
97
|
-
|
|
98
|
-
import { createAutoExtractor } from "webforai";
|
|
82
|
+
import { htmlToMarkdown } from "webforai";
|
|
99
83
|
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
84
|
+
const url = "https://example.com/article";
|
|
85
|
+
const html = await (await fetch(url)).text();
|
|
86
|
+
|
|
87
|
+
// url selects a site-specific adapter (GitHub, MDN, …) and fills metadata;
|
|
88
|
+
// baseUrl resolves relative links
|
|
89
|
+
const markdown = htmlToMarkdown(html, { url, baseUrl: url });
|
|
104
90
|
```
|
|
105
91
|
|
|
106
|
-
|
|
92
|
+
For pages that need JavaScript to render, load them with the Playwright loader
|
|
93
|
+
(`import { loadHtml } from "webforai/loaders/playwright"`, after `npx playwright-core install`);
|
|
94
|
+
see [Loaders](https://webforai.dev/docs/loaders).
|
|
107
95
|
|
|
108
|
-
|
|
109
|
-
import { htmlToMarkdownWithMetadata } from "webforai";
|
|
96
|
+
## What you get
|
|
110
97
|
|
|
111
|
-
|
|
112
|
-
|
|
98
|
+
- **Main content only.** Navigation, ads and footers are dropped. Pages are first matched
|
|
99
|
+
against site adapters; every other page goes through **kiwame**, a small built-in learned
|
|
100
|
+
classifier (plain TypeScript, no WASM, runs in a Cloudflare Worker). See
|
|
101
|
+
[How it works](https://webforai.dev/how-it-works) for the model, the benchmark and how to switch
|
|
102
|
+
back to the heuristic extractor.
|
|
103
|
+
- **Site adapters** for GitHub, Stack Overflow, npm, MDN, Zenn, Qiita, Medium, Substack, note,
|
|
104
|
+
Hatena, WordPress, Wikipedia, Reddit, YouTube, Hacker News, Docusaurus, VitePress, MkDocs,
|
|
105
|
+
Read the Docs and GitBook — matched by hostname or by a platform fingerprint, so self-hosted
|
|
106
|
+
instances are covered too. An adapter that produces too little falls back to generic
|
|
107
|
+
extraction, so a site redesign degrades rather than breaks.
|
|
108
|
+
- **Page metadata** as data or as YAML front matter:
|
|
113
109
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
```ts
|
|
111
|
+
import { htmlToMarkdown, htmlToMarkdownWithMetadata } from "webforai";
|
|
112
|
+
|
|
113
|
+
const { markdown, metadata } = htmlToMarkdownWithMetadata(html, { url });
|
|
114
|
+
// metadata: { title, author, published, siteName, canonicalUrl, lang, ... }
|
|
115
|
+
|
|
116
|
+
const withFrontmatter = htmlToMarkdown(html, { url, frontmatter: true });
|
|
117
|
+
```
|
|
117
118
|
|
|
118
|
-
**Markup
|
|
119
|
-
|
|
120
|
-
elements become real headings; superscripts and subscripts stay distinguishable; and definition
|
|
121
|
-
lists keep their term/definition pairing.
|
|
119
|
+
- **Markup that survives conversion**: lazily-loaded images, KaTeX/MathJax, code blocks and tabs,
|
|
120
|
+
tables, definition lists, and superscripts/subscripts.
|
|
122
121
|
|
|
123
|
-
|
|
122
|
+
Release notes and breaking changes are in the
|
|
123
|
+
[CHANGELOG](https://github.com/inaridiy/webforai/blob/main/packages/webforai/CHANGELOG.md).
|
|
124
124
|
|
|
125
125
|
## Platform (hosted API)
|
|
126
126
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
127
|
+
webforai platform runs the browsers, proxies and crawl queues for you and returns the same
|
|
128
|
+
Markdown as the library. It includes 1,000 free credits a month; sign up and create an API key
|
|
129
|
+
at [platform.webforai.dev](https://platform.webforai.dev).
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { createPlatformClient } from "webforai/platform";
|
|
133
|
+
|
|
134
|
+
const platform = createPlatformClient({ apiKey: process.env.WEBFORAI_API_KEY });
|
|
135
|
+
const page = await platform.scrape({ url: "https://example.com/article" });
|
|
136
|
+
page.markdown;
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
See the [platform docs](https://webforai.dev/platform) for the API reference and
|
|
140
|
+
[billing](https://webforai.dev/platform/billing).
|
|
136
141
|
|
|
137
142
|
## Support
|
|
138
143
|
|
|
139
144
|
- [GitHub Sponsors](https://github.com/sponsors/inaridiy)
|
|
140
|
-
- [inaridiy
|
|
145
|
+
- [@inaridiy on X](https://x.com/inaridiy)
|
|
141
146
|
|
|
142
147
|
## License
|
|
143
148
|
|
|
144
|
-
[Apache 2.0](/LICENSE)
|
|
149
|
+
[Apache 2.0](https://github.com/inaridiy/webforai/blob/main/LICENSE)
|