paper-search-cli 0.3.0 → 0.3.2

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 (314) hide show
  1. package/README.md +11 -9
  2. package/README.zh.md +11 -9
  3. package/dist/capabilities/body-snippet-search/handler.d.ts +9 -0
  4. package/dist/capabilities/body-snippet-search/handler.d.ts.map +1 -0
  5. package/dist/capabilities/body-snippet-search/handler.js +17 -0
  6. package/dist/capabilities/body-snippet-search/handler.js.map +1 -0
  7. package/dist/capabilities/body-snippet-search/index.d.ts +7 -0
  8. package/dist/capabilities/body-snippet-search/index.d.ts.map +1 -0
  9. package/dist/capabilities/body-snippet-search/index.js +6 -0
  10. package/dist/capabilities/body-snippet-search/index.js.map +1 -0
  11. package/dist/capabilities/body-snippet-search/schemas.d.ts +36 -0
  12. package/dist/capabilities/body-snippet-search/schemas.d.ts.map +1 -0
  13. package/dist/capabilities/body-snippet-search/schemas.js +16 -0
  14. package/dist/capabilities/body-snippet-search/schemas.js.map +1 -0
  15. package/dist/capabilities/body-snippet-search/service.d.ts +4 -0
  16. package/dist/capabilities/body-snippet-search/service.d.ts.map +1 -0
  17. package/dist/capabilities/body-snippet-search/service.js +4 -0
  18. package/dist/capabilities/body-snippet-search/service.js.map +1 -0
  19. package/dist/capabilities/body-snippet-search/tools.d.ts +187 -0
  20. package/dist/capabilities/body-snippet-search/tools.d.ts.map +1 -0
  21. package/dist/capabilities/body-snippet-search/tools.js +49 -0
  22. package/dist/capabilities/body-snippet-search/tools.js.map +1 -0
  23. package/dist/capabilities/body-snippet-search/types.d.ts +14 -0
  24. package/dist/capabilities/body-snippet-search/types.d.ts.map +1 -0
  25. package/dist/capabilities/body-snippet-search/types.js +2 -0
  26. package/dist/capabilities/body-snippet-search/types.js.map +1 -0
  27. package/dist/capabilities/citation-expansion/CitationService.d.ts +47 -0
  28. package/dist/capabilities/citation-expansion/CitationService.d.ts.map +1 -0
  29. package/dist/capabilities/citation-expansion/CitationService.js +243 -0
  30. package/dist/capabilities/citation-expansion/CitationService.js.map +1 -0
  31. package/dist/capabilities/citation-expansion/handler.d.ts +36 -0
  32. package/dist/capabilities/citation-expansion/handler.d.ts.map +1 -0
  33. package/dist/capabilities/citation-expansion/handler.js +44 -0
  34. package/dist/capabilities/citation-expansion/handler.js.map +1 -0
  35. package/dist/capabilities/citation-expansion/index.d.ts +6 -0
  36. package/dist/capabilities/citation-expansion/index.d.ts.map +1 -0
  37. package/dist/capabilities/citation-expansion/index.js +5 -0
  38. package/dist/capabilities/citation-expansion/index.js.map +1 -0
  39. package/dist/capabilities/citation-expansion/schemas.d.ts +28 -0
  40. package/dist/capabilities/citation-expansion/schemas.d.ts.map +1 -0
  41. package/dist/capabilities/citation-expansion/schemas.js +13 -0
  42. package/dist/capabilities/citation-expansion/schemas.js.map +1 -0
  43. package/dist/capabilities/citation-expansion/tools.d.ts +82 -0
  44. package/dist/capabilities/citation-expansion/tools.d.ts.map +1 -0
  45. package/dist/capabilities/citation-expansion/tools.js +48 -0
  46. package/dist/capabilities/citation-expansion/tools.js.map +1 -0
  47. package/dist/capabilities/citation-expansion/types.d.ts +22 -0
  48. package/dist/capabilities/citation-expansion/types.d.ts.map +1 -0
  49. package/dist/capabilities/citation-expansion/types.js +2 -0
  50. package/dist/capabilities/citation-expansion/types.js.map +1 -0
  51. package/dist/capabilities/journal-metrics/JournalMetricsService.d.ts +3 -0
  52. package/dist/capabilities/journal-metrics/JournalMetricsService.d.ts.map +1 -0
  53. package/dist/capabilities/journal-metrics/JournalMetricsService.js +142 -0
  54. package/dist/capabilities/journal-metrics/JournalMetricsService.js.map +1 -0
  55. package/dist/capabilities/journal-metrics/handler.d.ts +12 -0
  56. package/dist/capabilities/journal-metrics/handler.d.ts.map +1 -0
  57. package/dist/capabilities/journal-metrics/handler.js +38 -0
  58. package/dist/capabilities/journal-metrics/handler.js.map +1 -0
  59. package/dist/capabilities/journal-metrics/index.d.ts +6 -0
  60. package/dist/capabilities/journal-metrics/index.d.ts.map +1 -0
  61. package/dist/capabilities/journal-metrics/index.js +5 -0
  62. package/dist/capabilities/journal-metrics/index.js.map +1 -0
  63. package/dist/capabilities/journal-metrics/schemas.d.ts +28 -0
  64. package/dist/capabilities/journal-metrics/schemas.d.ts.map +1 -0
  65. package/dist/capabilities/journal-metrics/schemas.js +13 -0
  66. package/dist/capabilities/journal-metrics/schemas.js.map +1 -0
  67. package/dist/capabilities/journal-metrics/tools.d.ts +67 -0
  68. package/dist/capabilities/journal-metrics/tools.d.ts.map +1 -0
  69. package/dist/capabilities/journal-metrics/tools.js +27 -0
  70. package/dist/capabilities/journal-metrics/tools.js.map +1 -0
  71. package/dist/capabilities/journal-metrics/types.d.ts +36 -0
  72. package/dist/capabilities/journal-metrics/types.d.ts.map +1 -0
  73. package/dist/capabilities/journal-metrics/types.js +2 -0
  74. package/dist/capabilities/journal-metrics/types.js.map +1 -0
  75. package/dist/capabilities/metadata-search/MultiSourceSearchService.d.ts +9 -0
  76. package/dist/capabilities/metadata-search/MultiSourceSearchService.d.ts.map +1 -0
  77. package/dist/capabilities/metadata-search/MultiSourceSearchService.js +78 -0
  78. package/dist/capabilities/metadata-search/MultiSourceSearchService.js.map +1 -0
  79. package/dist/capabilities/metadata-search/handler.d.ts +23 -0
  80. package/dist/capabilities/metadata-search/handler.d.ts.map +1 -0
  81. package/dist/capabilities/metadata-search/handler.js +163 -0
  82. package/dist/capabilities/metadata-search/handler.js.map +1 -0
  83. package/dist/capabilities/metadata-search/index.d.ts +6 -0
  84. package/dist/capabilities/metadata-search/index.d.ts.map +1 -0
  85. package/dist/capabilities/metadata-search/index.js +5 -0
  86. package/dist/capabilities/metadata-search/index.js.map +1 -0
  87. package/dist/capabilities/metadata-search/schemas.d.ts +83 -0
  88. package/dist/capabilities/metadata-search/schemas.d.ts.map +1 -0
  89. package/dist/capabilities/metadata-search/schemas.js +81 -0
  90. package/dist/capabilities/metadata-search/schemas.js.map +1 -0
  91. package/dist/capabilities/metadata-search/tools.d.ts +178 -0
  92. package/dist/capabilities/metadata-search/tools.d.ts.map +1 -0
  93. package/dist/capabilities/metadata-search/tools.js +75 -0
  94. package/dist/capabilities/metadata-search/tools.js.map +1 -0
  95. package/dist/capabilities/metadata-search/types.d.ts +13 -0
  96. package/dist/capabilities/metadata-search/types.d.ts.map +1 -0
  97. package/dist/capabilities/metadata-search/types.js +2 -0
  98. package/dist/capabilities/metadata-search/types.js.map +1 -0
  99. package/dist/capabilities/pdf-discovery/DownloadTier.d.ts +22 -0
  100. package/dist/capabilities/pdf-discovery/DownloadTier.d.ts.map +1 -0
  101. package/dist/capabilities/pdf-discovery/DownloadTier.js +2 -0
  102. package/dist/capabilities/pdf-discovery/DownloadTier.js.map +1 -0
  103. package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.d.ts +10 -0
  104. package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.d.ts.map +1 -0
  105. package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.js +53 -0
  106. package/dist/capabilities/pdf-discovery/OpenAccessFallbackService.js.map +1 -0
  107. package/dist/capabilities/pdf-discovery/handler.d.ts +19 -0
  108. package/dist/capabilities/pdf-discovery/handler.d.ts.map +1 -0
  109. package/dist/capabilities/pdf-discovery/handler.js +56 -0
  110. package/dist/capabilities/pdf-discovery/handler.js.map +1 -0
  111. package/dist/capabilities/pdf-discovery/index.d.ts +7 -0
  112. package/dist/capabilities/pdf-discovery/index.d.ts.map +1 -0
  113. package/dist/capabilities/pdf-discovery/index.js +5 -0
  114. package/dist/capabilities/pdf-discovery/index.js.map +1 -0
  115. package/dist/capabilities/pdf-discovery/schemas.d.ts +37 -0
  116. package/dist/capabilities/pdf-discovery/schemas.d.ts.map +1 -0
  117. package/dist/capabilities/pdf-discovery/schemas.js +22 -0
  118. package/dist/capabilities/pdf-discovery/schemas.js.map +1 -0
  119. package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.d.ts +3 -0
  120. package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.d.ts.map +1 -0
  121. package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.js +27 -0
  122. package/dist/capabilities/pdf-discovery/tiers/directPdfUrl.js.map +1 -0
  123. package/dist/capabilities/pdf-discovery/tiers/primary.d.ts +3 -0
  124. package/dist/capabilities/pdf-discovery/tiers/primary.d.ts.map +1 -0
  125. package/dist/capabilities/pdf-discovery/tiers/primary.js +21 -0
  126. package/dist/capabilities/pdf-discovery/tiers/primary.js.map +1 -0
  127. package/dist/capabilities/pdf-discovery/tiers/repositories.d.ts +3 -0
  128. package/dist/capabilities/pdf-discovery/tiers/repositories.d.ts.map +1 -0
  129. package/dist/capabilities/pdf-discovery/tiers/repositories.js +35 -0
  130. package/dist/capabilities/pdf-discovery/tiers/repositories.js.map +1 -0
  131. package/dist/capabilities/pdf-discovery/tiers/scihub.d.ts +3 -0
  132. package/dist/capabilities/pdf-discovery/tiers/scihub.d.ts.map +1 -0
  133. package/dist/capabilities/pdf-discovery/tiers/scihub.js +21 -0
  134. package/dist/capabilities/pdf-discovery/tiers/scihub.js.map +1 -0
  135. package/dist/capabilities/pdf-discovery/tiers/unpaywall.d.ts +3 -0
  136. package/dist/capabilities/pdf-discovery/tiers/unpaywall.d.ts.map +1 -0
  137. package/dist/capabilities/pdf-discovery/tiers/unpaywall.js +29 -0
  138. package/dist/capabilities/pdf-discovery/tiers/unpaywall.js.map +1 -0
  139. package/dist/capabilities/pdf-discovery/tools.d.ts +114 -0
  140. package/dist/capabilities/pdf-discovery/tools.d.ts.map +1 -0
  141. package/dist/capabilities/pdf-discovery/tools.js +42 -0
  142. package/dist/capabilities/pdf-discovery/tools.js.map +1 -0
  143. package/dist/capabilities/pdf-discovery/types.d.ts +19 -0
  144. package/dist/capabilities/pdf-discovery/types.d.ts.map +1 -0
  145. package/dist/capabilities/pdf-discovery/types.js +2 -0
  146. package/dist/capabilities/pdf-discovery/types.js.map +1 -0
  147. package/dist/cli.js +10 -6
  148. package/dist/cli.js.map +1 -1
  149. package/dist/core/capabilityProfile.d.ts +1 -17
  150. package/dist/core/capabilityProfile.d.ts.map +1 -1
  151. package/dist/core/capabilityProfile.js +1 -152
  152. package/dist/core/capabilityProfile.js.map +1 -1
  153. package/dist/core/diagnostics.d.ts +1 -42
  154. package/dist/core/diagnostics.d.ts.map +1 -1
  155. package/dist/core/diagnostics.js +1 -585
  156. package/dist/core/diagnostics.js.map +1 -1
  157. package/dist/core/handleToolCall.d.ts +1 -0
  158. package/dist/core/handleToolCall.d.ts.map +1 -1
  159. package/dist/core/handleToolCall.js +265 -476
  160. package/dist/core/handleToolCall.js.map +1 -1
  161. package/dist/core/httpPolicies.d.ts +2 -0
  162. package/dist/core/httpPolicies.d.ts.map +1 -0
  163. package/dist/core/httpPolicies.js +2 -0
  164. package/dist/core/httpPolicies.js.map +1 -0
  165. package/dist/core/liveSmoke.d.ts +1 -41
  166. package/dist/core/liveSmoke.d.ts.map +1 -1
  167. package/dist/core/liveSmoke.js +1 -225
  168. package/dist/core/liveSmoke.js.map +1 -1
  169. package/dist/core/platformFactories.d.ts +2 -0
  170. package/dist/core/platformFactories.d.ts.map +1 -0
  171. package/dist/core/platformFactories.js +2 -0
  172. package/dist/core/platformFactories.js.map +1 -0
  173. package/dist/core/platformMetadata.d.ts +1 -27
  174. package/dist/core/platformMetadata.d.ts.map +1 -1
  175. package/dist/core/platformMetadata.js +1 -257
  176. package/dist/core/platformMetadata.js.map +1 -1
  177. package/dist/core/schemas.d.ts +11 -177
  178. package/dist/core/schemas.d.ts.map +1 -1
  179. package/dist/core/schemas.js +14 -107
  180. package/dist/core/schemas.js.map +1 -1
  181. package/dist/core/searchers.d.ts +24 -24
  182. package/dist/core/searchers.d.ts.map +1 -1
  183. package/dist/core/searchers.js +14 -79
  184. package/dist/core/searchers.js.map +1 -1
  185. package/dist/core/textReports.d.ts +1 -20
  186. package/dist/core/textReports.d.ts.map +1 -1
  187. package/dist/core/textReports.js +1 -84
  188. package/dist/core/textReports.js.map +1 -1
  189. package/dist/core/tools.d.ts.map +1 -1
  190. package/dist/core/tools.js +15 -183
  191. package/dist/core/tools.js.map +1 -1
  192. package/dist/infrastructure/cache/RequestCache.d.ts +26 -0
  193. package/dist/infrastructure/cache/RequestCache.d.ts.map +1 -0
  194. package/dist/infrastructure/cache/RequestCache.js +66 -0
  195. package/dist/infrastructure/cache/RequestCache.js.map +1 -0
  196. package/dist/infrastructure/http/ErrorHandler.d.ts +99 -0
  197. package/dist/infrastructure/http/ErrorHandler.d.ts.map +1 -0
  198. package/dist/infrastructure/http/ErrorHandler.js +266 -0
  199. package/dist/infrastructure/http/ErrorHandler.js.map +1 -0
  200. package/dist/infrastructure/http/HttpClient.d.ts +31 -0
  201. package/dist/infrastructure/http/HttpClient.d.ts.map +1 -0
  202. package/dist/infrastructure/http/HttpClient.js +50 -0
  203. package/dist/infrastructure/http/HttpClient.js.map +1 -0
  204. package/dist/infrastructure/pdf/PDFExtractor.d.ts +34 -0
  205. package/dist/infrastructure/pdf/PDFExtractor.d.ts.map +1 -0
  206. package/dist/infrastructure/pdf/PDFExtractor.js +130 -0
  207. package/dist/infrastructure/pdf/PDFExtractor.js.map +1 -0
  208. package/dist/infrastructure/pdf/PdfDownload.d.ts +7 -0
  209. package/dist/infrastructure/pdf/PdfDownload.d.ts.map +1 -0
  210. package/dist/infrastructure/pdf/PdfDownload.js +175 -0
  211. package/dist/infrastructure/pdf/PdfDownload.js.map +1 -0
  212. package/dist/infrastructure/rate-limit/RateLimiter.d.ts +50 -0
  213. package/dist/infrastructure/rate-limit/RateLimiter.d.ts.map +1 -0
  214. package/dist/infrastructure/rate-limit/RateLimiter.js +128 -0
  215. package/dist/infrastructure/rate-limit/RateLimiter.js.map +1 -0
  216. package/dist/infrastructure/security/SecurityUtils.d.ts +80 -0
  217. package/dist/infrastructure/security/SecurityUtils.d.ts.map +1 -0
  218. package/dist/infrastructure/security/SecurityUtils.js +357 -0
  219. package/dist/infrastructure/security/SecurityUtils.js.map +1 -0
  220. package/dist/management/capability-profile/index.d.ts +18 -0
  221. package/dist/management/capability-profile/index.d.ts.map +1 -0
  222. package/dist/management/capability-profile/index.js +167 -0
  223. package/dist/management/capability-profile/index.js.map +1 -0
  224. package/dist/management/config/index.d.ts +2 -0
  225. package/dist/management/config/index.d.ts.map +1 -0
  226. package/dist/management/config/index.js +2 -0
  227. package/dist/management/config/index.js.map +1 -0
  228. package/dist/management/diagnostics/index.d.ts +43 -0
  229. package/dist/management/diagnostics/index.d.ts.map +1 -0
  230. package/dist/management/diagnostics/index.js +586 -0
  231. package/dist/management/diagnostics/index.js.map +1 -0
  232. package/dist/management/reports/index.d.ts +21 -0
  233. package/dist/management/reports/index.d.ts.map +1 -0
  234. package/dist/management/reports/index.js +85 -0
  235. package/dist/management/reports/index.js.map +1 -0
  236. package/dist/management/skills/index.d.ts +2 -0
  237. package/dist/management/skills/index.d.ts.map +1 -0
  238. package/dist/management/skills/index.js +2 -0
  239. package/dist/management/skills/index.js.map +1 -0
  240. package/dist/management/smoke/index.d.ts +42 -0
  241. package/dist/management/smoke/index.d.ts.map +1 -0
  242. package/dist/management/smoke/index.js +226 -0
  243. package/dist/management/smoke/index.js.map +1 -0
  244. package/dist/platforms/BioRxivSearcher.d.ts.map +1 -1
  245. package/dist/platforms/BioRxivSearcher.js +40 -21
  246. package/dist/platforms/BioRxivSearcher.js.map +1 -1
  247. package/dist/platforms/GoogleScholarSearcher.d.ts.map +1 -1
  248. package/dist/platforms/GoogleScholarSearcher.js +3 -2
  249. package/dist/platforms/GoogleScholarSearcher.js.map +1 -1
  250. package/dist/registry/aliases.d.ts +2 -0
  251. package/dist/registry/aliases.d.ts.map +1 -0
  252. package/dist/registry/aliases.js +2 -0
  253. package/dist/registry/aliases.js.map +1 -0
  254. package/dist/registry/httpPolicies.d.ts +3 -0
  255. package/dist/registry/httpPolicies.d.ts.map +1 -0
  256. package/dist/registry/httpPolicies.js +17 -0
  257. package/dist/registry/httpPolicies.js.map +1 -0
  258. package/dist/registry/platformFactories.d.ts +8 -0
  259. package/dist/registry/platformFactories.d.ts.map +1 -0
  260. package/dist/registry/platformFactories.js +55 -0
  261. package/dist/registry/platformFactories.js.map +1 -0
  262. package/dist/registry/platformMetadata.d.ts +39 -0
  263. package/dist/registry/platformMetadata.d.ts.map +1 -0
  264. package/dist/registry/platformMetadata.js +321 -0
  265. package/dist/registry/platformMetadata.js.map +1 -0
  266. package/dist/services/CitationService.d.ts +2 -65
  267. package/dist/services/CitationService.d.ts.map +1 -1
  268. package/dist/services/CitationService.js +1 -236
  269. package/dist/services/CitationService.js.map +1 -1
  270. package/dist/services/JournalMetricsService.d.ts +2 -37
  271. package/dist/services/JournalMetricsService.d.ts.map +1 -1
  272. package/dist/services/JournalMetricsService.js +1 -141
  273. package/dist/services/JournalMetricsService.js.map +1 -1
  274. package/dist/services/MultiSourceSearchService.d.ts +2 -18
  275. package/dist/services/MultiSourceSearchService.d.ts.map +1 -1
  276. package/dist/services/MultiSourceSearchService.js +1 -77
  277. package/dist/services/MultiSourceSearchService.js.map +1 -1
  278. package/dist/services/OpenAccessFallbackService.d.ts +3 -20
  279. package/dist/services/OpenAccessFallbackService.d.ts.map +1 -1
  280. package/dist/services/OpenAccessFallbackService.js +1 -123
  281. package/dist/services/OpenAccessFallbackService.js.map +1 -1
  282. package/dist/utils/ErrorHandler.d.ts +2 -98
  283. package/dist/utils/ErrorHandler.d.ts.map +1 -1
  284. package/dist/utils/ErrorHandler.js +2 -265
  285. package/dist/utils/ErrorHandler.js.map +1 -1
  286. package/dist/utils/HttpClient.d.ts +1 -5
  287. package/dist/utils/HttpClient.d.ts.map +1 -1
  288. package/dist/utils/HttpClient.js +1 -29
  289. package/dist/utils/HttpClient.js.map +1 -1
  290. package/dist/utils/PDFExtractor.d.ts +2 -33
  291. package/dist/utils/PDFExtractor.d.ts.map +1 -1
  292. package/dist/utils/PDFExtractor.js +2 -129
  293. package/dist/utils/PDFExtractor.js.map +1 -1
  294. package/dist/utils/PdfDownload.d.ts +1 -6
  295. package/dist/utils/PdfDownload.d.ts.map +1 -1
  296. package/dist/utils/PdfDownload.js +1 -141
  297. package/dist/utils/PdfDownload.js.map +1 -1
  298. package/dist/utils/RateLimiter.d.ts +1 -49
  299. package/dist/utils/RateLimiter.d.ts.map +1 -1
  300. package/dist/utils/RateLimiter.js +1 -120
  301. package/dist/utils/RateLimiter.js.map +1 -1
  302. package/dist/utils/RequestCache.d.ts +2 -25
  303. package/dist/utils/RequestCache.d.ts.map +1 -1
  304. package/dist/utils/RequestCache.js +2 -65
  305. package/dist/utils/RequestCache.js.map +1 -1
  306. package/dist/utils/SecurityUtils.d.ts +2 -79
  307. package/dist/utils/SecurityUtils.d.ts.map +1 -1
  308. package/dist/utils/SecurityUtils.js +2 -356
  309. package/dist/utils/SecurityUtils.js.map +1 -1
  310. package/package.json +1 -1
  311. package/skills/paper-search/SKILL.md +4 -2
  312. package/skills/paper-search/references/capability-routing.md +15 -2
  313. package/skills/paper-search/references/cli-contract.md +19 -0
  314. package/skills/paper-search/references/management-layer.md +1 -0
