@synsci/cli-darwin-x64 1.1.71 → 1.1.72

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 (339) hide show
  1. package/bin/skills/citation-management/SKILL.md +1109 -0
  2. package/bin/skills/citation-management/assets/bibtex_template.bib +264 -0
  3. package/bin/skills/citation-management/assets/citation_checklist.md +386 -0
  4. package/bin/skills/citation-management/references/bibtex_formatting.md +908 -0
  5. package/bin/skills/citation-management/references/citation_validation.md +794 -0
  6. package/bin/skills/citation-management/references/google_scholar_search.md +725 -0
  7. package/bin/skills/citation-management/references/metadata_extraction.md +870 -0
  8. package/bin/skills/citation-management/references/pubmed_search.md +839 -0
  9. package/bin/skills/citation-management/scripts/doi_to_bibtex.py +182 -0
  10. package/bin/skills/citation-management/scripts/extract_metadata.py +570 -0
  11. package/bin/skills/citation-management/scripts/format_bibtex.py +349 -0
  12. package/bin/skills/citation-management/scripts/search_google_scholar.py +251 -0
  13. package/bin/skills/citation-management/scripts/search_pubmed.py +348 -0
  14. package/bin/skills/citation-management/scripts/validate_citations.py +494 -0
  15. package/bin/skills/clinical-decision-support/README.md +129 -0
  16. package/bin/skills/clinical-decision-support/SKILL.md +506 -0
  17. package/bin/skills/clinical-decision-support/assets/biomarker_report_template.tex +380 -0
  18. package/bin/skills/clinical-decision-support/assets/clinical_pathway_template.tex +222 -0
  19. package/bin/skills/clinical-decision-support/assets/cohort_analysis_template.tex +359 -0
  20. package/bin/skills/clinical-decision-support/assets/color_schemes.tex +149 -0
  21. package/bin/skills/clinical-decision-support/assets/example_gbm_cohort.md +208 -0
  22. package/bin/skills/clinical-decision-support/assets/recommendation_strength_guide.md +328 -0
  23. package/bin/skills/clinical-decision-support/assets/treatment_recommendation_template.tex +529 -0
  24. package/bin/skills/clinical-decision-support/references/biomarker_classification.md +719 -0
  25. package/bin/skills/clinical-decision-support/references/clinical_decision_algorithms.md +604 -0
  26. package/bin/skills/clinical-decision-support/references/evidence_synthesis.md +840 -0
  27. package/bin/skills/clinical-decision-support/references/outcome_analysis.md +640 -0
  28. package/bin/skills/clinical-decision-support/references/patient_cohort_analysis.md +427 -0
  29. package/bin/skills/clinical-decision-support/references/treatment_recommendations.md +521 -0
  30. package/bin/skills/clinical-decision-support/scripts/biomarker_classifier.py +383 -0
  31. package/bin/skills/clinical-decision-support/scripts/build_decision_tree.py +417 -0
  32. package/bin/skills/clinical-decision-support/scripts/create_cohort_tables.py +509 -0
  33. package/bin/skills/clinical-decision-support/scripts/generate_survival_analysis.py +441 -0
  34. package/bin/skills/clinical-decision-support/scripts/validate_cds_document.py +326 -0
  35. package/bin/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
  36. package/bin/skills/clinical-reports/README.md +236 -0
  37. package/bin/skills/clinical-reports/SKILL.md +1127 -0
  38. package/bin/skills/clinical-reports/assets/case_report_template.md +352 -0
  39. package/bin/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
  40. package/bin/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
  41. package/bin/skills/clinical-reports/assets/consult_note_template.md +305 -0
  42. package/bin/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
  43. package/bin/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
  44. package/bin/skills/clinical-reports/assets/history_physical_template.md +305 -0
  45. package/bin/skills/clinical-reports/assets/lab_report_template.md +309 -0
  46. package/bin/skills/clinical-reports/assets/pathology_report_template.md +249 -0
  47. package/bin/skills/clinical-reports/assets/quality_checklist.md +338 -0
  48. package/bin/skills/clinical-reports/assets/radiology_report_template.md +318 -0
  49. package/bin/skills/clinical-reports/assets/soap_note_template.md +253 -0
  50. package/bin/skills/clinical-reports/references/case_report_guidelines.md +570 -0
  51. package/bin/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
  52. package/bin/skills/clinical-reports/references/data_presentation.md +530 -0
  53. package/bin/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
  54. package/bin/skills/clinical-reports/references/medical_terminology.md +588 -0
  55. package/bin/skills/clinical-reports/references/patient_documentation.md +744 -0
  56. package/bin/skills/clinical-reports/references/peer_review_standards.md +585 -0
  57. package/bin/skills/clinical-reports/references/regulatory_compliance.md +577 -0
  58. package/bin/skills/clinical-reports/scripts/check_deidentification.py +332 -0
  59. package/bin/skills/clinical-reports/scripts/compliance_checker.py +78 -0
  60. package/bin/skills/clinical-reports/scripts/extract_clinical_data.py +97 -0
  61. package/bin/skills/clinical-reports/scripts/format_adverse_events.py +97 -0
  62. package/bin/skills/clinical-reports/scripts/generate_report_template.py +149 -0
  63. package/bin/skills/clinical-reports/scripts/terminology_validator.py +126 -0
  64. package/bin/skills/clinical-reports/scripts/validate_case_report.py +323 -0
  65. package/bin/skills/clinical-reports/scripts/validate_trial_report.py +88 -0
  66. package/bin/skills/fireworks-ai/SKILL.md +665 -0
  67. package/bin/skills/generate-image/SKILL.md +178 -0
  68. package/bin/skills/generate-image/scripts/generate_image.py +254 -0
  69. package/bin/skills/groq/SKILL.md +347 -0
  70. package/bin/skills/hypothesis-generation/SKILL.md +293 -0
  71. package/bin/skills/hypothesis-generation/assets/FORMATTING_GUIDE.md +672 -0
  72. package/bin/skills/hypothesis-generation/assets/hypothesis_generation.sty +307 -0
  73. package/bin/skills/hypothesis-generation/assets/hypothesis_report_template.tex +572 -0
  74. package/bin/skills/hypothesis-generation/references/experimental_design_patterns.md +329 -0
  75. package/bin/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +198 -0
  76. package/bin/skills/hypothesis-generation/references/literature_search_strategies.md +622 -0
  77. package/bin/skills/latex-posters/README.md +417 -0
  78. package/bin/skills/latex-posters/SKILL.md +1602 -0
  79. package/bin/skills/latex-posters/assets/baposter_template.tex +257 -0
  80. package/bin/skills/latex-posters/assets/beamerposter_template.tex +244 -0
  81. package/bin/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
  82. package/bin/skills/latex-posters/assets/tikzposter_template.tex +251 -0
  83. package/bin/skills/latex-posters/references/latex_poster_packages.md +745 -0
  84. package/bin/skills/latex-posters/references/poster_content_guide.md +748 -0
  85. package/bin/skills/latex-posters/references/poster_design_principles.md +806 -0
  86. package/bin/skills/latex-posters/references/poster_layout_design.md +900 -0
  87. package/bin/skills/latex-posters/scripts/review_poster.sh +214 -0
  88. package/bin/skills/literature-review/SKILL.md +641 -0
  89. package/bin/skills/literature-review/assets/review_template.md +412 -0
  90. package/bin/skills/literature-review/references/citation_styles.md +166 -0
  91. package/bin/skills/literature-review/references/database_strategies.md +455 -0
  92. package/bin/skills/literature-review/scripts/generate_pdf.py +184 -0
  93. package/bin/skills/literature-review/scripts/search_databases.py +310 -0
  94. package/bin/skills/literature-review/scripts/verify_citations.py +218 -0
  95. package/bin/skills/market-research-reports/SKILL.md +904 -0
  96. package/bin/skills/market-research-reports/assets/FORMATTING_GUIDE.md +428 -0
  97. package/bin/skills/market-research-reports/assets/market_report_template.tex +1380 -0
  98. package/bin/skills/market-research-reports/assets/market_research.sty +564 -0
  99. package/bin/skills/market-research-reports/references/data_analysis_patterns.md +548 -0
  100. package/bin/skills/market-research-reports/references/report_structure_guide.md +999 -0
  101. package/bin/skills/market-research-reports/references/visual_generation_guide.md +1077 -0
  102. package/bin/skills/market-research-reports/scripts/generate_market_visuals.py +472 -0
  103. package/bin/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
  104. package/bin/skills/markitdown/LICENSE.txt +22 -0
  105. package/bin/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
  106. package/bin/skills/markitdown/QUICK_REFERENCE.md +309 -0
  107. package/bin/skills/markitdown/README.md +184 -0
  108. package/bin/skills/markitdown/SKILL.md +486 -0
  109. package/bin/skills/markitdown/SKILL_SUMMARY.md +307 -0
  110. package/bin/skills/markitdown/assets/example_usage.md +463 -0
  111. package/bin/skills/markitdown/references/api_reference.md +399 -0
  112. package/bin/skills/markitdown/references/file_formats.md +542 -0
  113. package/bin/skills/markitdown/scripts/batch_convert.py +195 -0
  114. package/bin/skills/markitdown/scripts/convert_literature.py +262 -0
  115. package/bin/skills/markitdown/scripts/convert_with_ai.py +224 -0
  116. package/bin/skills/ml-paper-writing/SKILL.md +937 -0
  117. package/bin/skills/ml-paper-writing/references/checklists.md +361 -0
  118. package/bin/skills/ml-paper-writing/references/citation-workflow.md +562 -0
  119. package/bin/skills/ml-paper-writing/references/reviewer-guidelines.md +367 -0
  120. package/bin/skills/ml-paper-writing/references/sources.md +159 -0
  121. package/bin/skills/ml-paper-writing/references/writing-guide.md +476 -0
  122. package/bin/skills/ml-paper-writing/templates/README.md +251 -0
  123. package/bin/skills/ml-paper-writing/templates/aaai2026/README.md +534 -0
  124. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-supp.tex +144 -0
  125. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026-unified-template.tex +952 -0
  126. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bib +111 -0
  127. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.bst +1493 -0
  128. package/bin/skills/ml-paper-writing/templates/aaai2026/aaai2026.sty +315 -0
  129. package/bin/skills/ml-paper-writing/templates/acl/README.md +50 -0
  130. package/bin/skills/ml-paper-writing/templates/acl/acl.sty +312 -0
  131. package/bin/skills/ml-paper-writing/templates/acl/acl_latex.tex +377 -0
  132. package/bin/skills/ml-paper-writing/templates/acl/acl_lualatex.tex +101 -0
  133. package/bin/skills/ml-paper-writing/templates/acl/acl_natbib.bst +1940 -0
  134. package/bin/skills/ml-paper-writing/templates/acl/anthology.bib.txt +26 -0
  135. package/bin/skills/ml-paper-writing/templates/acl/custom.bib +70 -0
  136. package/bin/skills/ml-paper-writing/templates/acl/formatting.md +326 -0
  137. package/bin/skills/ml-paper-writing/templates/colm2025/README.md +3 -0
  138. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bib +11 -0
  139. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.bst +1440 -0
  140. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.pdf +0 -0
  141. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.sty +218 -0
  142. package/bin/skills/ml-paper-writing/templates/colm2025/colm2025_conference.tex +305 -0
  143. package/bin/skills/ml-paper-writing/templates/colm2025/fancyhdr.sty +485 -0
  144. package/bin/skills/ml-paper-writing/templates/colm2025/math_commands.tex +508 -0
  145. package/bin/skills/ml-paper-writing/templates/colm2025/natbib.sty +1246 -0
  146. package/bin/skills/ml-paper-writing/templates/iclr2026/fancyhdr.sty +485 -0
  147. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bib +24 -0
  148. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.bst +1440 -0
  149. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.pdf +0 -0
  150. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.sty +246 -0
  151. package/bin/skills/ml-paper-writing/templates/iclr2026/iclr2026_conference.tex +414 -0
  152. package/bin/skills/ml-paper-writing/templates/iclr2026/math_commands.tex +508 -0
  153. package/bin/skills/ml-paper-writing/templates/iclr2026/natbib.sty +1246 -0
  154. package/bin/skills/ml-paper-writing/templates/icml2026/algorithm.sty +79 -0
  155. package/bin/skills/ml-paper-writing/templates/icml2026/algorithmic.sty +201 -0
  156. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.bib +75 -0
  157. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.pdf +0 -0
  158. package/bin/skills/ml-paper-writing/templates/icml2026/example_paper.tex +662 -0
  159. package/bin/skills/ml-paper-writing/templates/icml2026/fancyhdr.sty +864 -0
  160. package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.bst +1443 -0
  161. package/bin/skills/ml-paper-writing/templates/icml2026/icml2026.sty +767 -0
  162. package/bin/skills/ml-paper-writing/templates/icml2026/icml_numpapers.pdf +0 -0
  163. package/bin/skills/ml-paper-writing/templates/neurips2025/Makefile +36 -0
  164. package/bin/skills/ml-paper-writing/templates/neurips2025/extra_pkgs.tex +53 -0
  165. package/bin/skills/ml-paper-writing/templates/neurips2025/main.tex +38 -0
  166. package/bin/skills/ml-paper-writing/templates/neurips2025/neurips.sty +382 -0
  167. package/bin/skills/paper-2-web/SKILL.md +491 -0
  168. package/bin/skills/paper-2-web/references/installation.md +141 -0
  169. package/bin/skills/paper-2-web/references/paper2poster.md +346 -0
  170. package/bin/skills/paper-2-web/references/paper2video.md +305 -0
  171. package/bin/skills/paper-2-web/references/paper2web.md +187 -0
  172. package/bin/skills/paper-2-web/references/usage_examples.md +436 -0
  173. package/bin/skills/peer-review/SKILL.md +702 -0
  174. package/bin/skills/peer-review/references/calibration_guidelines.md +196 -0
  175. package/bin/skills/peer-review/references/common_issues.md +552 -0
  176. package/bin/skills/peer-review/references/paper_mechanics.md +269 -0
  177. package/bin/skills/peer-review/references/reporting_standards.md +290 -0
  178. package/bin/skills/peer-review/references/scoring_rubric.md +239 -0
  179. package/bin/skills/pptx-posters/SKILL.md +410 -0
  180. package/bin/skills/pptx-posters/assets/poster_html_template.html +257 -0
  181. package/bin/skills/pptx-posters/assets/poster_quality_checklist.md +358 -0
  182. package/bin/skills/pptx-posters/references/poster_content_guide.md +748 -0
  183. package/bin/skills/pptx-posters/references/poster_design_principles.md +806 -0
  184. package/bin/skills/pptx-posters/references/poster_layout_design.md +900 -0
  185. package/bin/skills/research-grants/README.md +285 -0
  186. package/bin/skills/research-grants/SKILL.md +938 -0
  187. package/bin/skills/research-grants/assets/budget_justification_template.md +453 -0
  188. package/bin/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
  189. package/bin/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
  190. package/bin/skills/research-grants/references/broader_impacts.md +392 -0
  191. package/bin/skills/research-grants/references/darpa_guidelines.md +636 -0
  192. package/bin/skills/research-grants/references/doe_guidelines.md +586 -0
  193. package/bin/skills/research-grants/references/nih_guidelines.md +851 -0
  194. package/bin/skills/research-grants/references/nsf_guidelines.md +570 -0
  195. package/bin/skills/research-grants/references/specific_aims_guide.md +458 -0
  196. package/bin/skills/research-lookup/README.md +156 -0
  197. package/bin/skills/research-lookup/SKILL.md +606 -0
  198. package/bin/skills/research-lookup/examples.py +174 -0
  199. package/bin/skills/research-lookup/lookup.py +187 -0
  200. package/bin/skills/research-lookup/research_lookup.py +483 -0
  201. package/bin/skills/research-lookup/scripts/research_lookup.py +483 -0
  202. package/bin/skills/scholar-evaluation/SKILL.md +289 -0
  203. package/bin/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
  204. package/bin/skills/scholar-evaluation/scripts/calculate_scores.py +366 -0
  205. package/bin/skills/scientific-critical-thinking/SKILL.md +566 -0
  206. package/bin/skills/scientific-critical-thinking/references/common_biases.md +364 -0
  207. package/bin/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
  208. package/bin/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
  209. package/bin/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
  210. package/bin/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
  211. package/bin/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
  212. package/bin/skills/scientific-schematics/QUICK_REFERENCE.md +207 -0
  213. package/bin/skills/scientific-schematics/README.md +327 -0
  214. package/bin/skills/scientific-schematics/SKILL.md +615 -0
  215. package/bin/skills/scientific-schematics/example_usage.sh +89 -0
  216. package/bin/skills/scientific-schematics/references/best_practices.md +559 -0
  217. package/bin/skills/scientific-schematics/scripts/generate_schematic.py +135 -0
  218. package/bin/skills/scientific-schematics/scripts/generate_schematic_ai.py +807 -0
  219. package/bin/skills/scientific-schematics/test_ai_generation.py +243 -0
  220. package/bin/skills/scientific-slides/SKILL.md +942 -0
  221. package/bin/skills/scientific-slides/assets/timing_guidelines.md +597 -0
  222. package/bin/skills/scientific-slides/references/data_visualization_slides.md +708 -0
  223. package/bin/skills/scientific-slides/references/presentation_structure.md +642 -0
  224. package/bin/skills/scientific-slides/references/slide_design_principles.md +849 -0
  225. package/bin/skills/scientific-slides/references/talk_types_guide.md +687 -0
  226. package/bin/skills/scientific-slides/references/visual_review_workflow.md +775 -0
  227. package/bin/skills/scientific-slides/scripts/generate_slide_image.py +143 -0
  228. package/bin/skills/scientific-slides/scripts/generate_slide_image_ai.py +748 -0
  229. package/bin/skills/scientific-slides/scripts/pdf_to_images.py +201 -0
  230. package/bin/skills/scientific-slides/scripts/slides_to_pdf.py +220 -0
  231. package/bin/skills/scientific-slides/scripts/validate_presentation.py +367 -0
  232. package/bin/skills/scientific-writing/SKILL.md +714 -0
  233. package/bin/skills/scientific-writing/assets/REPORT_FORMATTING_GUIDE.md +574 -0
  234. package/bin/skills/scientific-writing/assets/scientific_report.sty +606 -0
  235. package/bin/skills/scientific-writing/assets/scientific_report_template.tex +449 -0
  236. package/bin/skills/scientific-writing/references/citation_styles.md +720 -0
  237. package/bin/skills/scientific-writing/references/figures_tables.md +806 -0
  238. package/bin/skills/scientific-writing/references/imrad_structure.md +686 -0
  239. package/bin/skills/scientific-writing/references/professional_report_formatting.md +664 -0
  240. package/bin/skills/scientific-writing/references/reporting_guidelines.md +748 -0
  241. package/bin/skills/scientific-writing/references/writing_principles.md +824 -0
  242. package/bin/skills/tinker/SKILL.md +2 -3
  243. package/bin/skills/together-ai/SKILL.md +722 -0
  244. package/bin/skills/treatment-plans/README.md +488 -0
  245. package/bin/skills/treatment-plans/SKILL.md +1579 -0
  246. package/bin/skills/treatment-plans/assets/STYLING_QUICK_REFERENCE.md +185 -0
  247. package/bin/skills/treatment-plans/assets/chronic_disease_management_plan.tex +665 -0
  248. package/bin/skills/treatment-plans/assets/general_medical_treatment_plan.tex +547 -0
  249. package/bin/skills/treatment-plans/assets/medical_treatment_plan.sty +222 -0
  250. package/bin/skills/treatment-plans/assets/mental_health_treatment_plan.tex +774 -0
  251. package/bin/skills/treatment-plans/assets/one_page_treatment_plan.tex +193 -0
  252. package/bin/skills/treatment-plans/assets/pain_management_plan.tex +799 -0
  253. package/bin/skills/treatment-plans/assets/perioperative_care_plan.tex +753 -0
  254. package/bin/skills/treatment-plans/assets/quality_checklist.md +471 -0
  255. package/bin/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +756 -0
  256. package/bin/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
  257. package/bin/skills/treatment-plans/references/intervention_guidelines.md +507 -0
  258. package/bin/skills/treatment-plans/references/regulatory_compliance.md +476 -0
  259. package/bin/skills/treatment-plans/references/specialty_specific_guidelines.md +655 -0
  260. package/bin/skills/treatment-plans/references/treatment_plan_standards.md +485 -0
  261. package/bin/skills/treatment-plans/scripts/check_completeness.py +322 -0
  262. package/bin/skills/treatment-plans/scripts/generate_template.py +233 -0
  263. package/bin/skills/treatment-plans/scripts/timeline_generator.py +385 -0
  264. package/bin/skills/treatment-plans/scripts/validate_treatment_plan.py +369 -0
  265. package/bin/skills/unsloth/SKILL.md +565 -47
  266. package/bin/skills/unsloth/docs/advanced-rl.md +222 -0
  267. package/bin/skills/unsloth/docs/chat-templates.md +141 -0
  268. package/bin/skills/unsloth/docs/datasets.md +489 -0
  269. package/bin/skills/unsloth/docs/docker-extended.md +99 -0
  270. package/bin/skills/unsloth/docs/dynamic-ggufs-2.0.md +116 -0
  271. package/bin/skills/unsloth/docs/dynamic-ggufs-aider.md +118 -0
  272. package/bin/skills/unsloth/docs/faq.md +91 -0
  273. package/bin/skills/unsloth/docs/fp16-vs-bf16.md +61 -0
  274. package/bin/skills/unsloth/docs/fp8-rl.md +224 -0
  275. package/bin/skills/unsloth/docs/glm-4.7-flash.md +997 -0
  276. package/bin/skills/unsloth/docs/inference-deployment-overview.md +17 -0
  277. package/bin/skills/unsloth/docs/inference.md +27 -0
  278. package/bin/skills/unsloth/docs/installation-docker.md +155 -0
  279. package/bin/skills/unsloth/docs/installation-pip.md +148 -0
  280. package/bin/skills/unsloth/docs/kernels-packing.md +190 -0
  281. package/bin/skills/unsloth/docs/kimi-k2.5.md +634 -0
  282. package/bin/skills/unsloth/docs/lm-studio.md +235 -0
  283. package/bin/skills/unsloth/docs/lora-hot-swapping.md +75 -0
  284. package/bin/skills/unsloth/docs/lora-hyperparameters.md +363 -0
  285. package/bin/skills/unsloth/docs/memory-efficient-rl.md +267 -0
  286. package/bin/skills/unsloth/docs/model-selection.md +70 -0
  287. package/bin/skills/unsloth/docs/models.md +532 -0
  288. package/bin/skills/unsloth/docs/multi-gpu-ddp.md +90 -0
  289. package/bin/skills/unsloth/docs/notebooks.md +223 -0
  290. package/bin/skills/unsloth/docs/overview.md +110 -0
  291. package/bin/skills/unsloth/docs/qwen3-coder-next-extended.md +900 -0
  292. package/bin/skills/unsloth/docs/qwen3-coder-next.md +900 -0
  293. package/bin/skills/unsloth/docs/requirements.md +45 -0
  294. package/bin/skills/unsloth/docs/reward-hacking.md +25 -0
  295. package/bin/skills/unsloth/docs/saving-to-gguf.md +138 -0
  296. package/bin/skills/unsloth/docs/saving-to-ollama.md +46 -0
  297. package/bin/skills/unsloth/docs/sglang-guide.md +278 -0
  298. package/bin/skills/unsloth/docs/speculative-decoding.md +70 -0
  299. package/bin/skills/unsloth/docs/tool-calling.md +334 -0
  300. package/bin/skills/unsloth/docs/troubleshooting-faq.md +204 -0
  301. package/bin/skills/unsloth/docs/troubleshooting-inference.md +26 -0
  302. package/bin/skills/unsloth/docs/tts-fine-tuning.md +149 -0
  303. package/bin/skills/unsloth/docs/tutorial-grpo.md +273 -0
  304. package/bin/skills/unsloth/docs/tutorial-llama3-ollama.md +356 -0
  305. package/bin/skills/unsloth/docs/vision-fine-tuning.md +135 -0
  306. package/bin/skills/unsloth/docs/vision-rl.md +170 -0
  307. package/bin/skills/unsloth/docs/vllm-engine-arguments.md +43 -0
  308. package/bin/skills/unsloth/docs/vllm-guide.md +98 -0
  309. package/bin/skills/venue-templates/SKILL.md +686 -0
  310. package/bin/skills/venue-templates/assets/examples/cell_summary_example.md +247 -0
  311. package/bin/skills/venue-templates/assets/examples/medical_structured_abstract.md +313 -0
  312. package/bin/skills/venue-templates/assets/examples/nature_abstract_examples.md +213 -0
  313. package/bin/skills/venue-templates/assets/examples/neurips_introduction_example.md +245 -0
  314. package/bin/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
  315. package/bin/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
  316. package/bin/skills/venue-templates/assets/journals/nature_article.tex +171 -0
  317. package/bin/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
  318. package/bin/skills/venue-templates/assets/journals/plos_one.tex +317 -0
  319. package/bin/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
  320. package/bin/skills/venue-templates/references/cell_press_style.md +483 -0
  321. package/bin/skills/venue-templates/references/conferences_formatting.md +564 -0
  322. package/bin/skills/venue-templates/references/cs_conference_style.md +463 -0
  323. package/bin/skills/venue-templates/references/grants_requirements.md +787 -0
  324. package/bin/skills/venue-templates/references/journals_formatting.md +486 -0
  325. package/bin/skills/venue-templates/references/medical_journal_styles.md +535 -0
  326. package/bin/skills/venue-templates/references/ml_conference_style.md +556 -0
  327. package/bin/skills/venue-templates/references/nature_science_style.md +405 -0
  328. package/bin/skills/venue-templates/references/posters_guidelines.md +628 -0
  329. package/bin/skills/venue-templates/references/reviewer_expectations.md +417 -0
  330. package/bin/skills/venue-templates/references/venue_writing_styles.md +321 -0
  331. package/bin/skills/venue-templates/scripts/customize_template.py +195 -0
  332. package/bin/skills/venue-templates/scripts/query_template.py +266 -0
  333. package/bin/skills/venue-templates/scripts/validate_format.py +250 -0
  334. package/bin/synsc +0 -0
  335. package/package.json +1 -1
  336. package/bin/skills/unsloth/references/index.md +0 -7
  337. package/bin/skills/unsloth/references/llms-full.md +0 -16799
  338. package/bin/skills/unsloth/references/llms-txt.md +0 -12044
  339. package/bin/skills/unsloth/references/llms.md +0 -82
