@v1nvn/readability 0.43.0 → 0.45.0
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 +3 -3
- package/package.json +7 -9
- package/src/cli.ts +134 -0
- package/src/config.ts +42 -0
- package/src/dev.ts +77 -0
- package/src/errors.ts +19 -0
- package/src/handler.ts +8 -0
- package/src/host-sampling.ts +86 -0
- package/src/index.ts +27 -0
- package/src/logger.ts +3 -0
- package/src/output/format.ts +132 -0
- package/src/pipeline/cell-text.ts +56 -0
- package/src/pipeline/context.ts +88 -0
- package/src/pipeline/dom.ts +23 -0
- package/src/pipeline/footnotes.ts +181 -0
- package/src/pipeline/math.ts +130 -0
- package/src/pipeline/normalize.ts +594 -0
- package/src/pipeline/readability.ts +36 -0
- package/src/pipeline/resolver.ts +143 -0
- package/src/pipeline/sanitize.ts +42 -0
- package/src/pipeline/tables.ts +286 -0
- package/src/pipeline/turndown.ts +191 -0
- package/src/pipeline/urls.ts +13 -0
- package/src/policy/chunk.ts +482 -0
- package/src/policy/diagnostics.ts +96 -0
- package/src/policy/explain.ts +182 -0
- package/src/policy/fallback.ts +110 -0
- package/src/policy/gating.ts +106 -0
- package/src/policy/grid-detector.ts +313 -0
- package/src/policy/identifiers.ts +75 -0
- package/src/policy/images.ts +64 -0
- package/src/policy/list-detector.ts +308 -0
- package/src/policy/lost-signal.ts +69 -0
- package/src/policy/markdown.ts +76 -0
- package/src/policy/metadata.ts +312 -0
- package/src/policy/outline-chains.ts +215 -0
- package/src/policy/outline.ts +89 -0
- package/src/policy/pagination.ts +104 -0
- package/src/policy/presets.ts +142 -0
- package/src/policy/section.ts +127 -0
- package/src/policy/selector-lint.ts +186 -0
- package/src/policy/sibling-scan.ts +99 -0
- package/src/policy/text.ts +36 -0
- package/src/policy/truncate.ts +59 -0
- package/src/preset-cache.ts +221 -0
- package/src/resources.ts +317 -0
- package/src/sampling.ts +74 -0
- package/src/server.ts +85 -0
- package/src/tools/chunk_text.ts +65 -0
- package/src/tools/explain.ts +299 -0
- package/src/tools/extract.ts +368 -0
- package/src/tools/extract_grid.ts +90 -0
- package/src/tools/extract_links.ts +138 -0
- package/src/tools/extract_list.ts +97 -0
- package/src/tools/extract_metadata.ts +102 -0
- package/src/tools/extract_section.ts +84 -0
- package/src/tools/extract_tables.ts +101 -0
- package/src/tools/html-source.ts +40 -0
- package/src/tools/html_to_markdown.ts +180 -0
- package/src/tools/outline.ts +77 -0
- package/src/tools/output-schema.ts +715 -0
- package/src/tools/schemas.ts +442 -0
- package/src/tools/suggest-preset.ts +708 -0
- package/src/types/jsdom.d.ts +15 -0
- package/src/types/turndown-plugin-gfm.d.ts +11 -0
- package/dist/assets/cli-BE_Ml3rh.js +0 -76
- package/dist/assets/cli-BE_Ml3rh.js.map +0 -1
- package/dist/assets/extract-Cyv5qfGN.js +0 -2880
- package/dist/assets/extract-Cyv5qfGN.js.map +0 -1
- package/dist/index.js +0 -2267
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare module 'jsdom' {
|
|
2
|
+
export interface JSDOMOptions {
|
|
3
|
+
readonly contentType?: string;
|
|
4
|
+
readonly pretendToBeVisual?: boolean;
|
|
5
|
+
readonly referrer?: string;
|
|
6
|
+
readonly runScripts?: 'dangerously' | 'outside-only';
|
|
7
|
+
readonly url?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class JSDOM {
|
|
11
|
+
public readonly window: typeof globalThis & Window;
|
|
12
|
+
public constructor(input?: string, options?: JSDOMOptions);
|
|
13
|
+
public serialize(): string;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
declare module 'turndown-plugin-gfm' {
|
|
2
|
+
import type TurndownService from 'turndown';
|
|
3
|
+
|
|
4
|
+
export type TurndownPlugin = (service: TurndownService) => void;
|
|
5
|
+
|
|
6
|
+
export const gfm: TurndownPlugin;
|
|
7
|
+
export const tables: TurndownPlugin;
|
|
8
|
+
export const strikethrough: TurndownPlugin;
|
|
9
|
+
export const taskListItems: TurndownPlugin;
|
|
10
|
+
export const highlightedCodeBlock: TurndownPlugin;
|
|
11
|
+
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { ft as describeError, ht as parseQuietly, j as readHtmlFile, mt as HelpRequested, t as extractArticleFromHtml } from "./extract-Cyv5qfGN.js";
|
|
2
|
-
import { Command, InvalidArgumentError, Option } from "commander";
|
|
3
|
-
//#region src/cli.ts
|
|
4
|
-
var FORMATS = [
|
|
5
|
-
"html",
|
|
6
|
-
"json",
|
|
7
|
-
"md"
|
|
8
|
-
];
|
|
9
|
-
function parseMaxChars(value) {
|
|
10
|
-
const n = Number(value);
|
|
11
|
-
if (!Number.isInteger(n)) throw new InvalidArgumentError("must be an integer");
|
|
12
|
-
return n;
|
|
13
|
-
}
|
|
14
|
-
function buildProgram() {
|
|
15
|
-
return new Command("readability extract").argument("[file]", "HTML file; stdin when omitted").addOption(new Option("--format <fmt>", "output format").choices(FORMATS).default("md")).option("--max-chars <n>", "truncate the output", parseMaxChars);
|
|
16
|
-
}
|
|
17
|
-
function parseArgs(argv) {
|
|
18
|
-
const program = buildProgram();
|
|
19
|
-
const parsed = parseQuietly(program, argv.slice(1));
|
|
20
|
-
if (parsed === void 0 || parsed instanceof HelpRequested) return parsed;
|
|
21
|
-
const { format, maxChars } = parsed.opts();
|
|
22
|
-
return {
|
|
23
|
-
file: parsed.args.at(0),
|
|
24
|
-
format,
|
|
25
|
-
maxChars
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
async function readHtml(file, stream) {
|
|
29
|
-
if (file !== void 0) return readHtmlFile(file);
|
|
30
|
-
const chunks = [];
|
|
31
|
-
for await (const chunk of stream) if (typeof chunk === "string") chunks.push(chunk);
|
|
32
|
-
else chunks.push(Buffer.from(chunk).toString("utf8"));
|
|
33
|
-
return chunks.join("");
|
|
34
|
-
}
|
|
35
|
-
function payloadText(result) {
|
|
36
|
-
const first = result.content.at(0);
|
|
37
|
-
return first !== void 0 && "text" in first ? first.text : "";
|
|
38
|
-
}
|
|
39
|
-
async function runCli(argv) {
|
|
40
|
-
if (argv[0] !== "extract") {
|
|
41
|
-
process.stderr.write(buildProgram().helpInformation());
|
|
42
|
-
return 2;
|
|
43
|
-
}
|
|
44
|
-
const parsed = parseArgs(argv);
|
|
45
|
-
if (parsed instanceof HelpRequested) {
|
|
46
|
-
process.stdout.write(`${parsed.command.helpInformation()}\n`);
|
|
47
|
-
return 0;
|
|
48
|
-
}
|
|
49
|
-
if (parsed === void 0) {
|
|
50
|
-
process.stderr.write(buildProgram().helpInformation());
|
|
51
|
-
return 2;
|
|
52
|
-
}
|
|
53
|
-
try {
|
|
54
|
-
const html = await readHtml(parsed.file, process.stdin);
|
|
55
|
-
const pipelineFormat = parsed.format === "html" ? "html" : "markdown";
|
|
56
|
-
const result = extractArticleFromHtml({
|
|
57
|
-
html,
|
|
58
|
-
format: pipelineFormat,
|
|
59
|
-
...parsed.maxChars !== void 0 ? { maxChars: parsed.maxChars } : {}
|
|
60
|
-
});
|
|
61
|
-
if (result.isError) {
|
|
62
|
-
process.stderr.write(`${payloadText(result)}\n`);
|
|
63
|
-
return 1;
|
|
64
|
-
}
|
|
65
|
-
if (parsed.format === "json") process.stdout.write(`${JSON.stringify(result.structuredContent, null, 2)}\n`);
|
|
66
|
-
else process.stdout.write(`${payloadText(result)}\n`);
|
|
67
|
-
return 0;
|
|
68
|
-
} catch (err) {
|
|
69
|
-
process.stderr.write(`${describeError(err)}\n`);
|
|
70
|
-
return 1;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
export { runCli };
|
|
75
|
-
|
|
76
|
-
//# sourceMappingURL=cli-BE_Ml3rh.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-BE_Ml3rh.js","names":[],"sources":["../../src/cli.ts"],"sourcesContent":["import { HelpRequested, parseQuietly } from '@v1nvn/agentic-core';\nimport { Command, InvalidArgumentError, Option } from 'commander';\n\nimport { describeError } from './errors.js';\nimport { extractArticleFromHtml } from './tools/extract.js';\nimport { readHtmlFile } from './tools/html-source.js';\n\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { Readable } from 'node:stream';\n\ntype CliFormat = 'html' | 'json' | 'md';\n\nexport interface ParsedArgs {\n readonly file: string | undefined;\n readonly format: CliFormat;\n readonly maxChars: number | undefined;\n}\n\nconst FORMATS: readonly CliFormat[] = ['html', 'json', 'md'];\n\nfunction parseMaxChars(value: string): number {\n const n = Number(value);\n if (!Number.isInteger(n)) {\n throw new InvalidArgumentError('must be an integer');\n }\n return n;\n}\n\nexport function buildProgram(): Command {\n return new Command('readability extract')\n .argument('[file]', 'HTML file; stdin when omitted')\n .addOption(\n new Option('--format <fmt>', 'output format')\n .choices(FORMATS)\n .default('md'),\n )\n .option('--max-chars <n>', 'truncate the output', parseMaxChars);\n}\n\nexport function parseArgs(\n argv: readonly string[],\n): HelpRequested | ParsedArgs | undefined {\n const program = buildProgram();\n const parsed = parseQuietly(program, argv.slice(1));\n if (parsed === undefined || parsed instanceof HelpRequested) {\n return parsed;\n }\n const { format, maxChars } = parsed.opts<{\n format: CliFormat;\n maxChars: number | undefined;\n }>();\n return { file: parsed.args.at(0), format, maxChars };\n}\n\n// The stream is injected rather than reading process.stdin directly so the\n// path is testable. Chunks may be Buffer (process.stdin) or string\n// (Readable.from), so both are handled.\nexport async function readHtml(\n file: string | undefined,\n stream: Readable,\n): Promise<string> {\n if (file !== undefined) {\n return readHtmlFile(file);\n }\n const chunks: string[] = [];\n for await (const chunk of stream) {\n if (typeof chunk === 'string') {\n chunks.push(chunk);\n } else {\n chunks.push(Buffer.from(chunk as Uint8Array).toString('utf8'));\n }\n }\n return chunks.join('');\n}\n\nfunction payloadText(result: CallToolResult): string {\n const first = result.content.at(0);\n return first !== undefined && 'text' in first ? first.text : '';\n}\n\nexport async function runCli(argv: readonly string[]): Promise<number> {\n if (argv[0] !== 'extract') {\n process.stderr.write(buildProgram().helpInformation());\n return 2;\n }\n\n const parsed = parseArgs(argv);\n if (parsed instanceof HelpRequested) {\n process.stdout.write(`${parsed.command.helpInformation()}\\n`);\n return 0;\n }\n if (parsed === undefined) {\n process.stderr.write(buildProgram().helpInformation());\n return 2;\n }\n\n try {\n const html = await readHtml(parsed.file, process.stdin);\n // json reuses the markdown pipeline; the structured object is serialized below.\n const pipelineFormat = parsed.format === 'html' ? 'html' : 'markdown';\n const result = extractArticleFromHtml({\n html,\n format: pipelineFormat,\n ...(parsed.maxChars !== undefined ? { maxChars: parsed.maxChars } : {}),\n });\n\n if (result.isError) {\n process.stderr.write(`${payloadText(result)}\\n`);\n return 1;\n }\n\n if (parsed.format === 'json') {\n process.stdout.write(\n `${JSON.stringify(result.structuredContent, null, 2)}\\n`,\n );\n } else {\n process.stdout.write(`${payloadText(result)}\\n`);\n }\n return 0;\n } catch (err) {\n process.stderr.write(`${describeError(err)}\\n`);\n return 1;\n }\n}\n"],"mappings":";;;AAkBA,IAAM,UAAgC;CAAC;CAAQ;CAAQ;AAAI;AAE3D,SAAS,cAAc,OAAuB;CAC5C,MAAM,IAAI,OAAO,KAAK;CACtB,IAAI,CAAC,OAAO,UAAU,CAAC,GACrB,MAAM,IAAI,qBAAqB,oBAAoB;CAErD,OAAO;AACT;AAEA,SAAgB,eAAwB;CACtC,OAAO,IAAI,QAAQ,qBAAqB,CAAC,CACtC,SAAS,UAAU,+BAA+B,CAAC,CACnD,UACC,IAAI,OAAO,kBAAkB,eAAe,CAAC,CAC1C,QAAQ,OAAO,CAAC,CAChB,QAAQ,IAAI,CACjB,CAAC,CACA,OAAO,mBAAmB,uBAAuB,aAAa;AACnE;AAEA,SAAgB,UACd,MACwC;CACxC,MAAM,UAAU,aAAa;CAC7B,MAAM,SAAS,aAAa,SAAS,KAAK,MAAM,CAAC,CAAC;CAClD,IAAI,WAAW,KAAA,KAAa,kBAAkB,eAC5C,OAAO;CAET,MAAM,EAAE,QAAQ,aAAa,OAAO,KAGjC;CACH,OAAO;EAAE,MAAM,OAAO,KAAK,GAAG,CAAC;EAAG;EAAQ;CAAS;AACrD;AAKA,eAAsB,SACpB,MACA,QACiB;CACjB,IAAI,SAAS,KAAA,GACX,OAAO,aAAa,IAAI;CAE1B,MAAM,SAAmB,CAAC;CAC1B,WAAW,MAAM,SAAS,QACxB,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,KAAK;MAEjB,OAAO,KAAK,OAAO,KAAK,KAAmB,CAAC,CAAC,SAAS,MAAM,CAAC;CAGjE,OAAO,OAAO,KAAK,EAAE;AACvB;AAEA,SAAS,YAAY,QAAgC;CACnD,MAAM,QAAQ,OAAO,QAAQ,GAAG,CAAC;CACjC,OAAO,UAAU,KAAA,KAAa,UAAU,QAAQ,MAAM,OAAO;AAC/D;AAEA,eAAsB,OAAO,MAA0C;CACrE,IAAI,KAAK,OAAO,WAAW;EACzB,QAAQ,OAAO,MAAM,aAAa,CAAC,CAAC,gBAAgB,CAAC;EACrD,OAAO;CACT;CAEA,MAAM,SAAS,UAAU,IAAI;CAC7B,IAAI,kBAAkB,eAAe;EACnC,QAAQ,OAAO,MAAM,GAAG,OAAO,QAAQ,gBAAgB,EAAE,GAAG;EAC5D,OAAO;CACT;CACA,IAAI,WAAW,KAAA,GAAW;EACxB,QAAQ,OAAO,MAAM,aAAa,CAAC,CAAC,gBAAgB,CAAC;EACrD,OAAO;CACT;CAEA,IAAI;EACF,MAAM,OAAO,MAAM,SAAS,OAAO,MAAM,QAAQ,KAAK;EAEtD,MAAM,iBAAiB,OAAO,WAAW,SAAS,SAAS;EAC3D,MAAM,SAAS,uBAAuB;GACpC;GACA,QAAQ;GACR,GAAI,OAAO,aAAa,KAAA,IAAY,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;EACvE,CAAC;EAED,IAAI,OAAO,SAAS;GAClB,QAAQ,OAAO,MAAM,GAAG,YAAY,MAAM,EAAE,GAAG;GAC/C,OAAO;EACT;EAEA,IAAI,OAAO,WAAW,QACpB,QAAQ,OAAO,MACb,GAAG,KAAK,UAAU,OAAO,mBAAmB,MAAM,CAAC,EAAE,GACvD;OAEA,QAAQ,OAAO,MAAM,GAAG,YAAY,MAAM,EAAE,GAAG;EAEjD,OAAO;CACT,SAAS,KAAK;EACZ,QAAQ,OAAO,MAAM,GAAG,cAAc,GAAG,EAAE,GAAG;EAC9C,OAAO;CACT;AACF"}
|