@@ -1,80 +1,3 @@
1
- /**
2
- * Security utilities for sanitizing and validating data
3
- * Provides comprehensive protection against security vulnerabilities
4
- */
5
- /**
6
- * Comprehensive request sanitization to remove sensitive data
7
- * @param config - Axios request configuration
8
- * @returns Sanitized configuration copy
9
- */
10
- export declare function sanitizeRequest(config: any): any;
11
- /**
12
- * Sanitize headers to remove sensitive information
13
- */
14
- export declare function sanitizeHeaders(headers: Record<string, any>): Record<string, any>;
15
- /**
16
- * Sanitize URL parameters
17
- */
18
- export declare function sanitizeParams(params: Record<string, any>): Record<string, any>;
19
- /**
20
- * Sanitize request body
21
- */
22
- export declare function sanitizeBody(body: any): any;
23
- /**
24
- * Sanitize URL to remove sensitive query parameters
25
- */
26
- export declare function sanitizeUrl(url: string): string;
27
- /**
28
- * Validate and sanitize a DOI string
29
- */
30
- export declare function sanitizeDoi(doi: string): {
31
- valid: boolean;
32
- sanitized: string;
33
- error?: string;
34
- };
35
- /**
36
- * Escape query value for different contexts
37
- */
38
- export declare function escapeQueryValue(value: string, context?: 'springer' | 'wos' | 'general'): string;
39
- /**
40
- * Validate query complexity to prevent DoS
41
- */
42
- export declare function validateQueryComplexity(query: string, options?: {
43
- maxLength?: number;
44
- maxBooleanOperators?: number;
45
- }): {
46
- valid: boolean;
47
- error?: string;
48
- };
49
- /**
50
- * Create a timeout wrapper for promises
51
- */
52
- export declare function withTimeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T>;
53
- /**
54
- * Generate a correlation ID for request tracking
55
- */
56
- export declare function generateCorrelationId(): string;
57
- /**
58
- * Mask sensitive data in strings
59
- */
60
- export declare function maskSensitiveData(str: string): string;
61
- /**
62
- * Check if a string looks like an API key or token
63
- */
64
- export declare function looksLikeToken(str: string): boolean;
65
- declare const _default: {
66
- sanitizeRequest: typeof sanitizeRequest;
67
- sanitizeHeaders: typeof sanitizeHeaders;
68
- sanitizeParams: typeof sanitizeParams;
69
- sanitizeBody: typeof sanitizeBody;
70
- sanitizeUrl: typeof sanitizeUrl;
71
- sanitizeDoi: typeof sanitizeDoi;
72
- escapeQueryValue: typeof escapeQueryValue;
73
- validateQueryComplexity: typeof validateQueryComplexity;
74
- withTimeout: typeof withTimeout;
75
- generateCorrelationId: typeof generateCorrelationId;
76
- maskSensitiveData: typeof maskSensitiveData;
77
- looksLikeToken: typeof looksLikeToken;
78
- };
79
- export default _default;
1
+ export * from '../infrastructure/security/SecurityUtils.js';
2
+ export { default } from '../infrastructure/security/SecurityUtils.js';
80
3
  //# sourceMappingURL=SecurityUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityUtils.d.ts","sourceRoot":"","sources":["../../src/utils/SecurityUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAiChD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA0CjF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA2B/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,CAwC3C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA2B/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA6C9F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,UAAU,GAAG,KAAK,GAAG,SAAqB,GAClD,MAAM,CAsCR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAO,GACjE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0CpC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAC3B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAanD;;;;;;;;;;;;;;;AAED,wBAaE"}