@@ -0,0 +1,570 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Metadata Extraction Tool
4
+ Extract citation metadata from DOI, PMID, arXiv ID, or URL using various APIs.
5
+ """
6
+
7
+ import argparse
8
+ import json
9
+ import os
10
+ import re
11
+ import sys
12
+ import time
13
+ import xml.etree.ElementTree as ET
14
+ from typing import Dict, List, Optional, Tuple
15
+ from urllib.parse import urlparse
16
+
17
+ import requests
18
+
19
+
20
+ class MetadataExtractor:
21
+ """Extract metadata from various sources and generate BibTeX."""
22
+
23
+ def __init__(self, email: Optional[str] = None):
24
+ """
25
+ Initialize extractor.
26
+
27
+ Args:
28
+ email: Email for Entrez API (recommended for PubMed)
29
+ """
30
+ self.session = requests.Session()
31
+ self.session.headers.update({'User-Agent': 'MetadataExtractor/1.0 (Citation Management Tool)'})
32
+ self.email = email or os.getenv('NCBI_EMAIL', '')
33
+
34
+ def identify_type(self, identifier: str) -> Tuple[str, str]:
35
+ """
36
+ Identify the type of identifier.
37
+
38
+ Args:
39
+ identifier: DOI, PMID, arXiv ID, or URL
40
+
41
+ Returns:
42
+ Tuple of (type, cleaned_identifier)
43
+ """
44
+ identifier = identifier.strip()
45
+
46
+ # Check if URL
47
+ if identifier.startswith('http://') or identifier.startswith('https://'):
48
+ return self._parse_url(identifier)
49
+
50
+ # Check for DOI
51
+ if identifier.startswith('10.'):
52
+ return ('doi', identifier)
53
+
54
+ # Check for arXiv ID
55
+ if re.match(r'^\d{4}\.\d{4,5}(v\d+)?$', identifier):
56
+ return ('arxiv', identifier)
57
+ if identifier.startswith('arXiv:'):
58
+ return ('arxiv', identifier.replace('arXiv:', ''))
59
+
60
+ # Check for PMID (8-digit number typically)
61
+ if identifier.isdigit() and len(identifier) >= 7:
62
+ return ('pmid', identifier)
63
+
64
+ # Check for PMCID
65
+ if identifier.upper().startswith('PMC') and identifier[3:].isdigit():
66
+ return ('pmcid', identifier.upper())
67
+
68
+ return ('unknown', identifier)
69
+
70
+ def _parse_url(self, url: str) -> Tuple[str, str]:
71
+ """Parse URL to extract identifier type and value."""
72
+ parsed = urlparse(url)
73
+
74
+ # DOI URLs
75
+ if 'doi.org' in parsed.netloc:
76
+ doi = parsed.path.lstrip('/')
77
+ return ('doi', doi)
78
+
79
+ # PubMed URLs
80
+ if 'pubmed.ncbi.nlm.nih.gov' in parsed.netloc or 'ncbi.nlm.nih.gov/pubmed' in url:
81
+ pmid = re.search(r'/(\d+)', parsed.path)
82
+ if pmid:
83
+ return ('pmid', pmid.group(1))
84
+
85
+ # arXiv URLs
86
+ if 'arxiv.org' in parsed.netloc:
87
+ arxiv_id = re.search(r'/abs/(\d{4}\.\d{4,5})', parsed.path)
88
+ if arxiv_id:
89
+ return ('arxiv', arxiv_id.group(1))
90
+
91
+ # Nature, Science, Cell, etc. - try to extract DOI from URL
92
+ doi_match = re.search(r'10\.\d{4,}/[^\s/]+', url)
93
+ if doi_match:
94
+ return ('doi', doi_match.group())
95
+
96
+ return ('url', url)
97
+
98
+ def extract_from_doi(self, doi: str) -> Optional[Dict]:
99
+ """
100
+ Extract metadata from DOI using CrossRef API.
101
+
102
+ Args:
103
+ doi: Digital Object Identifier
104
+
105
+ Returns:
106
+ Metadata dictionary or None
107
+ """
108
+ url = f'https://api.crossref.org/works/{doi}'
109
+
110
+ try:
111
+ response = self.session.get(url, timeout=15)
112
+
113
+ if response.status_code == 200:
114
+ data = response.json()
115
+ message = data.get('message', {})
116
+
117
+ metadata = {
118
+ 'type': 'doi',
119
+ 'entry_type': self._crossref_type_to_bibtex(message.get('type')),
120
+ 'doi': doi,
121
+ 'title': message.get('title', [''])[0],
122
+ 'authors': self._format_authors_crossref(message.get('author', [])),
123
+ 'year': self._extract_year_crossref(message),
124
+ 'journal': message.get('container-title', [''])[0] if message.get('container-title') else '',
125
+ 'volume': str(message.get('volume', '')) if message.get('volume') else '',
126
+ 'issue': str(message.get('issue', '')) if message.get('issue') else '',
127
+ 'pages': message.get('page', ''),
128
+ 'publisher': message.get('publisher', ''),
129
+ 'url': f'https://doi.org/{doi}',
130
+ }
131
+
132
+ return metadata
133
+ else:
134
+ print(f'Error: CrossRef API returned status {response.status_code} for DOI: {doi}', file=sys.stderr)
135
+ return None
136
+
137
+ except Exception as e:
138
+ print(f'Error extracting metadata from DOI {doi}: {e}', file=sys.stderr)
139
+ return None
140
+
141
+ def extract_from_pmid(self, pmid: str) -> Optional[Dict]:
142
+ """
143
+ Extract metadata from PMID using PubMed E-utilities.
144
+
145
+ Args:
146
+ pmid: PubMed ID
147
+
148
+ Returns:
149
+ Metadata dictionary or None
150
+ """
151
+ url = 'https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi'
152
+ params = {'db': 'pubmed', 'id': pmid, 'retmode': 'xml', 'rettype': 'abstract'}
153
+
154
+ if self.email:
155
+ params['email'] = self.email
156
+
157
+ api_key = os.getenv('NCBI_API_KEY')
158
+ if api_key:
159
+ params['api_key'] = api_key
160
+
161
+ try:
162
+ response = self.session.get(url, params=params, timeout=15)
163
+
164
+ if response.status_code == 200:
165
+ root = ET.fromstring(response.content)
166
+ article = root.find('.//PubmedArticle')
167
+
168
+ if article is None:
169
+ print(f'Error: No article found for PMID: {pmid}', file=sys.stderr)
170
+ return None
171
+
172
+ # Extract metadata from XML
173
+ medline_citation = article.find('.//MedlineCitation')
174
+ article_elem = medline_citation.find('.//Article')
175
+ journal = article_elem.find('.//Journal')
176
+
177
+ # Get DOI if available
178
+ doi = None
179
+ article_ids = article.findall('.//ArticleId')
180
+ for article_id in article_ids:
181
+ if article_id.get('IdType') == 'doi':
182
+ doi = article_id.text
183
+ break
184
+
185
+ metadata = {
186
+ 'type': 'pmid',
187
+ 'entry_type': 'article',
188
+ 'pmid': pmid,
189
+ 'title': article_elem.findtext('.//ArticleTitle', ''),
190
+ 'authors': self._format_authors_pubmed(article_elem.findall('.//Author')),
191
+ 'year': self._extract_year_pubmed(article_elem),
192
+ 'journal': journal.findtext('.//Title', ''),
193
+ 'volume': journal.findtext('.//JournalIssue/Volume', ''),
194
+ 'issue': journal.findtext('.//JournalIssue/Issue', ''),
195
+ 'pages': article_elem.findtext('.//Pagination/MedlinePgn', ''),
196
+ 'doi': doi,
197
+ }
198
+
199
+ return metadata
200
+ else:
201
+ print(f'Error: PubMed API returned status {response.status_code} for PMID: {pmid}', file=sys.stderr)
202
+ return None
203
+
204
+ except Exception as e:
205
+ print(f'Error extracting metadata from PMID {pmid}: {e}', file=sys.stderr)
206
+ return None
207
+
208
+ def extract_from_arxiv(self, arxiv_id: str) -> Optional[Dict]:
209
+ """
210
+ Extract metadata from arXiv ID using arXiv API.
211
+
212
+ Args:
213
+ arxiv_id: arXiv identifier
214
+
215
+ Returns:
216
+ Metadata dictionary or None
217
+ """
218
+ url = 'http://export.arxiv.org/api/query'
219
+ params = {'id_list': arxiv_id, 'max_results': 1}
220
+
221
+ try:
222
+ response = self.session.get(url, params=params, timeout=15)
223
+
224
+ if response.status_code == 200:
225
+ # Parse Atom XML
226
+ root = ET.fromstring(response.content)
227
+ ns = {'atom': 'http://www.w3.org/2005/Atom', 'arxiv': 'http://arxiv.org/schemas/atom'}
228
+
229
+ entry = root.find('atom:entry', ns)
230
+ if entry is None:
231
+ print(f'Error: No entry found for arXiv ID: {arxiv_id}', file=sys.stderr)
232
+ return None
233
+
234
+ # Extract DOI if published
235
+ doi_elem = entry.find('arxiv:doi', ns)
236
+ doi = doi_elem.text if doi_elem is not None else None
237
+
238
+ # Extract journal reference if published
239
+ journal_ref_elem = entry.find('arxiv:journal_ref', ns)
240
+ journal_ref = journal_ref_elem.text if journal_ref_elem is not None else None
241
+
242
+ # Get publication date
243
+ published = entry.findtext('atom:published', '', ns)
244
+ year = published[:4] if published else ''
245
+
246
+ # Get authors
247
+ authors = []
248
+ for author in entry.findall('atom:author', ns):
249
+ name = author.findtext('atom:name', '', ns)
250
+ if name:
251
+ authors.append(name)
252
+
253
+ metadata = {
254
+ 'type': 'arxiv',
255
+ 'entry_type': 'misc' if not doi else 'article',
256
+ 'arxiv_id': arxiv_id,
257
+ 'title': entry.findtext('atom:title', '', ns).strip().replace('\n', ' '),
258
+ 'authors': ' and '.join(authors),
259
+ 'year': year,
260
+ 'doi': doi,
261
+ 'journal_ref': journal_ref,
262
+ 'abstract': entry.findtext('atom:summary', '', ns).strip().replace('\n', ' '),
263
+ 'url': f'https://arxiv.org/abs/{arxiv_id}',
264
+ }
265
+
266
+ return metadata
267
+ else:
268
+ print(f'Error: arXiv API returned status {response.status_code} for ID: {arxiv_id}', file=sys.stderr)
269
+ return None
270
+
271
+ except Exception as e:
272
+ print(f'Error extracting metadata from arXiv {arxiv_id}: {e}', file=sys.stderr)
273
+ return None
274
+
275
+ def metadata_to_bibtex(self, metadata: Dict, citation_key: Optional[str] = None) -> str:
276
+ """
277
+ Convert metadata dictionary to BibTeX format.
278
+
279
+ Args:
280
+ metadata: Metadata dictionary
281
+ citation_key: Optional custom citation key
282
+
283
+ Returns:
284
+ BibTeX string
285
+ """
286
+ if not citation_key:
287
+ citation_key = self._generate_citation_key(metadata)
288
+
289
+ entry_type = metadata.get('entry_type', 'misc')
290
+
291
+ # Build BibTeX entry
292
+ lines = [f'@{entry_type}{{{citation_key},']
293
+
294
+ # Add fields
295
+ if metadata.get('authors'):
296
+ lines.append(f' author = {{{metadata["authors"]}}},')
297
+
298
+ if metadata.get('title'):
299
+ # Protect capitalization
300
+ title = self._protect_title(metadata['title'])
301
+ lines.append(f' title = {{{title}}},')
302
+
303
+ if entry_type == 'article' and metadata.get('journal'):
304
+ lines.append(f' journal = {{{metadata["journal"]}}},')
305
+ elif entry_type == 'misc' and metadata.get('type') == 'arxiv':
306
+ lines.append(' howpublished = {arXiv},')
307
+
308
+ if metadata.get('year'):
309
+ lines.append(f' year = {{{metadata["year"]}}},')
310
+
311
+ if metadata.get('volume'):
312
+ lines.append(f' volume = {{{metadata["volume"]}}},')
313
+
314
+ if metadata.get('issue'):
315
+ lines.append(f' number = {{{metadata["issue"]}}},')
316
+
317
+ if metadata.get('pages'):
318
+ pages = metadata['pages'].replace('-', '--') # En-dash
319
+ lines.append(f' pages = {{{pages}}},')
320
+
321
+ if metadata.get('doi'):
322
+ lines.append(f' doi = {{{metadata["doi"]}}},')
323
+ elif metadata.get('url'):
324
+ lines.append(f' url = {{{metadata["url"]}}},')
325
+
326
+ if metadata.get('pmid'):
327
+ lines.append(f' note = {{PMID: {metadata["pmid"]}}},')
328
+
329
+ if metadata.get('type') == 'arxiv' and not metadata.get('doi'):
330
+ lines.append(' note = {Preprint},')
331
+
332
+ # Remove trailing comma from last field
333
+ if lines[-1].endswith(','):
334
+ lines[-1] = lines[-1][:-1]
335
+
336
+ lines.append('}')
337
+
338
+ return '\n'.join(lines)
339
+
340
+ def _crossref_type_to_bibtex(self, crossref_type: str) -> str:
341
+ """Map CrossRef type to BibTeX entry type."""
342
+ type_map = {
343
+ 'journal-article': 'article',
344
+ 'book': 'book',
345
+ 'book-chapter': 'incollection',
346
+ 'proceedings-article': 'inproceedings',
347
+ 'posted-content': 'misc',
348
+ 'dataset': 'misc',
349
+ 'report': 'techreport',
350
+ }
351
+ return type_map.get(crossref_type, 'misc')
352
+
353
+ def _format_authors_crossref(self, authors: List[Dict]) -> str:
354
+ """Format author list from CrossRef data."""
355
+ if not authors:
356
+ return ''
357
+
358
+ formatted = []
359
+ for author in authors:
360
+ given = author.get('given', '')
361
+ family = author.get('family', '')
362
+ if family:
363
+ if given:
364
+ formatted.append(f'{family}, {given}')
365
+ else:
366
+ formatted.append(family)
367
+
368
+ return ' and '.join(formatted)
369
+
370
+ def _format_authors_pubmed(self, authors: List) -> str:
371
+ """Format author list from PubMed XML."""
372
+ formatted = []
373
+ for author in authors:
374
+ last_name = author.findtext('.//LastName', '')
375
+ fore_name = author.findtext('.//ForeName', '')
376
+ if last_name:
377
+ if fore_name:
378
+ formatted.append(f'{last_name}, {fore_name}')
379
+ else:
380
+ formatted.append(last_name)
381
+
382
+ return ' and '.join(formatted)
383
+
384
+ def _extract_year_crossref(self, message: Dict) -> str:
385
+ """Extract year from CrossRef message."""
386
+ # Try published-print first, then published-online
387
+ date_parts = message.get('published-print', {}).get('date-parts', [[]])
388
+ if not date_parts or not date_parts[0]:
389
+ date_parts = message.get('published-online', {}).get('date-parts', [[]])
390
+
391
+ if date_parts and date_parts[0]:
392
+ return str(date_parts[0][0])
393
+ return ''
394
+
395
+ def _extract_year_pubmed(self, article: ET.Element) -> str:
396
+ """Extract year from PubMed XML."""
397
+ year = article.findtext('.//Journal/JournalIssue/PubDate/Year', '')
398
+ if not year:
399
+ medline_date = article.findtext('.//Journal/JournalIssue/PubDate/MedlineDate', '')
400
+ if medline_date:
401
+ year_match = re.search(r'\d{4}', medline_date)
402
+ if year_match:
403
+ year = year_match.group()
404
+ return year
405
+
406
+ def _generate_citation_key(self, metadata: Dict) -> str:
407
+ """Generate a citation key from metadata."""
408
+ # Get first author last name
409
+ authors = metadata.get('authors', '')
410
+ if authors:
411
+ first_author = authors.split(' and ')[0]
412
+ if ',' in first_author:
413
+ last_name = first_author.split(',')[0].strip()
414
+ else:
415
+ last_name = first_author.split()[-1] if first_author else 'Unknown'
416
+ else:
417
+ last_name = 'Unknown'
418
+
419
+ # Get year
420
+ year = metadata.get('year', '').strip()
421
+ if not year:
422
+ year = 'XXXX'
423
+
424
+ # Clean last name (remove special characters)
425
+ last_name = re.sub(r'[^a-zA-Z]', '', last_name)
426
+
427
+ # Get keyword from title
428
+ title = metadata.get('title', '')
429
+ words = re.findall(r'\b[a-zA-Z]{4,}\b', title)
430
+ keyword = words[0].lower() if words else 'paper'
431
+
432
+ return f'{last_name}{year}{keyword}'
433
+
434
+ def _protect_title(self, title: str) -> str:
435
+ """Protect capitalization in title for BibTeX."""
436
+ # Protect common acronyms and proper nouns
437
+ protected_words = [
438
+ 'DNA',
439
+ 'RNA',
440
+ 'CRISPR',
441
+ 'COVID',
442
+ 'HIV',
443
+ 'AIDS',
444
+ 'AlphaFold',
445
+ 'Python',
446
+ 'AI',
447
+ 'ML',
448
+ 'GPU',
449
+ 'CPU',
450
+ 'USA',
451
+ 'UK',
452
+ 'EU',
453
+ ]
454
+
455
+ for word in protected_words:
456
+ title = re.sub(rf'\b{word}\b', f'{{{word}}}', title, flags=re.IGNORECASE)
457
+
458
+ return title
459
+
460
+ def extract(self, identifier: str) -> Optional[str]:
461
+ """
462
+ Extract metadata and return BibTeX.
463
+
464
+ Args:
465
+ identifier: DOI, PMID, arXiv ID, or URL
466
+
467
+ Returns:
468
+ BibTeX string or None
469
+ """
470
+ id_type, clean_id = self.identify_type(identifier)
471
+
472
+ print(f'Identified as {id_type}: {clean_id}', file=sys.stderr)
473
+
474
+ metadata = None
475
+
476
+ if id_type == 'doi':
477
+ metadata = self.extract_from_doi(clean_id)
478
+ elif id_type == 'pmid':
479
+ metadata = self.extract_from_pmid(clean_id)
480
+ elif id_type == 'arxiv':
481
+ metadata = self.extract_from_arxiv(clean_id)
482
+ else:
483
+ print(f'Error: Unknown identifier type: {identifier}', file=sys.stderr)
484
+ return None
485
+
486
+ if metadata:
487
+ return self.metadata_to_bibtex(metadata)
488
+ else:
489
+ return None
490
+
491
+
492
+ def main():
493
+ """Command-line interface."""
494
+ parser = argparse.ArgumentParser(
495
+ description='Extract citation metadata from DOI, PMID, arXiv ID, or URL',
496
+ epilog='Example: python extract_metadata.py --doi 10.1038/s41586-021-03819-2',
497
+ )
498
+
499
+ parser.add_argument('--doi', help='Digital Object Identifier')
500
+ parser.add_argument('--pmid', help='PubMed ID')
501
+ parser.add_argument('--arxiv', help='arXiv ID')
502
+ parser.add_argument('--url', help='URL to article')
503
+ parser.add_argument('-i', '--input', help='Input file with identifiers (one per line)')
504
+ parser.add_argument('-o', '--output', help='Output file for BibTeX (default: stdout)')
505
+ parser.add_argument('--format', choices=['bibtex', 'json'], default='bibtex', help='Output format')
506
+ parser.add_argument('--email', help='Email for NCBI E-utilities (recommended)')
507
+
508
+ args = parser.parse_args()
509
+
510
+ # Collect identifiers
511
+ identifiers = []
512
+ if args.doi:
513
+ identifiers.append(args.doi)
514
+ if args.pmid:
515
+ identifiers.append(args.pmid)
516
+ if args.arxiv:
517
+ identifiers.append(args.arxiv)
518
+ if args.url:
519
+ identifiers.append(args.url)
520
+
521
+ if args.input:
522
+ try:
523
+ with open(args.input, 'r', encoding='utf-8') as f:
524
+ file_ids = [line.strip() for line in f if line.strip()]
525
+ identifiers.extend(file_ids)
526
+ except Exception as e:
527
+ print(f'Error reading input file: {e}', file=sys.stderr)
528
+ sys.exit(1)
529
+
530
+ if not identifiers:
531
+ parser.print_help()
532
+ sys.exit(1)
533
+
534
+ # Extract metadata
535
+ extractor = MetadataExtractor(email=args.email)
536
+ bibtex_entries = []
537
+
538
+ for i, identifier in enumerate(identifiers):
539
+ print(f'\nProcessing {i + 1}/{len(identifiers)}...', file=sys.stderr)
540
+ bibtex = extractor.extract(identifier)
541
+ if bibtex:
542
+ bibtex_entries.append(bibtex)
543
+
544
+ # Rate limiting
545
+ if i < len(identifiers) - 1:
546
+ time.sleep(0.5)
547
+
548
+ if not bibtex_entries:
549
+ print('Error: No successful extractions', file=sys.stderr)
550
+ sys.exit(1)
551
+
552
+ # Format output
553
+ if args.format == 'bibtex':
554
+ output = '\n\n'.join(bibtex_entries) + '\n'
555
+ else: # json
556
+ output = json.dumps({'count': len(bibtex_entries), 'entries': bibtex_entries}, indent=2)
557
+
558
+ # Write output
559
+ if args.output:
560
+ with open(args.output, 'w', encoding='utf-8') as f:
561
+ f.write(output)
562
+ print(f'\nSuccessfully wrote {len(bibtex_entries)} entries to {args.output}', file=sys.stderr)
563
+ else:
564
+ print(output)
565
+
566
+ print(f'\nExtracted {len(bibtex_entries)}/{len(identifiers)} entries', file=sys.stderr)
567
+
568
+
569
+ if __name__ == '__main__':
570
+ main()