paper-search-cli 0.3.0 → 0.3.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.
Files changed (39) hide show
  1. package/README.md +10 -8
  2. package/README.zh.md +10 -8
  3. package/dist/cli.js +4 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/core/capabilityProfile.d.ts +1 -1
  6. package/dist/core/capabilityProfile.d.ts.map +1 -1
  7. package/dist/core/capabilityProfile.js +14 -0
  8. package/dist/core/capabilityProfile.js.map +1 -1
  9. package/dist/core/handleToolCall.d.ts.map +1 -1
  10. package/dist/core/handleToolCall.js +33 -0
  11. package/dist/core/handleToolCall.js.map +1 -1
  12. package/dist/core/schemas.d.ts +27 -1
  13. package/dist/core/schemas.d.ts.map +1 -1
  14. package/dist/core/schemas.js +14 -0
  15. package/dist/core/schemas.js.map +1 -1
  16. package/dist/core/tools.d.ts.map +1 -1
  17. package/dist/core/tools.js +54 -0
  18. package/dist/core/tools.js.map +1 -1
  19. package/dist/platforms/BioRxivSearcher.d.ts.map +1 -1
  20. package/dist/platforms/BioRxivSearcher.js +40 -21
  21. package/dist/platforms/BioRxivSearcher.js.map +1 -1
  22. package/dist/platforms/GoogleScholarSearcher.d.ts.map +1 -1
  23. package/dist/platforms/GoogleScholarSearcher.js +3 -2
  24. package/dist/platforms/GoogleScholarSearcher.js.map +1 -1
  25. package/dist/services/CitationService.d.ts.map +1 -1
  26. package/dist/services/CitationService.js +8 -2
  27. package/dist/services/CitationService.js.map +1 -1
  28. package/dist/services/OpenAccessFallbackService.d.ts +20 -0
  29. package/dist/services/OpenAccessFallbackService.d.ts.map +1 -1
  30. package/dist/services/OpenAccessFallbackService.js +95 -72
  31. package/dist/services/OpenAccessFallbackService.js.map +1 -1
  32. package/dist/utils/RateLimiter.d.ts.map +1 -1
  33. package/dist/utils/RateLimiter.js +7 -0
  34. package/dist/utils/RateLimiter.js.map +1 -1
  35. package/package.json +1 -1
  36. package/skills/paper-search/SKILL.md +4 -2
  37. package/skills/paper-search/references/capability-routing.md +15 -2
  38. package/skills/paper-search/references/cli-contract.md +19 -0
  39. package/skills/paper-search/references/management-layer.md +1 -0
@@ -1,75 +1,91 @@
1
1
  import { downloadPdfFromUrl, safeFilename } from '../utils/PdfDownload.js';
2
+ export const INSTITUTIONAL_ACCESS_TIER_ID = 'institutional_access';
2
3
  const REPOSITORY_SOURCES = ['pmc', 'europepmc', 'core', 'openaire'];