1
+ {"version":3,"file":"SecurityUtils.d.ts","sourceRoot":"","sources":["../../src/utils/SecurityUtils.ts"],"names":[],"mappings":"AAAA,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,6CAA6C,CAAC"}
@@ -1,357 +1,3 @@
1
- /**
2
- * Security utilities for sanitizing and validating data
3
- * Provides comprehensive protection against security vulnerabilities
4
- */
5
- /**
6
- * Comprehensive request sanitization to remove sensitive data
7
- * @param config - Axios request configuration
8
- * @returns Sanitized configuration copy
9
- */
10
- export function sanitizeRequest(config) {
11
- if (!config)
12
- return config;
13
- // Deep clone to avoid mutating original
14
- let sanitized;
15
- try {
16
- sanitized = JSON.parse(JSON.stringify(config));
17
- }
18
- catch {
19
- // If JSON serialization fails, return redacted version
20
- return { __redacted: 'Failed to sanitize - potentially circular reference' };
21
- }
22
- // Sanitize headers
23
- if (sanitized.headers) {
24
- sanitized.headers = sanitizeHeaders(sanitized.headers);
25
- }
26
- // Sanitize URL parameters
27
- if (sanitized.params) {
28
- sanitized.params = sanitizeParams(sanitized.params);
29
- }
30
- // Sanitize request body
31
- if (sanitized.data) {
32
- sanitized.data = sanitizeBody(sanitized.data);
33
- }
34
- // Sanitize URL
35
- if (sanitized.url) {
36
- sanitized.url = sanitizeUrl(sanitized.url);
37
- }
38
- return sanitized;
39
- }
40
- /**
41
- * Sanitize headers to remove sensitive information
42
- */
43
- export function sanitizeHeaders(headers) {
44
- if (!headers)
45
- return headers;
46
- const sanitized = { ...headers };
47
- // Patterns for sensitive headers (case-insensitive)
48
- const sensitivePatterns = [
49
- /^api[-_]?key$/i,
50
- /^x[-_]api[-_]key$/i,
51
- /^authorization$/i,
52
- /^x[-_]apikey$/i,
53
- /^access[-_]token$/i,
54
- /^bearer$/i,
55
- /^x[-_]auth[-_]token$/i,
56
- /^cookie$/i,
57
- /^set[-_]cookie$/i,
58
- /^x[-_]csrf[-_]token$/i,
59
- /^x[-_]forwarded[-_]for$/i, // May contain IP
60
- /^referer$/i, // May contain sensitive URLs
61
- /^user[-_]agent$/i // May contain system info
62
- ];
63
- Object.keys(sanitized).forEach(key => {
64
- const lowerKey = key.toLowerCase();
65
- // Check against patterns
66
- if (sensitivePatterns.some(pattern => pattern.test(key))) {
67
- sanitized[key] = '***REDACTED***';
68
- }
69
- // Also check values that might contain tokens
70
- if (typeof sanitized[key] === 'string') {
71
- if (sanitized[key].match(/^(Bearer|Basic)\s+/i) ||
72
- sanitized[key].match(/^[a-zA-Z0-9_-]{20,}$/) || // Likely token
73
- sanitized[key].includes('session=') ||
74
- sanitized[key].includes('token=')) {
75
- sanitized[key] = '***REDACTED***';
76
- }
77
- }
78
- });
79
- return sanitized;
80
- }
81
- /**
82
- * Sanitize URL parameters
83
- */
84
- export function sanitizeParams(params) {
85
- if (!params)
86
- return params;
87
- const sanitized = { ...params };
88
- Object.keys(sanitized).forEach(key => {
89
- const lowerKey = key.toLowerCase();
90
- // Check for common sensitive parameter names
91
- if (lowerKey.includes('api_key') ||
92
- lowerKey.includes('apikey') ||
93
- lowerKey.includes('token') ||
94
- lowerKey.includes('secret') ||
95
- lowerKey.includes('password') ||
96
- lowerKey.includes('private') ||
97
- lowerKey.includes('auth')) {
98
- sanitized[key] = '***REDACTED***';
99
- }
100
- // Mask values that look like tokens
101
- if (typeof sanitized[key] === 'string' &&
102
- sanitized[key].match(/^[a-zA-Z0-9_-]{16,}$/)) {
103
- sanitized[key] = sanitized[key].substring(0, 4) + '***';
104
- }
105
- });
106
- return sanitized;
107
- }
108
- /**
109
- * Sanitize request body
110
- */
111
- export function sanitizeBody(body) {
112
- if (!body)
113
- return body;
114
- // For objects, recursively sanitize
115
- if (typeof body === 'object' && body !== null) {
116
- // Handle arrays
117
- if (Array.isArray(body)) {
118
- return body.map(item => sanitizeBody(item));
119
- }
120
- // Handle objects
121
- const sanitized = {};
122
- for (const [key, value] of Object.entries(body)) {
123
- const lowerKey = key.toLowerCase();
124
- // Check for sensitive keys
125
- if (lowerKey.includes('password') ||
126
- lowerKey.includes('secret') ||
127
- lowerKey.includes('token') ||
128
- lowerKey.includes('api_key') ||
129
- lowerKey.includes('private')) {
130
- sanitized[key] = '***REDACTED***';
131
- }
132
- else {
133
- sanitized[key] = sanitizeBody(value);
134
- }
135
- }
136
- return sanitized;
137
- }
138
- // For strings, check if it looks like a token
139
- if (typeof body === 'string') {
140
- if (body.match(/^(Bearer|Basic)\s+/i)) {
141
- return body.replace(/\s+\S+/, ' ***REDACTED***');
142
- }
143
- if (body.match(/^[a-zA-Z0-9_-]{32,}$/)) {
144
- return body.substring(0, 8) + '***';
145
- }
146
- }
147
- return body;
148
- }
149
- /**
150
- * Sanitize URL to remove sensitive query parameters
151
- */
152
- export function sanitizeUrl(url) {
153
- if (!url)
154
- return url;
155
- try {
156
- const urlObj = new URL(url);
157
- // Remove sensitive query parameters
158
- const sensitiveParams = ['api_key', 'apikey', 'token', 'secret', 'auth'];
159
- let hasSensitiveParams = false;
160
- sensitiveParams.forEach(param => {
161
- if (urlObj.searchParams.has(param)) {
162
- urlObj.searchParams.set(param, '***REDACTED***');
163
- hasSensitiveParams = true;
164
- }
165
- });
166
- // If we modified parameters, add indicator
167
- if (hasSensitiveParams) {
168
- return urlObj.toString() + '#sanitized';
169
- }
170
- return url;
171
- }
172
- catch {
173
- // If URL parsing fails, mask the entire URL
174
- return '***REDACTED_URL***';
175
- }
176
- }
177
- /**
178
- * Validate and sanitize a DOI string
179
- */
180
- export function sanitizeDoi(doi) {
181
- if (!doi || typeof doi !== 'string') {
182
- return { valid: false, sanitized: '', error: 'DOI must be a non-empty string' };
183
- }
184
- // Remove whitespace and common prefixes
185
- let sanitized = doi.trim();
186
- // Remove common DOI URL prefixes
187
- const prefixes = [
188
- 'https://doi.org/',
189
- 'http://doi.org/',
190
- 'https://dx.doi.org/',
191
- 'http://dx.doi.org/',
192
- 'doi:',
193
- 'DOI:'
194
- ];
195
- for (const prefix of prefixes) {
196
- if (sanitized.toLowerCase().startsWith(prefix.toLowerCase())) {
197
- sanitized = sanitized.substring(prefix.length);
198
- break;
199
- }
200
- }
201
- // Basic DOI format validation
202
- // DOI should start with "10." followed by digits and then any characters
203
- const doiPattern = /^10\.\d{4,}(\.\d+)*\/\S+$/;
204
- if (!doiPattern.test(sanitized)) {
205
- return { valid: false, sanitized: '', error: 'Invalid DOI format' };
206
- }
207
- // Additional safety checks
208
- if (sanitized.length > 256) {
209
- return { valid: false, sanitized: '', error: 'DOI too long (max 256 characters)' };
210
- }
211
- // Check for suspicious patterns
212
- if (sanitized.includes('<') || sanitized.includes('>') ||
213
- sanitized.includes('"') || sanitized.includes("'")) {
214
- return { valid: false, sanitized: '', error: 'DOI contains invalid characters' };
215
- }
216
- return { valid: true, sanitized: sanitized };
217
- }
218
- /**
219
- * Escape query value for different contexts
220
- */
221
- export function escapeQueryValue(value, context = 'general') {
222
- if (!value)
223
- return '';
224
- // Remove null bytes and control characters
225
- let escaped = value.replace(/[\x00-\x1F\x7F]/g, '');
226
- switch (context) {
227
- case 'springer':
228
- escaped = escaped
229
- .replace(/"/g, '\\"') // Escape quotes
230
- .replace(/[()]/g, '') // Remove parentheses
231
- .replace(/;/g, '') // Remove semicolons
232
- .replace(/\/\*/g, '') // Remove SQL comment start
233
- .replace(/\*\//g, ''); // Remove SQL comment end
234
- break;
235
- case 'wos':
236
- // For WoS, only remove quotes and parentheses if not user-provided field query
237
- if (!escaped.includes('TS=') && !escaped.includes('TI=') &&
238
- !escaped.includes('AU=') && !escaped.includes('SO=')) {
239
- escaped = escaped
240
- .replace(/"/g, '') // Remove quotes
241
- .replace(/[()]/g, '') // Remove parentheses
242
- .trim();
243
- }
244
- break;
245
- default:
246
- escaped = escaped
247
- .replace(/["<>]/g, '') // Remove quotes and angle brackets
248
- .replace(/\/\/+/g, '') // Remove multiple slashes
249
- .trim();
250
- }
251
- // Length limit to prevent DoS
252
- if (escaped.length > 200) {
253
- escaped = escaped.substring(0, 200);
254
- }
255
- return escaped.trim();
256
- }
257
- /**
258
- * Validate query complexity to prevent DoS
259
- */
260
- export function validateQueryComplexity(query, options = {}) {
261
- const maxLength = options.maxLength || 1000;
262
- const maxBooleanOperators = options.maxBooleanOperators || 10;
263
- if (!query)
264
- return { valid: true };
265
- // Check length
266
- if (query.length > maxLength) {
267
- return {
268
- valid: false,
269
- error: `Query too long (max ${maxLength} characters)`
270
- };
271
- }
272
- // Count boolean operators
273
- const booleanOperators = query.match(/\b(AND|OR|NOT)\b/gi) || [];
274
- if (booleanOperators.length > maxBooleanOperators) {
275
- return {
276
- valid: false,
277
- error: `Query too complex (max ${maxBooleanOperators} boolean operators)`
278
- };
279
- }
280
- // Check for potential injection patterns
281
- const injectionPatterns = [
282
- /;\s*(drop|delete|update|insert|exec|union)/i,
283
- /\/\*.*\*\//s, // SQL comments
284
- /\/\/.*/, // Line comments
285
- /\b(select|insert|update|delete|drop|create|alter|exec|execute|union)\b.*\b(from|where|and|or)\b/i,
286
- /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/ // Control characters
287
- ];
288
- for (const pattern of injectionPatterns) {
289
- if (pattern.test(query)) {
290
- return {
291
- valid: false,
292
- error: 'Query contains potentially dangerous patterns'
293
- };
294
- }
295
- }
296
- return { valid: true };
297
- }
298
- /**
299
- * Create a timeout wrapper for promises
300
- */
301
- export function withTimeout(promise, ms, message) {
302
- let timer;
303
- const timeout = new Promise((_, reject) => {
304
- timer = setTimeout(() => {
305
- reject(new Error(message || `Operation timed out after ${ms}ms`));
306
- }, ms);
307
- });
308
- return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
309
- }
310
- /**
311
- * Generate a correlation ID for request tracking
312
- */
313
- export function generateCorrelationId() {
314
- return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
315
- }
316
- /**
317
- * Mask sensitive data in strings
318
- */
319
- export function maskSensitiveData(str) {
320
- if (!str || str.length < 8)
321
- return '***';
322
- const visibleChars = Math.min(4, Math.floor(str.length / 4));
323
- return str.substring(0, visibleChars) +
324
- '*'.repeat(str.length - visibleChars * 2) +
325
- str.substring(str.length - visibleChars);
326
- }
327
- /**
328
- * Check if a string looks like an API key or token
329
- */
330
- export function looksLikeToken(str) {
331
- if (!str || typeof str !== 'string')
332
- return false;
333
- // Common token patterns
334
- const tokenPatterns = [
335
- /^[a-zA-Z0-9_-]{20,}$/, // Long alphanumeric
336
- /^Bearer\s+[a-zA-Z0-9_-]+$/, // Bearer token
337
- /^Basic\s+[A-Za-z0-9+/=]+$/, // Basic auth
338
- /^[0-9a-f]{32,}$/i, // Hex token
339
- /^[A-Za-z0-9+/]{20,}={0,2}$/ // Base64-like
340
- ];
341
- return tokenPatterns.some(pattern => pattern.test(str));
342
- }
343
- export default {
344
- sanitizeRequest,
345
- sanitizeHeaders,
346
- sanitizeParams,
347
- sanitizeBody,
348
- sanitizeUrl,
349
- sanitizeDoi,
350
- escapeQueryValue,
351
- validateQueryComplexity,
352
- withTimeout,
353
- generateCorrelationId,
354
- maskSensitiveData,
355
- looksLikeToken
356
- };
1
+ export * from '../infrastructure/security/SecurityUtils.js';
2
+ export { default } from '../infrastructure/security/SecurityUtils.js';
357
3
  //# sourceMappingURL=SecurityUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityUtils.js","sourceRoot":"","sources":["../../src/utils/SecurityUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SecurityUtils.js","sourceRoot":"","sources":["../../src/utils/SecurityUtils.ts"],"names":[],"mappings":"AAAA,cAAc,6CAA6C,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,6CAA6C,CAAC"}
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.2",
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.