@zenalexa/unicli 0.225.1 → 0.225.3
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/AGENTS.md +3 -3
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/adapters/acl-anthology/papers.d.ts +16 -9
- package/dist/adapters/acl-anthology/papers.d.ts.map +1 -1
- package/dist/adapters/acl-anthology/papers.js +322 -58
- package/dist/adapters/acl-anthology/papers.js.map +1 -1
- package/dist/adapters/arxiv/papers.d.ts +22 -4
- package/dist/adapters/arxiv/papers.d.ts.map +1 -1
- package/dist/adapters/arxiv/papers.js +202 -4
- package/dist/adapters/arxiv/papers.js.map +1 -1
- package/dist/adapters/baidu-scholar/search.d.ts +15 -1
- package/dist/adapters/baidu-scholar/search.d.ts.map +1 -1
- package/dist/adapters/baidu-scholar/search.js +72 -8
- package/dist/adapters/baidu-scholar/search.js.map +1 -1
- package/dist/adapters/biorxiv/preprints.d.ts +9 -0
- package/dist/adapters/biorxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/biorxiv/preprints.js +78 -0
- package/dist/adapters/biorxiv/preprints.js.map +1 -0
- package/dist/adapters/cnki/search.d.ts +82 -0
- package/dist/adapters/cnki/search.d.ts.map +1 -0
- package/dist/adapters/cnki/search.js +236 -0
- package/dist/adapters/cnki/search.js.map +1 -0
- package/dist/adapters/cvf/papers.d.ts +12 -7
- package/dist/adapters/cvf/papers.d.ts.map +1 -1
- package/dist/adapters/cvf/papers.js +210 -27
- package/dist/adapters/cvf/papers.js.map +1 -1
- package/dist/adapters/dblp/publications.d.ts +12 -5
- package/dist/adapters/dblp/publications.d.ts.map +1 -1
- package/dist/adapters/dblp/publications.js +31 -8
- package/dist/adapters/dblp/publications.js.map +1 -1
- package/dist/adapters/google-scholar/search.d.ts +22 -1
- package/dist/adapters/google-scholar/search.d.ts.map +1 -1
- package/dist/adapters/google-scholar/search.js +129 -14
- package/dist/adapters/google-scholar/search.js.map +1 -1
- package/dist/adapters/hf/paper.d.ts +12 -3
- package/dist/adapters/hf/paper.d.ts.map +1 -1
- package/dist/adapters/hf/paper.js +65 -5
- package/dist/adapters/hf/paper.js.map +1 -1
- package/dist/adapters/medrxiv/preprints.d.ts +9 -0
- package/dist/adapters/medrxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/medrxiv/preprints.js +78 -0
- package/dist/adapters/medrxiv/preprints.js.map +1 -0
- package/dist/adapters/neurips/proceedings.d.ts +8 -7
- package/dist/adapters/neurips/proceedings.d.ts.map +1 -1
- package/dist/adapters/neurips/proceedings.js +209 -21
- package/dist/adapters/neurips/proceedings.js.map +1 -1
- package/dist/adapters/openalex/works.d.ts +21 -5
- package/dist/adapters/openalex/works.d.ts.map +1 -1
- package/dist/adapters/openalex/works.js +108 -8
- package/dist/adapters/openalex/works.js.map +1 -1
- package/dist/adapters/openreview/papers.d.ts +10 -4
- package/dist/adapters/openreview/papers.d.ts.map +1 -1
- package/dist/adapters/openreview/papers.js +351 -24
- package/dist/adapters/openreview/papers.js.map +1 -1
- package/dist/adapters/pmlr/proceedings.d.ts +6 -6
- package/dist/adapters/pmlr/proceedings.d.ts.map +1 -1
- package/dist/adapters/pmlr/proceedings.js +92 -12
- package/dist/adapters/pmlr/proceedings.js.map +1 -1
- package/dist/adapters/pubmed/articles.d.ts +8 -4
- package/dist/adapters/pubmed/articles.d.ts.map +1 -1
- package/dist/adapters/pubmed/articles.js +272 -39
- package/dist/adapters/pubmed/articles.js.map +1 -1
- package/dist/adapters/rxiv/preprints.d.ts +75 -0
- package/dist/adapters/rxiv/preprints.d.ts.map +1 -0
- package/dist/adapters/rxiv/preprints.js +651 -0
- package/dist/adapters/rxiv/preprints.js.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf-read.d.ts +49 -0
- package/dist/adapters/scholar-artifacts/pdf-read.d.ts.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf-read.js +204 -0
- package/dist/adapters/scholar-artifacts/pdf-read.js.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf.d.ts +16 -0
- package/dist/adapters/scholar-artifacts/pdf.d.ts.map +1 -0
- package/dist/adapters/scholar-artifacts/pdf.js +122 -0
- package/dist/adapters/scholar-artifacts/pdf.js.map +1 -0
- package/dist/adapters/semantic-scholar/papers.d.ts +6 -6
- package/dist/adapters/semantic-scholar/papers.d.ts.map +1 -1
- package/dist/adapters/semantic-scholar/papers.js +80 -6
- package/dist/adapters/semantic-scholar/papers.js.map +1 -1
- package/dist/adapters/unpaywall/works.d.ts +7 -7
- package/dist/adapters/unpaywall/works.d.ts.map +1 -1
- package/dist/adapters/unpaywall/works.js +104 -12
- package/dist/adapters/unpaywall/works.js.map +1 -1
- package/dist/adapters/wanfang/search.d.ts +14 -0
- package/dist/adapters/wanfang/search.d.ts.map +1 -1
- package/dist/adapters/wanfang/search.js +56 -7
- package/dist/adapters/wanfang/search.js.map +1 -1
- package/dist/browser/page.d.ts +2 -0
- package/dist/browser/page.d.ts.map +1 -1
- package/dist/browser/page.js +12 -0
- package/dist/browser/page.js.map +1 -1
- package/dist/browser/protocol.d.ts +6 -1
- package/dist/browser/protocol.d.ts.map +1 -1
- package/dist/browser/protocol.js.map +1 -1
- package/dist/commands/browser/actions.d.ts.map +1 -1
- package/dist/commands/browser/actions.js +487 -8
- package/dist/commands/browser/actions.js.map +1 -1
- package/dist/commands/compute.js +12 -1
- package/dist/commands/compute.js.map +1 -1
- package/dist/commands/schema.d.ts.map +1 -1
- package/dist/commands/schema.js +22 -0
- package/dist/commands/schema.js.map +1 -1
- package/dist/commands/scholar.d.ts +77 -5
- package/dist/commands/scholar.d.ts.map +1 -1
- package/dist/commands/scholar.js +2945 -83
- package/dist/commands/scholar.js.map +1 -1
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +14 -3
- package/dist/commands/search.js.map +1 -1
- package/dist/compute/contracts.d.ts +55 -0
- package/dist/compute/contracts.d.ts.map +1 -0
- package/dist/compute/contracts.js +487 -0
- package/dist/compute/contracts.js.map +1 -0
- package/dist/core/command-contract.d.ts.map +1 -1
- package/dist/core/command-contract.js +5 -0
- package/dist/core/command-contract.js.map +1 -1
- package/dist/core/schema-v2.d.ts +1 -0
- package/dist/core/schema-v2.d.ts.map +1 -1
- package/dist/core/schema-v2.js +1 -0
- package/dist/core/schema-v2.js.map +1 -1
- package/dist/discovery/aliases.d.ts +8 -1
- package/dist/discovery/aliases.d.ts.map +1 -1
- package/dist/discovery/aliases.js +333 -20
- package/dist/discovery/aliases.js.map +1 -1
- package/dist/discovery/core-catalog.d.ts +2 -0
- package/dist/discovery/core-catalog.d.ts.map +1 -1
- package/dist/discovery/core-catalog.js +525 -66
- package/dist/discovery/core-catalog.js.map +1 -1
- package/dist/discovery/intents.d.ts +1 -0
- package/dist/discovery/intents.d.ts.map +1 -1
- package/dist/discovery/intents.js +299 -2
- package/dist/discovery/intents.js.map +1 -1
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +3 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/discovery/macos-dynamic.d.ts +1 -0
- package/dist/discovery/macos-dynamic.d.ts.map +1 -1
- package/dist/discovery/macos-dynamic.js +20 -1
- package/dist/discovery/macos-dynamic.js.map +1 -1
- package/dist/discovery/search.d.ts.map +1 -1
- package/dist/discovery/search.js +12 -5
- package/dist/discovery/search.js.map +1 -1
- package/dist/engine/browser/evidence.d.ts +34 -1
- package/dist/engine/browser/evidence.d.ts.map +1 -1
- package/dist/engine/browser/evidence.js +141 -6
- package/dist/engine/browser/evidence.js.map +1 -1
- package/dist/engine/capability-policy.d.ts.map +1 -1
- package/dist/engine/capability-policy.js +30 -4
- package/dist/engine/capability-policy.js.map +1 -1
- package/dist/engine/kernel/stages.d.ts.map +1 -1
- package/dist/engine/kernel/stages.js +3 -0
- package/dist/engine/kernel/stages.js.map +1 -1
- package/dist/engine/operation-policy.d.ts +4 -1
- package/dist/engine/operation-policy.d.ts.map +1 -1
- package/dist/engine/operation-policy.js +23 -0
- package/dist/engine/operation-policy.js.map +1 -1
- package/dist/engine/steps/fetch-text.d.ts.map +1 -1
- package/dist/engine/steps/fetch-text.js +2 -2
- package/dist/engine/steps/fetch-text.js.map +1 -1
- package/dist/engine/steps/fetch.d.ts +1 -0
- package/dist/engine/steps/fetch.d.ts.map +1 -1
- package/dist/engine/steps/fetch.js +24 -4
- package/dist/engine/steps/fetch.js.map +1 -1
- package/dist/fast-path/handlers/discovery.d.ts +5 -5
- package/dist/fast-path/handlers/discovery.d.ts.map +1 -1
- package/dist/fast-path/handlers/discovery.js +61 -8
- package/dist/fast-path/handlers/discovery.js.map +1 -1
- package/dist/fast-path/manifest.d.ts +3 -0
- package/dist/fast-path/manifest.d.ts.map +1 -1
- package/dist/fast-path/manifest.js.map +1 -1
- package/dist/fast-path/policy.d.ts.map +1 -1
- package/dist/fast-path/policy.js +3 -0
- package/dist/fast-path/policy.js.map +1 -1
- package/dist/fast-path/render.d.ts +2 -0
- package/dist/fast-path/render.d.ts.map +1 -1
- package/dist/fast-path/render.js +9 -0
- package/dist/fast-path/render.js.map +1 -1
- package/dist/manifest-compact.txt +2 -2
- package/dist/manifest.json +6977 -1002
- package/dist/mcp/handler.d.ts +2 -16
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js.map +1 -1
- package/dist/mcp/http-transport.d.ts +7 -1
- package/dist/mcp/http-transport.d.ts.map +1 -1
- package/dist/mcp/http-transport.js +20 -1
- package/dist/mcp/http-transport.js.map +1 -1
- package/dist/mcp/jsonrpc.d.ts +27 -0
- package/dist/mcp/jsonrpc.d.ts.map +1 -0
- package/dist/mcp/jsonrpc.js +12 -0
- package/dist/mcp/jsonrpc.js.map +1 -0
- package/dist/mcp/origin-guard.d.ts +26 -0
- package/dist/mcp/origin-guard.d.ts.map +1 -0
- package/dist/mcp/origin-guard.js +42 -0
- package/dist/mcp/origin-guard.js.map +1 -0
- package/dist/mcp/profiles/computer-use.d.ts.map +1 -1
- package/dist/mcp/profiles/computer-use.js +30 -270
- package/dist/mcp/profiles/computer-use.js.map +1 -1
- package/dist/mcp/streamable-http/session.d.ts +4 -22
- package/dist/mcp/streamable-http/session.d.ts.map +1 -1
- package/dist/mcp/streamable-http/session.js +4 -24
- package/dist/mcp/streamable-http/session.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +74 -54
- package/dist/mcp/tools.js.map +1 -1
- package/dist/output/envelope.d.ts +2 -0
- package/dist/output/envelope.d.ts.map +1 -1
- package/dist/output/envelope.js.map +1 -1
- package/dist/output/error-map.d.ts +14 -0
- package/dist/output/error-map.d.ts.map +1 -1
- package/dist/output/error-map.js +20 -0
- package/dist/output/error-map.js.map +1 -1
- package/dist/registry.d.ts +2 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +1 -0
- package/dist/registry.js.map +1 -1
- package/dist/transport/cascade.d.ts.map +1 -1
- package/dist/transport/cascade.js +77 -5
- package/dist/transport/cascade.js.map +1 -1
- package/dist/transport/refs.d.ts +33 -1
- package/dist/transport/refs.d.ts.map +1 -1
- package/dist/transport/refs.js +40 -1
- package/dist/transport/refs.js.map +1 -1
- package/dist/types/scholarly.d.ts +19 -4
- package/dist/types/scholarly.d.ts.map +1 -1
- package/dist/types/scholarly.js +4 -4
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/skills/unicli/SKILL.md +1 -1
- package/skills/unicli-claude-code/SKILL.md +1 -1
- package/skills/unicli-hermes/SKILL.md +1 -1
- package/src/adapters/acl-anthology/papers.test.ts +111 -0
- package/src/adapters/acl-anthology/papers.ts +379 -71
- package/src/adapters/arxiv/papers.test.ts +46 -0
- package/src/adapters/arxiv/papers.ts +251 -4
- package/src/adapters/baidu-scholar/search.ts +74 -11
- package/src/adapters/biorxiv/preprints.ts +112 -0
- package/src/adapters/cnki/search.ts +357 -0
- package/src/adapters/cvf/papers.ts +260 -27
- package/src/adapters/dblp/publications.test.ts +9 -0
- package/src/adapters/dblp/publications.ts +31 -8
- package/src/adapters/defuddle/read.yaml +30 -0
- package/src/adapters/google-scholar/search.ts +165 -17
- package/src/adapters/hf/paper.test.ts +23 -0
- package/src/adapters/hf/paper.ts +89 -5
- package/src/adapters/hf/top.yaml +34 -2
- package/src/adapters/huggingface-papers/daily.yaml +37 -3
- package/src/adapters/huggingface-papers/search.yaml +43 -9
- package/src/adapters/jina/read.yaml +30 -0
- package/src/adapters/markdown-new/read.yaml +50 -0
- package/src/adapters/medrxiv/preprints.ts +112 -0
- package/src/adapters/neurips/proceedings.ts +266 -22
- package/src/adapters/ollama-cloud/fetch.yaml +39 -0
- package/src/adapters/ollama-cloud/search.yaml +43 -0
- package/src/adapters/openalex/works.test.ts +15 -4
- package/src/adapters/openalex/works.ts +136 -8
- package/src/adapters/openreview/papers.test.ts +31 -0
- package/src/adapters/openreview/papers.ts +407 -29
- package/src/adapters/pmlr/proceedings.ts +102 -12
- package/src/adapters/pubmed/articles.test.ts +88 -1
- package/src/adapters/pubmed/articles.ts +343 -44
- package/src/adapters/rxiv/preprints.test.ts +233 -0
- package/src/adapters/rxiv/preprints.ts +849 -0
- package/src/adapters/scholar-artifacts/pdf-read.ts +277 -0
- package/src/adapters/scholar-artifacts/pdf.ts +133 -0
- package/src/adapters/semantic-scholar/papers.ts +98 -6
- package/src/adapters/unpaywall/works.ts +141 -12
- package/src/adapters/wanfang/search.ts +57 -7
- package/src/adapters/cnki/search.yaml +0 -49
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @owner src::adapters::pmlr::proceedings
|
|
3
|
-
* @does Registers Proceedings of Machine Learning Research volume search using official citeproc.yaml metadata.
|
|
4
|
-
* @needs proceedings.mlr.press citeproc.yaml
|
|
5
|
-
* @feeds src/commands/scholar.ts via scholar.search, scholar.get, scholar.pdf, and scholar.venue
|
|
6
|
-
* @breaks Missing volume metadata
|
|
3
|
+
* @does Registers Proceedings of Machine Learning Research volume search, paper lookup, and PDF text reading using official citeproc.yaml metadata.
|
|
4
|
+
* @needs proceedings.mlr.press citeproc.yaml/PDF assets, js-yaml, src/adapters/scholar-artifacts/pdf-read.ts, src/registry.ts
|
|
5
|
+
* @feeds src/commands/scholar.ts via scholar.search, scholar.get, scholar.pdf, scholar.fulltext, and scholar.venue
|
|
6
|
+
* @breaks Missing volume metadata, citeproc/PDF drift, denied downloads, or missing pdftotext surfaces as explicit adapter errors.
|
|
7
7
|
* @invariants Volume is explicit; rows are filtered locally from official YAML metadata, not scraped from rendered cards.
|
|
8
|
-
* @side-effects HTTPS egress to proceedings.mlr.press
|
|
9
|
-
* @perf O(N) over one proceedings volume
|
|
8
|
+
* @side-effects HTTPS egress to proceedings.mlr.press/raw.githubusercontent.com; read writes one PDF artifact and executes pdftotext.
|
|
9
|
+
* @perf O(N) over one proceedings volume; read is O(PDF bytes + selected pages)
|
|
10
10
|
* @concurrency safe
|
|
11
11
|
* @test tests/unit/adapters/scholar-sources.test.ts
|
|
12
12
|
* @stability experimental
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import yaml from "js-yaml";
|
|
17
17
|
import { cli, Strategy } from "../../registry.js";
|
|
18
18
|
import type { ScholarlyWorkRecord } from "../../types/scholarly.js";
|
|
19
|
+
import { readScholarPdf } from "../scholar-artifacts/pdf-read.js";
|
|
19
20
|
|
|
20
21
|
interface PmlrEntry {
|
|
21
22
|
title?: unknown;
|
|
@@ -102,6 +103,44 @@ async function fetchVolume(volume: string): Promise<PmlrEntry[]> {
|
|
|
102
103
|
return parsePmlrCiteproc(await response.text());
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
async function findPmlrPaper(
|
|
107
|
+
volume: string,
|
|
108
|
+
id: string,
|
|
109
|
+
): Promise<ScholarlyWorkRecord> {
|
|
110
|
+
const row = (await fetchVolume(volume))
|
|
111
|
+
.map((entry) => mapPmlrEntry(entry, "pmlr"))
|
|
112
|
+
.find((entry) => entry.id === id);
|
|
113
|
+
if (!row) throw new Error(`No PMLR v${volume} paper found with id "${id}".`);
|
|
114
|
+
return row;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
async function readPmlrPaperPdf(
|
|
118
|
+
row: ScholarlyWorkRecord,
|
|
119
|
+
kwargs: Record<string, unknown>,
|
|
120
|
+
): Promise<Record<string, unknown>> {
|
|
121
|
+
if (!row.pdf_url) throw new Error(`PMLR paper ${row.id} has no PDF URL.`);
|
|
122
|
+
return readScholarPdf(
|
|
123
|
+
{
|
|
124
|
+
id: row.id,
|
|
125
|
+
title: row.title,
|
|
126
|
+
source_adapter: "pmlr",
|
|
127
|
+
source_url: row.source_url,
|
|
128
|
+
pdf_url: row.pdf_url,
|
|
129
|
+
output: kwargs.output,
|
|
130
|
+
filename: kwargs.filename,
|
|
131
|
+
"first-page": kwargs["first-page"] ?? kwargs.firstPage,
|
|
132
|
+
"last-page": kwargs["last-page"] ?? kwargs.lastPage,
|
|
133
|
+
"max-chars": kwargs["max-chars"] ?? kwargs.maxChars,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
site: "pmlr",
|
|
137
|
+
command: "read",
|
|
138
|
+
defaultOutput: "./pmlr-downloads",
|
|
139
|
+
userAgent: "unicli-pmlr/1.0 (https://github.com/olo-dot-io/Uni-CLI)",
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
105
144
|
cli({
|
|
106
145
|
site: "pmlr",
|
|
107
146
|
name: "search",
|
|
@@ -157,11 +196,62 @@ cli({
|
|
|
157
196
|
const id = String(kwargs.id ?? kwargs.ref ?? "").trim();
|
|
158
197
|
if (!id) throw new Error("pmlr paper id is required.");
|
|
159
198
|
const volume = requireVolume(kwargs.volume);
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
199
|
+
return [await findPmlrPaper(volume, id)];
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
cli({
|
|
204
|
+
site: "pmlr",
|
|
205
|
+
name: "read",
|
|
206
|
+
description:
|
|
207
|
+
"Download a PMLR paper PDF by id inside a proceedings volume and extract text",
|
|
208
|
+
domain: "proceedings.mlr.press",
|
|
209
|
+
strategy: Strategy.PUBLIC,
|
|
210
|
+
args: [
|
|
211
|
+
{ name: "id", type: "str", required: true, positional: true },
|
|
212
|
+
{ name: "volume", type: "str", default: "235" },
|
|
213
|
+
{
|
|
214
|
+
name: "output",
|
|
215
|
+
type: "str",
|
|
216
|
+
default: "./pmlr-downloads",
|
|
217
|
+
description: "Output directory for the downloaded PDF",
|
|
218
|
+
"x-unicli-kind": "path",
|
|
219
|
+
},
|
|
220
|
+
{ name: "filename", type: "str", description: "Output PDF filename" },
|
|
221
|
+
{ name: "first-page", type: "int", default: 1, description: "First page" },
|
|
222
|
+
{ name: "last-page", type: "int", default: 20, description: "Last page" },
|
|
223
|
+
{
|
|
224
|
+
name: "max-chars",
|
|
225
|
+
type: "int",
|
|
226
|
+
default: 40000,
|
|
227
|
+
description: "Maximum extracted text characters",
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
columns: [
|
|
231
|
+
"id",
|
|
232
|
+
"title",
|
|
233
|
+
"source_adapter",
|
|
234
|
+
"source_url",
|
|
235
|
+
"pdf_url",
|
|
236
|
+
"path",
|
|
237
|
+
"text_source",
|
|
238
|
+
"text",
|
|
239
|
+
"text_chars",
|
|
240
|
+
"text_truncated",
|
|
241
|
+
],
|
|
242
|
+
capabilities: [
|
|
243
|
+
"http.fetch",
|
|
244
|
+
"http.download",
|
|
245
|
+
"subprocess.exec",
|
|
246
|
+
"scholar.fulltext",
|
|
247
|
+
"scholar.pdf",
|
|
248
|
+
],
|
|
249
|
+
executables: ["pdftotext"],
|
|
250
|
+
minimum_capability: "subprocess.exec",
|
|
251
|
+
func: async (_page, kwargs) => {
|
|
252
|
+
const id = String(kwargs.id ?? kwargs.ref ?? "").trim();
|
|
253
|
+
if (!id) throw new Error("pmlr paper id is required.");
|
|
254
|
+
const volume = requireVolume(kwargs.volume);
|
|
255
|
+
return [await readPmlrPaperPdf(await findPmlrPaper(volume, id), kwargs)];
|
|
166
256
|
},
|
|
167
257
|
});
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
import {
|
|
3
|
+
mapPmcFullTextRow,
|
|
4
|
+
mapPubMedArticleRecord,
|
|
3
5
|
mapPubMedArticleRows,
|
|
4
6
|
mapPubMedSummaryRows,
|
|
7
|
+
normalizePmcId,
|
|
5
8
|
requirePmid,
|
|
6
9
|
requirePubMedLimit,
|
|
10
|
+
requirePubMedMaxChars,
|
|
7
11
|
requirePubMedText,
|
|
8
12
|
} from "./articles.js";
|
|
9
13
|
|
|
@@ -13,9 +17,15 @@ describe("pubmed agent-facing commands", () => {
|
|
|
13
17
|
expect(() => requirePubMedText("", "query")).toThrow("cannot be empty");
|
|
14
18
|
expect(requirePmid("37780221")).toBe("37780221");
|
|
15
19
|
expect(() => requirePmid("PMID:1")).toThrow("numeric PMID");
|
|
20
|
+
expect(normalizePmcId("8938715")).toBe("PMC8938715");
|
|
21
|
+
expect(normalizePmcId("PMC8938715")).toBe("PMC8938715");
|
|
22
|
+
expect(() => normalizePmcId("pmc:8938715")).toThrow("not valid");
|
|
16
23
|
expect(requirePubMedLimit(undefined)).toBe(20);
|
|
17
24
|
expect(requirePubMedLimit("100")).toBe(100);
|
|
18
25
|
expect(() => requirePubMedLimit("0")).toThrow("pubmed limit must");
|
|
26
|
+
expect(requirePubMedMaxChars(undefined)).toBe(40000);
|
|
27
|
+
expect(requirePubMedMaxChars("1000")).toBe(1000);
|
|
28
|
+
expect(() => requirePubMedMaxChars("999")).toThrow("max-chars");
|
|
19
29
|
});
|
|
20
30
|
|
|
21
31
|
it("maps PubMed summary rows in PMID order", () => {
|
|
@@ -34,7 +44,10 @@ describe("pubmed agent-facing commands", () => {
|
|
|
34
44
|
source: "Journal",
|
|
35
45
|
pubdate: "2026 May",
|
|
36
46
|
pubtype: ["Journal Article"],
|
|
37
|
-
articleids: [
|
|
47
|
+
articleids: [
|
|
48
|
+
{ idtype: "doi", value: "10.1/example" },
|
|
49
|
+
{ idtype: "pmc", value: "PMC123456" },
|
|
50
|
+
],
|
|
38
51
|
},
|
|
39
52
|
{
|
|
40
53
|
uid: "1",
|
|
@@ -51,6 +64,7 @@ describe("pubmed agent-facing commands", () => {
|
|
|
51
64
|
).toMatchObject([
|
|
52
65
|
{
|
|
53
66
|
rank: 1,
|
|
67
|
+
id: "1",
|
|
54
68
|
pmid: "1",
|
|
55
69
|
title: "First",
|
|
56
70
|
authors: "Hopper G",
|
|
@@ -59,9 +73,12 @@ describe("pubmed agent-facing commands", () => {
|
|
|
59
73
|
},
|
|
60
74
|
{
|
|
61
75
|
rank: 2,
|
|
76
|
+
id: "2",
|
|
62
77
|
pmid: "2",
|
|
63
78
|
authors: "Ada, Grace, Linus, et al.",
|
|
64
79
|
doi: "10.1/example",
|
|
80
|
+
pmc_id: "PMC123456",
|
|
81
|
+
source_adapter: "pubmed",
|
|
65
82
|
},
|
|
66
83
|
]);
|
|
67
84
|
});
|
|
@@ -77,12 +94,14 @@ describe("pubmed agent-facing commands", () => {
|
|
|
77
94
|
<PubDate><Year>2026</Year></PubDate>
|
|
78
95
|
<PublicationType>Journal Article</PublicationType>
|
|
79
96
|
<Language>eng</Language>
|
|
97
|
+
<ArticleId IdType="pmc">PMC123456</ArticleId>
|
|
80
98
|
<ArticleId IdType="doi">10.1/example</ArticleId>
|
|
81
99
|
</PubmedArticle>
|
|
82
100
|
`,
|
|
83
101
|
"123",
|
|
84
102
|
);
|
|
85
103
|
expect(rows).toContainEqual({ field: "PMID", value: "123" });
|
|
104
|
+
expect(rows).toContainEqual({ field: "PMCID", value: "PMC123456" });
|
|
86
105
|
expect(rows).toContainEqual({ field: "Title", value: "Test & Treat" });
|
|
87
106
|
expect(rows).toContainEqual({ field: "DOI", value: "10.1/example" });
|
|
88
107
|
expect(rows).toContainEqual({
|
|
@@ -93,4 +112,72 @@ describe("pubmed agent-facing commands", () => {
|
|
|
93
112
|
"did not include a title",
|
|
94
113
|
);
|
|
95
114
|
});
|
|
115
|
+
|
|
116
|
+
it("maps normalized PubMed article metadata rows", () => {
|
|
117
|
+
const row = mapPubMedArticleRecord(
|
|
118
|
+
`
|
|
119
|
+
<PubmedArticle>
|
|
120
|
+
<ArticleTitle>Normalized Article</ArticleTitle>
|
|
121
|
+
<Abstract><AbstractText>Abstract text</AbstractText></Abstract>
|
|
122
|
+
<Author><LastName>Ada</LastName><Initials>L</Initials></Author>
|
|
123
|
+
<Journal><Title>Journal</Title></Journal>
|
|
124
|
+
<PubDate><Year>2026</Year></PubDate>
|
|
125
|
+
<PublicationType>Journal Article</PublicationType>
|
|
126
|
+
<Language>eng</Language>
|
|
127
|
+
<ArticleId IdType="pmc">PMC123456</ArticleId>
|
|
128
|
+
<ArticleId IdType="doi">10.1/example</ArticleId>
|
|
129
|
+
</PubmedArticle>
|
|
130
|
+
`,
|
|
131
|
+
"123",
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
expect(row).toMatchObject({
|
|
135
|
+
id: "123",
|
|
136
|
+
pmid: "123",
|
|
137
|
+
title: "Normalized Article",
|
|
138
|
+
authors: ["Ada L"],
|
|
139
|
+
doi: "10.1/example",
|
|
140
|
+
pmc_id: "PMC123456",
|
|
141
|
+
source_adapter: "pubmed",
|
|
142
|
+
source_url: "https://pubmed.ncbi.nlm.nih.gov/123/",
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("maps PMC JATS XML into source-direct full text", () => {
|
|
147
|
+
const row = mapPmcFullTextRow(
|
|
148
|
+
`
|
|
149
|
+
<article>
|
|
150
|
+
<front>
|
|
151
|
+
<article-meta>
|
|
152
|
+
<article-id pub-id-type="pmcid">PMC123456</article-id>
|
|
153
|
+
<article-id pub-id-type="pmid">123</article-id>
|
|
154
|
+
<article-id pub-id-type="doi">10.1/example</article-id>
|
|
155
|
+
<title-group><article-title>Full Text Article</article-title></title-group>
|
|
156
|
+
</article-meta>
|
|
157
|
+
</front>
|
|
158
|
+
<abstract><p>Abstract paragraph.</p></abstract>
|
|
159
|
+
<body>
|
|
160
|
+
<sec><title>Introduction</title><p>First body paragraph.</p></sec>
|
|
161
|
+
<sec><title>Methods</title><p>Second body paragraph.</p></sec>
|
|
162
|
+
</body>
|
|
163
|
+
</article>
|
|
164
|
+
`,
|
|
165
|
+
"PMC123456",
|
|
166
|
+
1000,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
expect(row).toMatchObject({
|
|
170
|
+
id: "123",
|
|
171
|
+
title: "Full Text Article",
|
|
172
|
+
pmid: "123",
|
|
173
|
+
pmc_id: "PMC123456",
|
|
174
|
+
doi: "10.1/example",
|
|
175
|
+
source_adapter: "pubmed",
|
|
176
|
+
source_url: "https://pmc.ncbi.nlm.nih.gov/articles/PMC123456/",
|
|
177
|
+
text_truncated: false,
|
|
178
|
+
});
|
|
179
|
+
expect(row.text).toContain("## Abstract");
|
|
180
|
+
expect(row.text).toContain("## Introduction");
|
|
181
|
+
expect(row.text).toContain("First body paragraph.");
|
|
182
|
+
});
|
|
96
183
|
});
|