4
+ const DEFAULT_DOWNLOAD_TIERS = [
5
+ {
6
+ id: 'primary',
7
+ stage: 'primary',
8
+ run: tryPrimaryDownload
9
+ },
10
+ {
11
+ id: 'direct_pdf_url',
12
+ stage: 'direct_pdf_url',
13
+ run: tryDirectMetadataUrl
14
+ },
15
+ {
16
+ id: 'repositories',
17
+ stage: 'repositories',
18
+ run: tryRepositoryFallback
19
+ },
20
+ {
21
+ id: 'unpaywall',
22
+ stage: 'unpaywall',
23
+ run: tryUnpaywall
24
+ },
25
+ {
26
+ id: 'scihub',
27
+ stage: 'scihub',
28
+ run: trySciHub
29
+ }
30
+ ];
3
31
  export async function downloadWithFallback(searchers, options) {
4
32
  const savePath = options.savePath || './downloads';
5
33
  const attempts = [];
6
- const source = normalizeSource(options.source);
7
- const primary = searchers[source];
8
- if (primary?.getCapabilities().download) {
9
- try {
10
- const path = await primary.downloadPdf(options.paperId, { savePath });
11
- attempts.push({ stage: 'primary', status: 'ok', message: path });
12
- return { status: 'ok', path, attempts };
13
- }
14
- catch (error) {
15
- attempts.push({ stage: 'primary', status: 'error', message: error?.message || String(error) });
34
+ const context = {
35
+ searchers,
36
+ source: normalizeSource(options.source),
37
+ paperId: options.paperId,
38
+ doi: options.doi,
39
+ title: options.title,
40
+ savePath,
41
+ useSciHub: options.useSciHub !== false
42
+ };
43
+ for (const tier of DEFAULT_DOWNLOAD_TIERS) {
44
+ const result = await tier.run(context);
45
+ attempts.push({ stage: tier.stage, status: result.status, message: result.message });
46
+ if (result.status === 'ok' && result.path) {
47
+ return { status: 'ok', path: result.path, attempts };
16
48
  }
17
49
  }
18
- else {
19
- attempts.push({ stage: 'primary', status: 'skipped', message: `No primary downloader for ${source}` });
20
- }
21
- const directResult = await tryDirectMetadataUrl(searchers, source, options.paperId, savePath, attempts);
22
- if (directResult)
23
- return { status: 'ok', path: directResult, attempts };
24
- const repositoryResult = await tryRepositoryFallback(searchers, options, savePath, attempts);
25
- if (repositoryResult)
26
- return { status: 'ok', path: repositoryResult, attempts };
27
- const unpaywallResult = await tryUnpaywall(searchers, options.doi || '', savePath, attempts);
28
- if (unpaywallResult)
29
- return { status: 'ok', path: unpaywallResult, attempts };
30
- if (options.useSciHub !== false) {
31
- const identifier = options.doi || options.title || options.paperId;
32
- try {
33
- const path = await searchers.scihub.downloadPdf(identifier, { savePath });
34
- attempts.push({ stage: 'scihub', status: 'ok', message: path });
35
- return { status: 'ok', path, attempts };
36
- }
37
- catch (error) {
38
- attempts.push({ stage: 'scihub', status: 'error', message: error?.message || String(error) });
39
- }
50
+ return { status: 'error', attempts };
51
+ }
52
+ async function tryPrimaryDownload(context) {
53
+ const primary = context.searchers[context.source];
54
+ if (!primary?.getCapabilities().download) {
55
+ return { status: 'skipped', message: `No primary downloader for ${context.source}` };
40
56
  }
41
- else {
42
- attempts.push({ stage: 'scihub', status: 'skipped', message: 'Sci-Hub fallback disabled by useSciHub=false.' });
57
+ try {
58
+ const path = await primary.downloadPdf(context.paperId, { savePath: context.savePath });
59
+ return { status: 'ok', path, message: path };
60
+ }
61
+ catch (error) {
62
+ return { status: 'error', message: error?.message || String(error) };
43
63
  }
44
- return { status: 'error', attempts };
45
64
  }
46
- async function tryDirectMetadataUrl(searchers, source, paperId, savePath, attempts) {
47
- const searcher = searchers[source];
48
- if (!searcher)
49
- return '';
65
+ async function tryDirectMetadataUrl(context) {
66
+ const searcher = context.searchers[context.source];
67
+ if (!searcher) {
68
+ return { status: 'skipped', message: `No metadata searcher for ${context.source}.` };
69
+ }
50
70
  try {
51
- const paper = await searcher.getPaperByDoi(paperId);
71
+ const paper = await searcher.getPaperByDoi(context.paperId);
52
72
  if (!paper?.pdfUrl) {
53
- attempts.push({ stage: 'direct_pdf_url', status: 'skipped', message: 'No pdf_url found in source metadata.' });
54
- return '';
73
+ return { status: 'skipped', message: 'No pdf_url found in source metadata.' };
55
74
  }
56
- const path = await downloadPdfFromUrl(paper.pdfUrl, savePath, `${source}_${safeFilename(paper.paperId)}`);
57
- attempts.push({ stage: 'direct_pdf_url', status: 'ok', message: path });
58
- return path;
75
+ const path = await downloadPdfFromUrl(paper.pdfUrl, context.savePath, `${context.source}_${safeFilename(paper.paperId)}`);
76
+ return { status: 'ok', path, message: path };
59
77
  }
60
78
  catch (error) {
61
- attempts.push({ stage: 'direct_pdf_url', status: 'error', message: error?.message || String(error) });
62
- return '';
79
+ return { status: 'error', message: error?.message || String(error) };
63
80
  }
64
81
  }
65
- async function tryRepositoryFallback(searchers, options, savePath, attempts) {
66
- const queries = [options.doi || '', options.title || ''].filter(Boolean);
82
+ async function tryRepositoryFallback(context) {
83
+ const queries = [context.doi || '', context.title || ''].filter(Boolean);
67
84
  if (queries.length === 0) {
68
- attempts.push({ stage: 'repositories', status: 'skipped', message: 'No DOI/title provided for repository discovery.' });
69
- return '';
85
+ return { status: 'skipped', message: 'No DOI/title provided for repository discovery.' };
70
86
  }
71
87
  for (const source of REPOSITORY_SOURCES) {
72
- const searcher = searchers[source];
88
+ const searcher = context.searchers[source];
73
89
  if (!searcher)
74
90
  continue;
75
91
  for (const query of queries) {
@@ -78,37 +94,44 @@ async function tryRepositoryFallback(searchers, options, savePath, attempts) {
78
94
  const paper = papers.find(candidate => candidate.pdfUrl);
79
95
  if (!paper?.pdfUrl)
80
96
  continue;
81
- const path = await downloadPdfFromUrl(paper.pdfUrl, savePath, `${source}_${safeFilename(paper.paperId)}`);
82
- attempts.push({ stage: `repository:${source}`, status: 'ok', message: path });
83
- return path;
97
+ const path = await downloadPdfFromUrl(paper.pdfUrl, context.savePath, `${source}_${safeFilename(paper.paperId)}`);
98
+ return { status: 'ok', path, message: path };
84
99
  }
85
- catch (error) {
86
- attempts.push({ stage: `repository:${source}`, status: 'error', message: error?.message || String(error) });
100
+ catch {
101
+ continue;
87
102
  }
88
103
  }
89
104
  }
90
- attempts.push({ stage: 'repositories', status: 'skipped', message: 'No repository PDF candidate succeeded.' });
91
- return '';
105
+ return { status: 'skipped', message: 'No repository PDF candidate succeeded.' };
92
106
  }
93
- async function tryUnpaywall(searchers, doi, savePath, attempts) {
94
- if (!doi) {
95
- attempts.push({ stage: 'unpaywall', status: 'skipped', message: 'DOI not provided.' });
96
- return '';
107
+ async function tryUnpaywall(context) {
108
+ if (!context.doi) {
109
+ return { status: 'skipped', message: 'DOI not provided.' };
97
110
  }
98
111
  try {
99
- const unpaywall = searchers.unpaywall;
100
- const pdfUrl = await unpaywall.resolveBestPdfUrl(doi);
112
+ const unpaywall = context.searchers.unpaywall;
113
+ const pdfUrl = await unpaywall.resolveBestPdfUrl(context.doi);
101
114
  if (!pdfUrl) {
102
- attempts.push({ stage: 'unpaywall', status: 'skipped', message: 'No OA PDF URL found or email not configured.' });
103
- return '';
115
+ return { status: 'skipped', message: 'No OA PDF URL found or email not configured.' };
104
116
  }
105
- const path = await downloadPdfFromUrl(pdfUrl, savePath, `unpaywall_${safeFilename(doi)}`);
106
- attempts.push({ stage: 'unpaywall', status: 'ok', message: path });
107
- return path;
117
+ const path = await downloadPdfFromUrl(pdfUrl, context.savePath, `unpaywall_${safeFilename(context.doi)}`);
118
+ return { status: 'ok', path, message: path };
119
+ }
120
+ catch (error) {
121
+ return { status: 'error', message: error?.message || String(error) };
122
+ }
123
+ }
124
+ async function trySciHub(context) {
125
+ if (!context.useSciHub) {
126
+ return { status: 'skipped', message: 'Sci-Hub fallback disabled by useSciHub=false.' };
127
+ }
128
+ const identifier = context.doi || context.title || context.paperId;
129
+ try {
130
+ const path = await context.searchers.scihub.downloadPdf(identifier, { savePath: context.savePath });
131
+ return { status: 'ok', path, message: path };
108
132
  }
109
133
  catch (error) {
110
- attempts.push({ stage: 'unpaywall', status: 'error', message: error?.message || String(error) });
111
- return '';
134
+ return { status: 'error', message: error?.message || String(error) };
112
135
  }
113
136
  }
114
137
  function normalizeSource(source) {
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAccessFallbackService.js","sourceRoot":"","sources":["../../src/services/OpenAccessFallbackService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"OpenAccessFallbackService.js","sourceRoot":"","sources":["../../src/services/OpenAccessFallbackService.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/utils/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,cAAc;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAGxB;gBAEI,OAAO,EAAE,kBAAkB;IAevC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBxC;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;OAEG;IACH,SAAS,IAAI;QACX,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;KACzB;IAUD;;OAEG;IACH,OAAO,IAAI,IAAI;IAsBf,OAAO,IAAI,IAAI;CAGhB"}
1
+ {"version":3,"file":"RateLimiter.d.ts","sourceRoot":"","sources":["../../src/utils/RateLimiter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,kBAAkB;IACjC,cAAc;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAGxB;gBAEI,OAAO,EAAE,kBAAkB;IAevC;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBxC;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAqB9B;;OAEG;IACH,SAAS,IAAI;QACX,eAAe,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,MAAM,CAAC;QAClB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,eAAe,EAAE,MAAM,CAAC;KACzB;IAUD;;OAEG;IACH,OAAO,IAAI,IAAI;IA0Bf,OAAO,IAAI,IAAI;CAGhB"}
@@ -42,6 +42,7 @@ export class RateLimiter {
42
42
  resolve,
43
43
  timestamp: Date.now()
44
44
  });
45
+ this.intervalHandle.ref?.();
45
46
  if (this.debug) {
46
47
  logDebug(`RateLimiter: Request queued, ${this.pendingRequests.length} waiting`);
47
48
  }
@@ -78,6 +79,9 @@ export class RateLimiter {
78
79
  }
79
80
  }
80
81
  }
82
+ if (this.pendingRequests.length === 0) {
83
+ this.intervalHandle.unref?.();
84
+ }
81
85
  }
82
86
  /**
83
87
  * 获取当前状态
@@ -110,6 +114,9 @@ export class RateLimiter {
110
114
  break;
111
115
  }
112
116
  }
117
+ if (this.pendingRequests.length === 0) {
118
+ this.intervalHandle.unref?.();
119
+ }
113
120
  if (this.debug && removedCount > 0) {
114
121
  logDebug(`RateLimiter: Cleaned up ${removedCount} expired requests`);
115
122
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/utils/RateLimiter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"RateLimiter.js","sourceRoot":"","sources":["../../src/utils/RateLimiter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paper-search-cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Agent-friendly CLI for searching and downloading academic papers from multiple sources.",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
@@ -5,6 +5,7 @@ description: |
5
5
  用于:搜索论文、查找相似研究、做文献综述初筛、验证 PMID/DOI、下载论文 PDF、
6
6
  调用 Crossref/OpenAlex/PubMed/PMC/Europe PMC/arXiv/bioRxiv/medRxiv/Semantic Scholar/CORE/OpenAIRE/DBLP/ACM/USENIX/OpenReview/IACR 等来源,
7
7
  使用 Semantic Scholar Open Access snippet 索引检索论文正文片段中的方法学细节,
8
+ 通过 Semantic Scholar Graph API 查询已知论文的施引文献和参考文献,
8
9
  以及通过 EasyScholar 查询期刊影响因子、JCR/SSCI 分区、中科院分区、JCI、ESI、预警和等级指标。
9
10
  当用户提到“搜文献”“找论文”“文献检索”“search papers”“find papers”“literature search”
10
11
  “查一下有没有相关研究”“帮我找几篇参考文献”“看看别人怎么做的”“别人怎么写”
@@ -18,7 +19,7 @@ description: |
18
19
 
19
20
  # Paper Search CLI
20
21
 
21
- 你是学术文献检索调度器。本 Skill 是 Routing Skill:负责把用户意图路由到 `paper-search` CLI,并维护证据、密钥和下载边界。优先通过 `paper-search` CLI 完成论文检索、元数据核验、正文片段检索、期刊指标查询和 PDF 获取;不要把本 Skill 当作密钥、cookie、账号或下载策略的存储位置。
22
+ 你是学术文献检索调度器。本 Skill 是 Routing Skill:负责把用户意图路由到 `paper-search` CLI,并维护证据、密钥和下载边界。优先通过 `paper-search` CLI 完成论文检索、元数据核验、施引/参考文献扩展、正文片段检索、期刊指标查询和 PDF 获取;不要把本 Skill 当作密钥、cookie、账号或下载策略的存储位置。
22
23
 
23
24
  Reference 读取规则:
24
25
 
@@ -75,11 +76,12 @@ paper-search doctor --pretty
75
76
 
76
77
  ## 功能地图
77
78
 
78
- 本 Skill 只有四个文献主功能。`doctor`、`smoke`、`config`、`skills` 是管理层命令,不属于文献任务本身。
79
+ 本 Skill 只有五个文献主功能。`doctor`、`smoke`、`config`、`skills` 是管理层命令,不属于文献任务本身。
79
80
 
80
81
  | 用户意图 | 能力名 | 首选入口 | 关键边界 |
81
82
  |---|---|---|---|
82
83
  | 搜论文、找相关研究、验证 DOI/PMID、做文献初筛 | `metadata_search` | `paper-search search` 集成入口 / `paper-search run search_*` 精确工具入口 | 只返回和核验论文元数据;Sci-Hub 不属于搜索源 |
84
+ | 查询已知论文的施引文献或参考文献 | `citation_expansion` | `paper-search run get_paper_citations` / `paper-search run get_paper_references` | 需要已知 `paperId`、DOI 或 arXiv ID;不是关键词检索 |
83
85
  | 查影响因子、JCR/SSCI/中科院分区、JCI、ESI、预警、期刊等级 | `journal_metrics` | `paper-search journal-metrics` / `paper-search run query_journal_metrics` | 这是期刊指标查询,不是论文检索;需要 `EASYSCHOLAR_KEY` |
84
86
  | 获取或下载已确认论文的 PDF | `pdf_discovery` | `paper-search download` / `paper-search run download_with_fallback` | 先核验论文身份,再下载;Sci-Hub 是默认开启的最后 fallback |
85
87
  | 在论文正文片段中找 Methods/参数/写法线索 | `body_snippet_search` | `paper-search run search_semantic_snippets` | 查 Semantic Scholar OA snippet 索引;需要 `SEMANTIC_SCHOLAR_API_KEY`;不是完整全文解析 |
@@ -1,12 +1,13 @@
1
1
  # Capability Routing Reference
2
2
 
3
- Use this reference when mapping a user literature request to one of the four main `paper-search` workflow capabilities.
3
+ Use this reference when mapping a user literature request to one of the five main `paper-search` workflow capabilities.
4
4
 
5
5
  ## Functional Map
6
6
 
7
7
  | User Intent | Capability | Preferred Entrypoint | Boundary |
8
8
  |---|---|---|---|
9
9
  | Search papers, find related work, verify DOI/PMID, screen literature | `metadata_search` | `paper-search search` integrated entrypoint / `paper-search run search_*` precise tool entrypoint | Returns and verifies paper metadata only; Sci-Hub is not a search source |
10
+ | Expand citation graph for a known paper | `citation_expansion` | `paper-search run get_paper_citations` / `paper-search run get_paper_references` | Requires a known `paperId`, DOI, or arXiv ID; returns citing papers or cited references, not general keyword search |
10
11
  | Query impact factor, JCR/SSCI/CAS quartiles, JCI, ESI, warnings, journal rank | `journal_metrics` | `paper-search journal-metrics` / `paper-search run query_journal_metrics` | Journal-level lookup, not paper search; requires `EASYSCHOLAR_KEY` |
11
12
  | Get or download a verified paper PDF | `pdf_discovery` | `paper-search download` / `paper-search run download_with_fallback` | Verify identity before download; Sci-Hub is the default enabled final fallback |
12
13
  | Find Methods text, parameters, software, models, or statistical wording in body snippets | `body_snippet_search` | `paper-search run search_semantic_snippets` | Searches Semantic Scholar OA snippet index; requires `SEMANTIC_SCHOLAR_API_KEY`; not full-text parsing |
@@ -32,7 +33,7 @@ Use `metadata_search` for finding papers, expanding keywords, literature screeni
32
33
  - use `--sources a,b,c` for explicit multi-source search
33
34
  - use `--platform all` or `--sources all` only when broad recall matters more than precision
34
35
 
35
- It does not call `journal_metrics`, `pdf_discovery`, or `body_snippet_search`.
36
+ It does not call `citation_expansion`, `journal_metrics`, `pdf_discovery`, or `body_snippet_search`.
36
37
 
37
38
  ```bash
38
39
  paper-search search "machine learning" --platform crossref --max-results 5 --pretty
@@ -51,6 +52,17 @@ paper-search run get_paper_by_doi --arg doi="10.xxxx/xxxxx" --pretty
51
52
 
52
53
  Do not treat `search_scihub` as a search source. It is DOI/URL-targeted lookup, not `metadata_search`.
53
54
 
55
+ ## Citation Expansion
56
+
57
+ Use `citation_expansion` when the user has a known paper and asks which papers cite it or which references it cites.
58
+
59
+ ```bash
60
+ paper-search run get_paper_citations --arg doi="10.1038/nature12373" --arg limit=5 --pretty
61
+ paper-search run get_paper_references --arg doi="10.1038/nature12373" --arg limit=5 --pretty
62
+ ```
63
+
64
+ Target priority is `paperId` > `doi` > `arxivId`. This capability uses Semantic Scholar Graph API and is separate from keyword-based `metadata_search`.
65
+
54
66
  ## Journal Metrics
55
67
 
56
68
  Use `journal_metrics` for journal-level metrics: impact factor, JCR/SSCI quartiles, CAS quartiles, JCI, ESI, warnings, and rank.
@@ -117,6 +129,7 @@ Only results with `snippetKind="body"` can be used as body-snippet evidence. Res
117
129
  |---|---|---|
118
130
  | Biomedical, clinical, pharmaceutical, public health | `pubmed` | `pmc`, `europepmc`, `semantic`, `crossref` |
119
131
  | Methods/body snippet clues | `search_semantic_snippets` | Use `pubmed`/`semantic` first for titles and synonyms |
132
+ | Citation graph expansion | `get_paper_citations`, `get_paper_references` | Use only after a target paper identifier is known |
120
133
  | Computer science, AI, math, physics | `arxiv` | `semantic`, `crossref`, `openalex` |
121
134
  | CS bibliographies and conference metadata | `dblp` | `acm`, `usenix`, `openreview`, `ieee` requires key |
122
135
  | Cross-disciplinary coverage | `crossref` | `openalex`, `semantic` |
@@ -51,6 +51,8 @@ These names can be used with `paper-search run <tool-name>`:
51
51
  - `search_medrxiv`
52
52
  - `search_semantic_scholar`
53
53
  - `search_semantic_snippets`
54
+ - `get_paper_citations`
55
+ - `get_paper_references`
54
56
  - `search_iacr`
55
57
  - `download_paper`
56
58
  - `search_google_scholar`
@@ -97,6 +99,23 @@ These names can be used with `paper-search run <tool-name>`:
97
99
  - `search_scihub` is DOI/URL-targeted lookup and is not a metadata search source.
98
100
  - `CORE_MAX_RESULTS_CAP` controls the configurable CORE-only result cap. Default is `100`; hard maximum is `500`. Other platforms keep their own current limits.
99
101
 
102
+ ## Citation Expansion Contract
103
+
104
+ `get_paper_citations` and `get_paper_references` query Semantic Scholar Graph API for citation graph expansion.
105
+
106
+ - Provide at least one of `paperId`, `doi`, or `arxivId`.
107
+ - Target priority is `paperId`, then `doi`, then `arxivId`.
108
+ - `doi` is converted to `DOI:<doi>`.
109
+ - `arxivId` is converted to `ARXIV:<id>`.
110
+ - `limit` defaults to `100` and accepts values from `1` to `100`.
111
+
112
+ Examples:
113
+
114
+ ```bash
115
+ paper-search run get_paper_citations --arg doi="10.1038/nature12373" --arg limit=5 --pretty
116
+ paper-search run get_paper_references --arg doi="10.1038/nature12373" --arg limit=5 --pretty
117
+ ```
118
+
100
119
  ## Download Command Contract
101
120
 
102
121
  `download_paper` tries source-native download first when available. Unsupported or failed native downloads route into the same fallback funnel used by `download_with_fallback`.
@@ -35,6 +35,7 @@ paper-search config list --pretty
35
35
  Capability Profile entries are independent workflow capabilities:
36
36
 
37
37
  - `metadata_search`: metadata search through configured/free literature sources. Sci-Hub must not be included in metadata search.
38
+ - `citation_expansion`: citation and reference expansion for a known paper through Semantic Scholar Graph API. `SEMANTIC_SCHOLAR_API_KEY` is optional for higher quota.
38
39
  - `body_snippet_search`: Semantic Scholar Open Access snippet search. It requires `SEMANTIC_SCHOLAR_API_KEY`.
39
40
  - `journal_metrics`: EasyScholar journal metrics. It requires `EASYSCHOLAR_KEY`.
40
41
  - `pdf_discovery`: PDF discovery and download through source-native download, metadata PDF URLs, open-access sources, entitled-access sources when configured, and the default enabled Sci-Hub Fallback.