scientific-writer 2.3.1__py3-none-any.whl

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 (315) hide show
  1. scientific_writer/.claude/WRITER.md +822 -0
  2. scientific_writer/.claude/settings.local.json +30 -0
  3. scientific_writer/.claude/skills/citation-management/SKILL.md +1046 -0
  4. scientific_writer/.claude/skills/citation-management/assets/bibtex_template.bib +264 -0
  5. scientific_writer/.claude/skills/citation-management/assets/citation_checklist.md +386 -0
  6. scientific_writer/.claude/skills/citation-management/references/bibtex_formatting.md +908 -0
  7. scientific_writer/.claude/skills/citation-management/references/citation_validation.md +794 -0
  8. scientific_writer/.claude/skills/citation-management/references/google_scholar_search.md +725 -0
  9. scientific_writer/.claude/skills/citation-management/references/metadata_extraction.md +870 -0
  10. scientific_writer/.claude/skills/citation-management/references/pubmed_search.md +839 -0
  11. scientific_writer/.claude/skills/citation-management/scripts/doi_to_bibtex.py +204 -0
  12. scientific_writer/.claude/skills/citation-management/scripts/extract_metadata.py +569 -0
  13. scientific_writer/.claude/skills/citation-management/scripts/format_bibtex.py +349 -0
  14. scientific_writer/.claude/skills/citation-management/scripts/search_google_scholar.py +282 -0
  15. scientific_writer/.claude/skills/citation-management/scripts/search_pubmed.py +398 -0
  16. scientific_writer/.claude/skills/citation-management/scripts/validate_citations.py +497 -0
  17. scientific_writer/.claude/skills/clinical-reports/IMPLEMENTATION_SUMMARY.md +641 -0
  18. scientific_writer/.claude/skills/clinical-reports/README.md +236 -0
  19. scientific_writer/.claude/skills/clinical-reports/SKILL.md +1088 -0
  20. scientific_writer/.claude/skills/clinical-reports/assets/case_report_template.md +352 -0
  21. scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_csr_template.md +353 -0
  22. scientific_writer/.claude/skills/clinical-reports/assets/clinical_trial_sae_template.md +359 -0
  23. scientific_writer/.claude/skills/clinical-reports/assets/consult_note_template.md +305 -0
  24. scientific_writer/.claude/skills/clinical-reports/assets/discharge_summary_template.md +453 -0
  25. scientific_writer/.claude/skills/clinical-reports/assets/hipaa_compliance_checklist.md +395 -0
  26. scientific_writer/.claude/skills/clinical-reports/assets/history_physical_template.md +305 -0
  27. scientific_writer/.claude/skills/clinical-reports/assets/lab_report_template.md +309 -0
  28. scientific_writer/.claude/skills/clinical-reports/assets/pathology_report_template.md +249 -0
  29. scientific_writer/.claude/skills/clinical-reports/assets/quality_checklist.md +338 -0
  30. scientific_writer/.claude/skills/clinical-reports/assets/radiology_report_template.md +318 -0
  31. scientific_writer/.claude/skills/clinical-reports/assets/soap_note_template.md +253 -0
  32. scientific_writer/.claude/skills/clinical-reports/references/case_report_guidelines.md +570 -0
  33. scientific_writer/.claude/skills/clinical-reports/references/clinical_trial_reporting.md +693 -0
  34. scientific_writer/.claude/skills/clinical-reports/references/data_presentation.md +530 -0
  35. scientific_writer/.claude/skills/clinical-reports/references/diagnostic_reports_standards.md +629 -0
  36. scientific_writer/.claude/skills/clinical-reports/references/medical_terminology.md +588 -0
  37. scientific_writer/.claude/skills/clinical-reports/references/patient_documentation.md +744 -0
  38. scientific_writer/.claude/skills/clinical-reports/references/peer_review_standards.md +585 -0
  39. scientific_writer/.claude/skills/clinical-reports/references/regulatory_compliance.md +577 -0
  40. scientific_writer/.claude/skills/clinical-reports/scripts/check_deidentification.py +346 -0
  41. scientific_writer/.claude/skills/clinical-reports/scripts/compliance_checker.py +78 -0
  42. scientific_writer/.claude/skills/clinical-reports/scripts/extract_clinical_data.py +102 -0
  43. scientific_writer/.claude/skills/clinical-reports/scripts/format_adverse_events.py +103 -0
  44. scientific_writer/.claude/skills/clinical-reports/scripts/generate_report_template.py +163 -0
  45. scientific_writer/.claude/skills/clinical-reports/scripts/terminology_validator.py +133 -0
  46. scientific_writer/.claude/skills/clinical-reports/scripts/validate_case_report.py +334 -0
  47. scientific_writer/.claude/skills/clinical-reports/scripts/validate_trial_report.py +89 -0
  48. scientific_writer/.claude/skills/document-skills/docx/LICENSE.txt +30 -0
  49. scientific_writer/.claude/skills/document-skills/docx/SKILL.md +197 -0
  50. scientific_writer/.claude/skills/document-skills/docx/docx-js.md +350 -0
  51. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  52. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  53. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  54. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  55. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  56. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  57. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  58. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  59. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  60. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  61. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  62. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  63. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  64. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  65. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  66. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  67. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  68. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  69. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  70. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  71. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  72. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  73. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  74. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  75. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  76. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  77. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  78. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  79. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  80. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  81. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  82. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  83. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  84. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  85. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  86. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  87. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  88. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  89. scientific_writer/.claude/skills/document-skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  90. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/pack.py +159 -0
  91. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/unpack.py +29 -0
  92. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validate.py +69 -0
  93. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  94. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/base.py +951 -0
  95. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/docx.py +274 -0
  96. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  97. scientific_writer/.claude/skills/document-skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  98. scientific_writer/.claude/skills/document-skills/docx/ooxml.md +610 -0
  99. scientific_writer/.claude/skills/document-skills/docx/scripts/__init__.py +1 -0
  100. scientific_writer/.claude/skills/document-skills/docx/scripts/document.py +1276 -0
  101. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/comments.xml +3 -0
  102. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtended.xml +3 -0
  103. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  104. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/commentsIds.xml +3 -0
  105. scientific_writer/.claude/skills/document-skills/docx/scripts/templates/people.xml +3 -0
  106. scientific_writer/.claude/skills/document-skills/docx/scripts/utilities.py +374 -0
  107. scientific_writer/.claude/skills/document-skills/pdf/LICENSE.txt +30 -0
  108. scientific_writer/.claude/skills/document-skills/pdf/SKILL.md +294 -0
  109. scientific_writer/.claude/skills/document-skills/pdf/forms.md +205 -0
  110. scientific_writer/.claude/skills/document-skills/pdf/reference.md +612 -0
  111. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes.py +70 -0
  112. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  113. scientific_writer/.claude/skills/document-skills/pdf/scripts/check_fillable_fields.py +12 -0
  114. scientific_writer/.claude/skills/document-skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  115. scientific_writer/.claude/skills/document-skills/pdf/scripts/create_validation_image.py +41 -0
  116. scientific_writer/.claude/skills/document-skills/pdf/scripts/extract_form_field_info.py +152 -0
  117. scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_fillable_fields.py +114 -0
  118. scientific_writer/.claude/skills/document-skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  119. scientific_writer/.claude/skills/document-skills/pptx/LICENSE.txt +30 -0
  120. scientific_writer/.claude/skills/document-skills/pptx/SKILL.md +484 -0
  121. scientific_writer/.claude/skills/document-skills/pptx/html2pptx.md +625 -0
  122. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  123. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  124. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  125. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  126. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  127. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  128. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  129. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  130. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  131. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  132. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  133. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  134. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  135. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  136. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  137. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  138. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  139. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  140. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  141. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  142. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  143. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  144. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  145. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  146. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  147. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  148. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  149. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  150. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  151. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  152. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  153. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  154. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  155. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  156. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  157. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  158. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  159. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  160. scientific_writer/.claude/skills/document-skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  161. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/pack.py +159 -0
  162. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/unpack.py +29 -0
  163. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validate.py +69 -0
  164. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  165. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/base.py +951 -0
  166. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  167. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  168. scientific_writer/.claude/skills/document-skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  169. scientific_writer/.claude/skills/document-skills/pptx/ooxml.md +427 -0
  170. scientific_writer/.claude/skills/document-skills/pptx/scripts/html2pptx.js +979 -0
  171. scientific_writer/.claude/skills/document-skills/pptx/scripts/inventory.py +1020 -0
  172. scientific_writer/.claude/skills/document-skills/pptx/scripts/rearrange.py +231 -0
  173. scientific_writer/.claude/skills/document-skills/pptx/scripts/replace.py +385 -0
  174. scientific_writer/.claude/skills/document-skills/pptx/scripts/thumbnail.py +450 -0
  175. scientific_writer/.claude/skills/document-skills/xlsx/LICENSE.txt +30 -0
  176. scientific_writer/.claude/skills/document-skills/xlsx/SKILL.md +289 -0
  177. scientific_writer/.claude/skills/document-skills/xlsx/recalc.py +178 -0
  178. scientific_writer/.claude/skills/hypothesis-generation/SKILL.md +155 -0
  179. scientific_writer/.claude/skills/hypothesis-generation/assets/hypothesis_output_template.md +302 -0
  180. scientific_writer/.claude/skills/hypothesis-generation/references/experimental_design_patterns.md +327 -0
  181. scientific_writer/.claude/skills/hypothesis-generation/references/hypothesis_quality_criteria.md +196 -0
  182. scientific_writer/.claude/skills/hypothesis-generation/references/literature_search_strategies.md +505 -0
  183. scientific_writer/.claude/skills/latex-posters/README.md +417 -0
  184. scientific_writer/.claude/skills/latex-posters/SKILL.md +919 -0
  185. scientific_writer/.claude/skills/latex-posters/assets/baposter_template.tex +257 -0
  186. scientific_writer/.claude/skills/latex-posters/assets/beamerposter_template.tex +244 -0
  187. scientific_writer/.claude/skills/latex-posters/assets/poster_quality_checklist.md +358 -0
  188. scientific_writer/.claude/skills/latex-posters/assets/tikzposter_template.tex +251 -0
  189. scientific_writer/.claude/skills/latex-posters/references/latex_poster_packages.md +745 -0
  190. scientific_writer/.claude/skills/latex-posters/references/poster_content_guide.md +748 -0
  191. scientific_writer/.claude/skills/latex-posters/references/poster_design_principles.md +806 -0
  192. scientific_writer/.claude/skills/latex-posters/references/poster_layout_design.md +900 -0
  193. scientific_writer/.claude/skills/latex-posters/scripts/review_poster.sh +214 -0
  194. scientific_writer/.claude/skills/literature-review/SKILL.md +546 -0
  195. scientific_writer/.claude/skills/literature-review/assets/review_template.md +412 -0
  196. scientific_writer/.claude/skills/literature-review/references/citation_styles.md +166 -0
  197. scientific_writer/.claude/skills/literature-review/references/database_strategies.md +381 -0
  198. scientific_writer/.claude/skills/literature-review/scripts/generate_pdf.py +176 -0
  199. scientific_writer/.claude/skills/literature-review/scripts/search_databases.py +303 -0
  200. scientific_writer/.claude/skills/literature-review/scripts/verify_citations.py +222 -0
  201. scientific_writer/.claude/skills/markitdown/INSTALLATION_GUIDE.md +318 -0
  202. scientific_writer/.claude/skills/markitdown/LICENSE.txt +22 -0
  203. scientific_writer/.claude/skills/markitdown/OPENROUTER_INTEGRATION.md +359 -0
  204. scientific_writer/.claude/skills/markitdown/QUICK_REFERENCE.md +309 -0
  205. scientific_writer/.claude/skills/markitdown/README.md +184 -0
  206. scientific_writer/.claude/skills/markitdown/SKILL.md +450 -0
  207. scientific_writer/.claude/skills/markitdown/SKILL_SUMMARY.md +307 -0
  208. scientific_writer/.claude/skills/markitdown/assets/example_usage.md +463 -0
  209. scientific_writer/.claude/skills/markitdown/references/api_reference.md +399 -0
  210. scientific_writer/.claude/skills/markitdown/references/file_formats.md +542 -0
  211. scientific_writer/.claude/skills/markitdown/scripts/batch_convert.py +228 -0
  212. scientific_writer/.claude/skills/markitdown/scripts/convert_literature.py +283 -0
  213. scientific_writer/.claude/skills/markitdown/scripts/convert_with_ai.py +243 -0
  214. scientific_writer/.claude/skills/paper-2-web/SKILL.md +455 -0
  215. scientific_writer/.claude/skills/paper-2-web/references/installation.md +141 -0
  216. scientific_writer/.claude/skills/paper-2-web/references/paper2poster.md +346 -0
  217. scientific_writer/.claude/skills/paper-2-web/references/paper2video.md +305 -0
  218. scientific_writer/.claude/skills/paper-2-web/references/paper2web.md +187 -0
  219. scientific_writer/.claude/skills/paper-2-web/references/usage_examples.md +436 -0
  220. scientific_writer/.claude/skills/peer-review/SKILL.md +375 -0
  221. scientific_writer/.claude/skills/peer-review/references/common_issues.md +552 -0
  222. scientific_writer/.claude/skills/peer-review/references/reporting_standards.md +290 -0
  223. scientific_writer/.claude/skills/research-grants/README.md +285 -0
  224. scientific_writer/.claude/skills/research-grants/SKILL.md +896 -0
  225. scientific_writer/.claude/skills/research-grants/assets/budget_justification_template.md +453 -0
  226. scientific_writer/.claude/skills/research-grants/assets/nih_specific_aims_template.md +166 -0
  227. scientific_writer/.claude/skills/research-grants/assets/nsf_project_summary_template.md +92 -0
  228. scientific_writer/.claude/skills/research-grants/references/broader_impacts.md +392 -0
  229. scientific_writer/.claude/skills/research-grants/references/darpa_guidelines.md +636 -0
  230. scientific_writer/.claude/skills/research-grants/references/doe_guidelines.md +586 -0
  231. scientific_writer/.claude/skills/research-grants/references/nih_guidelines.md +851 -0
  232. scientific_writer/.claude/skills/research-grants/references/nsf_guidelines.md +570 -0
  233. scientific_writer/.claude/skills/research-grants/references/specific_aims_guide.md +458 -0
  234. scientific_writer/.claude/skills/research-lookup/README.md +116 -0
  235. scientific_writer/.claude/skills/research-lookup/SKILL.md +443 -0
  236. scientific_writer/.claude/skills/research-lookup/examples.py +174 -0
  237. scientific_writer/.claude/skills/research-lookup/lookup.py +93 -0
  238. scientific_writer/.claude/skills/research-lookup/research_lookup.py +335 -0
  239. scientific_writer/.claude/skills/research-lookup/scripts/research_lookup.py +261 -0
  240. scientific_writer/.claude/skills/scholar-evaluation/SKILL.md +254 -0
  241. scientific_writer/.claude/skills/scholar-evaluation/references/evaluation_framework.md +663 -0
  242. scientific_writer/.claude/skills/scholar-evaluation/scripts/calculate_scores.py +378 -0
  243. scientific_writer/.claude/skills/scientific-critical-thinking/SKILL.md +530 -0
  244. scientific_writer/.claude/skills/scientific-critical-thinking/references/common_biases.md +364 -0
  245. scientific_writer/.claude/skills/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
  246. scientific_writer/.claude/skills/scientific-critical-thinking/references/experimental_design.md +496 -0
  247. scientific_writer/.claude/skills/scientific-critical-thinking/references/logical_fallacies.md +478 -0
  248. scientific_writer/.claude/skills/scientific-critical-thinking/references/scientific_method.md +169 -0
  249. scientific_writer/.claude/skills/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
  250. scientific_writer/.claude/skills/scientific-schematics/SKILL.md +2035 -0
  251. scientific_writer/.claude/skills/scientific-schematics/assets/block_diagram_template.tex +199 -0
  252. scientific_writer/.claude/skills/scientific-schematics/assets/circuit_template.tex +159 -0
  253. scientific_writer/.claude/skills/scientific-schematics/assets/flowchart_template.tex +161 -0
  254. scientific_writer/.claude/skills/scientific-schematics/assets/pathway_template.tex +162 -0
  255. scientific_writer/.claude/skills/scientific-schematics/assets/tikz_styles.tex +422 -0
  256. scientific_writer/.claude/skills/scientific-schematics/references/best_practices.md +562 -0
  257. scientific_writer/.claude/skills/scientific-schematics/references/diagram_types.md +637 -0
  258. scientific_writer/.claude/skills/scientific-schematics/references/python_libraries.md +791 -0
  259. scientific_writer/.claude/skills/scientific-schematics/references/tikz_guide.md +734 -0
  260. scientific_writer/.claude/skills/scientific-schematics/scripts/circuit_generator.py +307 -0
  261. scientific_writer/.claude/skills/scientific-schematics/scripts/compile_tikz.py +292 -0
  262. scientific_writer/.claude/skills/scientific-schematics/scripts/generate_flowchart.py +281 -0
  263. scientific_writer/.claude/skills/scientific-schematics/scripts/pathway_diagram.py +406 -0
  264. scientific_writer/.claude/skills/scientific-writing/SKILL.md +443 -0
  265. scientific_writer/.claude/skills/scientific-writing/references/citation_styles.md +720 -0
  266. scientific_writer/.claude/skills/scientific-writing/references/figures_tables.md +806 -0
  267. scientific_writer/.claude/skills/scientific-writing/references/imrad_structure.md +658 -0
  268. scientific_writer/.claude/skills/scientific-writing/references/reporting_guidelines.md +748 -0
  269. scientific_writer/.claude/skills/scientific-writing/references/writing_principles.md +824 -0
  270. scientific_writer/.claude/skills/treatment-plans/README.md +488 -0
  271. scientific_writer/.claude/skills/treatment-plans/SKILL.md +1536 -0
  272. scientific_writer/.claude/skills/treatment-plans/assets/STYLING_QUICK_REFERENCE.md +185 -0
  273. scientific_writer/.claude/skills/treatment-plans/assets/chronic_disease_management_plan.tex +665 -0
  274. scientific_writer/.claude/skills/treatment-plans/assets/general_medical_treatment_plan.tex +547 -0
  275. scientific_writer/.claude/skills/treatment-plans/assets/medical_treatment_plan.sty +222 -0
  276. scientific_writer/.claude/skills/treatment-plans/assets/mental_health_treatment_plan.tex +774 -0
  277. scientific_writer/.claude/skills/treatment-plans/assets/one_page_treatment_plan.tex +193 -0
  278. scientific_writer/.claude/skills/treatment-plans/assets/pain_management_plan.tex +799 -0
  279. scientific_writer/.claude/skills/treatment-plans/assets/perioperative_care_plan.tex +753 -0
  280. scientific_writer/.claude/skills/treatment-plans/assets/quality_checklist.md +471 -0
  281. scientific_writer/.claude/skills/treatment-plans/assets/rehabilitation_treatment_plan.tex +756 -0
  282. scientific_writer/.claude/skills/treatment-plans/references/goal_setting_frameworks.md +411 -0
  283. scientific_writer/.claude/skills/treatment-plans/references/intervention_guidelines.md +507 -0
  284. scientific_writer/.claude/skills/treatment-plans/references/regulatory_compliance.md +476 -0
  285. scientific_writer/.claude/skills/treatment-plans/references/specialty_specific_guidelines.md +655 -0
  286. scientific_writer/.claude/skills/treatment-plans/references/treatment_plan_standards.md +485 -0
  287. scientific_writer/.claude/skills/treatment-plans/scripts/check_completeness.py +318 -0
  288. scientific_writer/.claude/skills/treatment-plans/scripts/generate_template.py +244 -0
  289. scientific_writer/.claude/skills/treatment-plans/scripts/timeline_generator.py +369 -0
  290. scientific_writer/.claude/skills/treatment-plans/scripts/validate_treatment_plan.py +367 -0
  291. scientific_writer/.claude/skills/venue-templates/SKILL.md +590 -0
  292. scientific_writer/.claude/skills/venue-templates/assets/grants/nih_specific_aims.tex +235 -0
  293. scientific_writer/.claude/skills/venue-templates/assets/grants/nsf_proposal_template.tex +375 -0
  294. scientific_writer/.claude/skills/venue-templates/assets/journals/nature_article.tex +171 -0
  295. scientific_writer/.claude/skills/venue-templates/assets/journals/neurips_article.tex +283 -0
  296. scientific_writer/.claude/skills/venue-templates/assets/journals/plos_one.tex +317 -0
  297. scientific_writer/.claude/skills/venue-templates/assets/posters/beamerposter_academic.tex +311 -0
  298. scientific_writer/.claude/skills/venue-templates/references/conferences_formatting.md +564 -0
  299. scientific_writer/.claude/skills/venue-templates/references/grants_requirements.md +787 -0
  300. scientific_writer/.claude/skills/venue-templates/references/journals_formatting.md +486 -0
  301. scientific_writer/.claude/skills/venue-templates/references/posters_guidelines.md +628 -0
  302. scientific_writer/.claude/skills/venue-templates/scripts/customize_template.py +206 -0
  303. scientific_writer/.claude/skills/venue-templates/scripts/query_template.py +260 -0
  304. scientific_writer/.claude/skills/venue-templates/scripts/validate_format.py +255 -0
  305. scientific_writer/__init__.py +43 -0
  306. scientific_writer/api.py +393 -0
  307. scientific_writer/cli.py +326 -0
  308. scientific_writer/core.py +275 -0
  309. scientific_writer/models.py +76 -0
  310. scientific_writer/utils.py +289 -0
  311. scientific_writer-2.3.1.dist-info/METADATA +272 -0
  312. scientific_writer-2.3.1.dist-info/RECORD +315 -0
  313. scientific_writer-2.3.1.dist-info/WHEEL +4 -0
  314. scientific_writer-2.3.1.dist-info/entry_points.txt +2 -0
  315. scientific_writer-2.3.1.dist-info/licenses/LICENSE +22 -0
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Validate Format Script
4
+ Check if document meets venue-specific formatting requirements.
5
+
6
+ Usage:
7
+ python validate_format.py --file my_paper.pdf --venue "Nature" --check-all
8
+ python validate_format.py --file my_paper.pdf --venue "NeurIPS" --check page-count,margins
9
+ python validate_format.py --file my_paper.pdf --venue "PLOS ONE" --report validation_report.txt
10
+ """
11
+
12
+ import argparse
13
+ import subprocess
14
+ from pathlib import Path
15
+ import re
16
+
17
+ # Venue requirements database
18
+ VENUE_REQUIREMENTS = {
19
+ "nature": {
20
+ "page_limit": 5, # Approximate for ~3000 words
21
+ "margins": {"top": 2.5, "bottom": 2.5, "left": 2.5, "right": 2.5}, # cm
22
+ "font_size": 12, # pt
23
+ "font_family": "Times",
24
+ "line_spacing": "double"
25
+ },
26
+ "neurips": {
27
+ "page_limit": 8, # Excluding refs
28
+ "margins": {"top": 2.54, "bottom": 2.54, "left": 2.54, "right": 2.54}, # cm (1 inch)
29
+ "font_size": 10,
30
+ "font_family": "Times",
31
+ "format": "two-column"
32
+ },
33
+ "plos_one": {
34
+ "page_limit": None, # No limit
35
+ "margins": {"top": 2.54, "bottom": 2.54, "left": 2.54, "right": 2.54},
36
+ "font_size": 10,
37
+ "font_family": "Arial",
38
+ "line_spacing": "double"
39
+ },
40
+ "nsf": {
41
+ "page_limit": 15, # Project description
42
+ "margins": {"top": 2.54, "bottom": 2.54, "left": 2.54, "right": 2.54}, # 1 inch required
43
+ "font_size": 11, # Minimum
44
+ "font_family": "Times Roman",
45
+ "line_spacing": "single or double"
46
+ },
47
+ "nih": {
48
+ "page_limit": 12, # Research strategy
49
+ "margins": {"top": 1.27, "bottom": 1.27, "left": 1.27, "right": 1.27}, # 0.5 inch minimum
50
+ "font_size": 11, # Arial 11pt minimum
51
+ "font_family": "Arial",
52
+ "line_spacing": "any"
53
+ }
54
+ }
55
+
56
+ def get_pdf_info(pdf_path):
57
+ """Extract information from PDF using pdfinfo."""
58
+ try:
59
+ result = subprocess.run(
60
+ ['pdfinfo', str(pdf_path)],
61
+ capture_output=True,
62
+ text=True,
63
+ check=True
64
+ )
65
+
66
+ info = {}
67
+ for line in result.stdout.split('\n'):
68
+ if ':' in line:
69
+ key, value = line.split(':', 1)
70
+ info[key.strip()] = value.strip()
71
+
72
+ return info
73
+ except FileNotFoundError:
74
+ print("⚠️ pdfinfo not found. Install poppler-utils for full PDF analysis.")
75
+ print(" macOS: brew install poppler")
76
+ print(" Linux: sudo apt-get install poppler-utils")
77
+ return None
78
+ except subprocess.CalledProcessError as e:
79
+ print(f"Error running pdfinfo: {e}")
80
+ return None
81
+
82
+ def check_page_count(pdf_path, venue_reqs):
83
+ """Check if page count is within limit."""
84
+ pdf_info = get_pdf_info(pdf_path)
85
+
86
+ if not pdf_info:
87
+ return {"status": "skip", "message": "Could not determine page count"}
88
+
89
+ pages = int(pdf_info.get('Pages', 0))
90
+ limit = venue_reqs.get('page_limit')
91
+
92
+ if limit is None:
93
+ return {"status": "pass", "message": f"No page limit. Document has {pages} pages."}
94
+
95
+ if pages <= limit:
96
+ return {"status": "pass", "message": f"✓ Page count OK: {pages}/{limit} pages"}
97
+ else:
98
+ return {"status": "fail", "message": f"✗ Page count exceeded: {pages}/{limit} pages"}
99
+
100
+ def check_margins(pdf_path, venue_reqs):
101
+ """Check if margins meet requirements."""
102
+ # Note: This is a simplified check. Full margin analysis requires more sophisticated tools.
103
+ req_margins = venue_reqs.get('margins', {})
104
+
105
+ if not req_margins:
106
+ return {"status": "skip", "message": "No margin requirements specified"}
107
+
108
+ # This is a placeholder - accurate margin checking requires parsing PDF content
109
+ return {
110
+ "status": "info",
111
+ "message": f"ℹ️ Required margins: {req_margins} cm (manual verification recommended)"
112
+ }
113
+
114
+ def check_fonts(pdf_path, venue_reqs):
115
+ """Check fonts in PDF."""
116
+ try:
117
+ result = subprocess.run(
118
+ ['pdffonts', str(pdf_path)],
119
+ capture_output=True,
120
+ text=True,
121
+ check=True
122
+ )
123
+
124
+ fonts_found = []
125
+ for line in result.stdout.split('\n')[2:]: # Skip header
126
+ if line.strip():
127
+ parts = line.split()
128
+ if parts:
129
+ fonts_found.append(parts[0])
130
+
131
+ req_font = venue_reqs.get('font_family', '')
132
+ req_size = venue_reqs.get('font_size')
133
+
134
+ message = f"ℹ️ Fonts found: {', '.join(set(fonts_found))}\n"
135
+ message += f" Required: {req_font}"
136
+ if req_size:
137
+ message += f" {req_size}pt minimum"
138
+
139
+ return {"status": "info", "message": message}
140
+
141
+ except FileNotFoundError:
142
+ return {"status": "skip", "message": "pdffonts not available"}
143
+ except subprocess.CalledProcessError:
144
+ return {"status": "skip", "message": "Could not extract font information"}
145
+
146
+ def validate_document(pdf_path, venue, checks):
147
+ """Validate document against venue requirements."""
148
+
149
+ venue_key = venue.lower().replace(" ", "_")
150
+
151
+ if venue_key not in VENUE_REQUIREMENTS:
152
+ print(f"❌ Unknown venue: {venue}")
153
+ print(f"Available venues: {', '.join(VENUE_REQUIREMENTS.keys())}")
154
+ return
155
+
156
+ venue_reqs = VENUE_REQUIREMENTS[venue_key]
157
+
158
+ print(f"\n{'='*60}")
159
+ print(f"VALIDATING: {pdf_path.name}")
160
+ print(f"VENUE: {venue}")
161
+ print(f"{'='*60}\n")
162
+
163
+ results = {}
164
+
165
+ # Run requested checks
166
+ if 'page-count' in checks or 'all' in checks:
167
+ results['page-count'] = check_page_count(pdf_path, venue_reqs)
168
+
169
+ if 'margins' in checks or 'all' in checks:
170
+ results['margins'] = check_margins(pdf_path, venue_reqs)
171
+
172
+ if 'fonts' in checks or 'all' in checks:
173
+ results['fonts'] = check_fonts(pdf_path, venue_reqs)
174
+
175
+ # Print results
176
+ for check_name, result in results.items():
177
+ print(f"{check_name.upper()}:")
178
+ print(f" {result['message']}\n")
179
+
180
+ # Summary
181
+ failures = sum(1 for r in results.values() if r['status'] == 'fail')
182
+ passes = sum(1 for r in results.values() if r['status'] == 'pass')
183
+
184
+ print(f"{'='*60}")
185
+ if failures == 0:
186
+ print(f"✓ VALIDATION PASSED ({passes} checks)")
187
+ else:
188
+ print(f"✗ VALIDATION FAILED ({failures} issues)")
189
+ print(f"{'='*60}\n")
190
+
191
+ return results
192
+
193
+ def generate_report(pdf_path, venue, results, report_path):
194
+ """Generate validation report."""
195
+
196
+ with open(report_path, 'w') as f:
197
+ f.write(f"Validation Report\n")
198
+ f.write(f"{'='*60}\n\n")
199
+ f.write(f"File: {pdf_path}\n")
200
+ f.write(f"Venue: {venue}\n")
201
+ f.write(f"Date: {Path.ctime(pdf_path)}\n\n")
202
+
203
+ for check_name, result in results.items():
204
+ f.write(f"{check_name.upper()}:\n")
205
+ f.write(f" Status: {result['status']}\n")
206
+ f.write(f" {result['message']}\n\n")
207
+
208
+ failures = sum(1 for r in results.values() if r['status'] == 'fail')
209
+ f.write(f"\nSummary: {'PASSED' if failures == 0 else 'FAILED'}\n")
210
+
211
+ print(f"Report saved to: {report_path}")
212
+
213
+ def main():
214
+ parser = argparse.ArgumentParser(
215
+ description="Validate document formatting for venue requirements",
216
+ formatter_class=argparse.RawDescriptionHelpFormatter,
217
+ epilog="""
218
+ Examples:
219
+ %(prog)s --file my_paper.pdf --venue "Nature" --check-all
220
+ %(prog)s --file my_paper.pdf --venue "NeurIPS" --check page-count,fonts
221
+ %(prog)s --file proposal.pdf --venue "NSF" --report validation.txt
222
+ """
223
+ )
224
+
225
+ parser.add_argument('--file', type=str, required=True, help='PDF file to validate')
226
+ parser.add_argument('--venue', type=str, required=True, help='Target venue')
227
+ parser.add_argument('--check', type=str, default='all',
228
+ help='Checks to perform: page-count, margins, fonts, all (comma-separated)')
229
+ parser.add_argument('--check-all', action='store_true', help='Perform all checks')
230
+ parser.add_argument('--report', type=str, help='Save report to file')
231
+
232
+ args = parser.parse_args()
233
+
234
+ # Check file exists
235
+ pdf_path = Path(args.file)
236
+ if not pdf_path.exists():
237
+ print(f"Error: File not found: {pdf_path}")
238
+ return
239
+
240
+ # Parse checks
241
+ if args.check_all:
242
+ checks = ['all']
243
+ else:
244
+ checks = [c.strip() for c in args.check.split(',')]
245
+
246
+ # Validate
247
+ results = validate_document(pdf_path, args.venue, checks)
248
+
249
+ # Generate report if requested
250
+ if args.report and results:
251
+ generate_report(pdf_path, args.venue, results, Path(args.report))
252
+
253
+ if __name__ == "__main__":
254
+ main()
255
+
@@ -0,0 +1,43 @@
1
+ """
2
+ Scientific Writer - AI-powered scientific writing assistant.
3
+
4
+ A powerful Python package for generating scientific papers, literature reviews,
5
+ and academic documents using Claude Sonnet 4.5.
6
+
7
+ Example:
8
+ Generate a paper programmatically::
9
+
10
+ import asyncio
11
+ from scientific_writer import generate_paper
12
+
13
+ async def main():
14
+ async for update in generate_paper("Create a Nature paper on CRISPR"):
15
+ if update["type"] == "progress":
16
+ print(f"[{update['percentage']}%] {update['message']}")
17
+ else:
18
+ print(f"Paper created: {update['paper_directory']}")
19
+ print(f"PDF: {update['files']['pdf_final']}")
20
+
21
+ asyncio.run(main())
22
+
23
+ Use the CLI::
24
+
25
+ $ scientific-writer
26
+ > Create a NeurIPS paper on transformer attention mechanisms
27
+ """
28
+
29
+ from .api import generate_paper
30
+ from .models import ProgressUpdate, PaperResult, PaperMetadata, PaperFiles
31
+
32
+ __version__ = "2.3.1"
33
+ __author__ = "K-Dense"
34
+ __license__ = "MIT"
35
+
36
+ __all__ = [
37
+ "generate_paper",
38
+ "ProgressUpdate",
39
+ "PaperResult",
40
+ "PaperMetadata",
41
+ "PaperFiles",
42
+ ]
43
+
@@ -0,0 +1,393 @@
1
+ """Async API for programmatic scientific paper generation."""
2
+
3
+ import asyncio
4
+ import time
5
+ from pathlib import Path
6
+ from typing import Optional, List, Dict, Any, AsyncGenerator, Union
7
+ from datetime import datetime
8
+ from dotenv import load_dotenv
9
+
10
+ from claude_agent_sdk import query, ClaudeAgentOptions
11
+
12
+ from .core import (
13
+ get_api_key,
14
+ load_system_instructions,
15
+ ensure_output_folder,
16
+ get_data_files,
17
+ process_data_files,
18
+ create_data_context_message,
19
+ setup_claude_skills,
20
+ )
21
+ from .models import ProgressUpdate, PaperResult, PaperMetadata, PaperFiles
22
+ from .utils import (
23
+ scan_paper_directory,
24
+ count_citations_in_bib,
25
+ extract_citation_style,
26
+ count_words_in_tex,
27
+ extract_title_from_tex,
28
+ )
29
+
30
+
31
+ async def generate_paper(
32
+ query: str,
33
+ output_dir: Optional[str] = None,
34
+ api_key: Optional[str] = None,
35
+ model: str = "claude-sonnet-4-20250514",
36
+ data_files: Optional[List[str]] = None,
37
+ cwd: Optional[str] = None,
38
+ ) -> AsyncGenerator[Dict[str, Any], None]:
39
+ """
40
+ Generate a scientific paper asynchronously with progress updates.
41
+
42
+ This is a stateless async generator that yields progress updates during
43
+ execution and a final comprehensive result with all paper details.
44
+
45
+ Args:
46
+ query: The paper generation request (e.g., "Create a Nature paper on CRISPR")
47
+ output_dir: Optional custom output directory (defaults to cwd/paper_outputs)
48
+ api_key: Optional Anthropic API key (defaults to ANTHROPIC_API_KEY env var)
49
+ model: Claude model to use (default: claude-sonnet-4-20250514)
50
+ data_files: Optional list of data file paths to include
51
+ cwd: Optional working directory (defaults to package parent directory)
52
+
53
+ Yields:
54
+ Progress updates (dict with type="progress") during execution
55
+ Final result (dict with type="result") containing all paper information
56
+
57
+ Example:
58
+ ```python
59
+ async for update in generate_paper("Create a NeurIPS paper on transformers"):
60
+ if update["type"] == "progress":
61
+ print(f"[{update['percentage']}%] {update['message']}")
62
+ else:
63
+ print(f"Paper created: {update['paper_directory']}")
64
+ print(f"PDF: {update['files']['pdf_final']}")
65
+ ```
66
+ """
67
+ # Initialize
68
+ start_time = time.time()
69
+
70
+ # Explicitly load .env file from working directory
71
+ # Determine working directory first
72
+ if cwd:
73
+ work_dir = Path(cwd).resolve()
74
+ else:
75
+ work_dir = Path.cwd().resolve()
76
+
77
+ # Load .env from working directory
78
+ env_file = work_dir / ".env"
79
+ if env_file.exists():
80
+ load_dotenv(dotenv_path=env_file, override=True)
81
+
82
+ # Get API key
83
+ try:
84
+ api_key_value = get_api_key(api_key)
85
+ except ValueError as e:
86
+ yield _create_error_result(str(e))
87
+ return
88
+
89
+ # Get package directory for copying skills to working directory
90
+ package_dir = Path(__file__).parent.absolute() # scientific_writer/ directory
91
+
92
+ # Set up Claude skills in the working directory (includes WRITER.md)
93
+ setup_claude_skills(package_dir, work_dir)
94
+
95
+ # Ensure output folder exists in user's directory
96
+ output_folder = ensure_output_folder(work_dir, output_dir)
97
+
98
+ # Initial progress update
99
+ yield ProgressUpdate(
100
+ message="Initializing paper generation",
101
+ stage="initialization",
102
+ percentage=0,
103
+ ).to_dict()
104
+
105
+ # Load system instructions from .claude/WRITER.md in working directory
106
+ system_instructions = load_system_instructions(work_dir)
107
+
108
+ # Add conversation continuity instruction
109
+ system_instructions += "\n\n" + f"""
110
+ IMPORTANT - WORKING DIRECTORY:
111
+ - Your working directory is: {work_dir}
112
+ - ALWAYS create paper_outputs folder in this directory: {work_dir}/paper_outputs/
113
+ - NEVER write to /tmp/ or any other temporary directory
114
+ - All paper outputs MUST go to: {work_dir}/paper_outputs/<timestamp>_<description>/
115
+
116
+ IMPORTANT - CONVERSATION CONTINUITY:
117
+ - This is a NEW paper request - create a new paper directory
118
+ - Create a unique timestamped directory in the paper_outputs folder
119
+ - Do NOT assume there's an existing paper unless explicitly told in the prompt context
120
+ """
121
+
122
+ # Process data files if provided
123
+ data_context = ""
124
+ temp_paper_path = None
125
+
126
+ if data_files:
127
+ data_file_paths = get_data_files(work_dir, data_files)
128
+ if data_file_paths:
129
+ # We'll need to process these after the paper directory is created
130
+ yield ProgressUpdate(
131
+ message=f"Found {len(data_file_paths)} data file(s) to process",
132
+ stage="initialization",
133
+ percentage=5,
134
+ ).to_dict()
135
+
136
+ # Configure Claude agent options
137
+ options = ClaudeAgentOptions(
138
+ system_prompt=system_instructions,
139
+ model=model,
140
+ allowed_tools=["Read", "Write", "Edit", "Bash", "research-lookup"],
141
+ permission_mode="bypassPermissions",
142
+ setting_sources=["project"], # Load skills from project .claude directory
143
+ cwd=str(work_dir), # User's working directory
144
+ )
145
+
146
+ # Track progress through message analysis
147
+ current_stage = "initialization"
148
+ current_percentage = 10
149
+ paper_directory = None
150
+
151
+ yield ProgressUpdate(
152
+ message="Starting paper generation with Claude",
153
+ stage="initialization",
154
+ percentage=10,
155
+ ).to_dict()
156
+
157
+ # Execute query with Claude
158
+ try:
159
+ accumulated_text = ""
160
+ async for message in query(prompt=query, options=options):
161
+ if hasattr(message, "content") and message.content:
162
+ for block in message.content:
163
+ if hasattr(block, "text"):
164
+ text = block.text
165
+ accumulated_text += text
166
+
167
+ # Analyze text for progress indicators
168
+ stage, percentage, msg = _analyze_progress(accumulated_text, current_stage, current_percentage)
169
+
170
+ if stage != current_stage or percentage != current_percentage:
171
+ current_stage = stage
172
+ current_percentage = percentage
173
+
174
+ yield ProgressUpdate(
175
+ message=msg,
176
+ stage=stage,
177
+ percentage=percentage,
178
+ ).to_dict()
179
+
180
+ # Paper generation complete - now scan for results
181
+ yield ProgressUpdate(
182
+ message="Scanning paper output directory",
183
+ stage="complete",
184
+ percentage=95,
185
+ ).to_dict()
186
+
187
+ # Find the most recently created paper directory
188
+ paper_directory = _find_most_recent_paper(output_folder, start_time)
189
+
190
+ if not paper_directory:
191
+ yield _create_error_result("Paper directory not found after generation")
192
+ return
193
+
194
+ # Process any data files now if we have a paper directory
195
+ if data_files:
196
+ data_file_paths = get_data_files(work_dir, data_files)
197
+ if data_file_paths:
198
+ processed_info = process_data_files(
199
+ work_dir,
200
+ data_file_paths,
201
+ str(paper_directory),
202
+ delete_originals=False # Don't delete when using programmatic API
203
+ )
204
+ if processed_info:
205
+ manuscript_count = len(processed_info.get('manuscript_files', []))
206
+ message = f"Processed {len(processed_info['all_files'])} file(s)"
207
+ if manuscript_count > 0:
208
+ message += f" ({manuscript_count} manuscript(s) copied to drafts/)"
209
+ yield ProgressUpdate(
210
+ message=message,
211
+ stage="complete",
212
+ percentage=97,
213
+ ).to_dict()
214
+
215
+ # Scan the paper directory for all files
216
+ file_info = scan_paper_directory(paper_directory)
217
+
218
+ # Build comprehensive result
219
+ result = _build_paper_result(paper_directory, file_info)
220
+
221
+ yield ProgressUpdate(
222
+ message="Paper generation complete",
223
+ stage="complete",
224
+ percentage=100,
225
+ ).to_dict()
226
+
227
+ # Final result
228
+ yield result.to_dict()
229
+
230
+ except Exception as e:
231
+ yield _create_error_result(f"Error during paper generation: {str(e)}")
232
+
233
+
234
+ def _analyze_progress(text: str, current_stage: str, current_percentage: int) -> tuple:
235
+ """
236
+ Analyze accumulated text to determine current progress stage.
237
+
238
+ Returns:
239
+ Tuple of (stage, percentage, message)
240
+ """
241
+ text_lower = text.lower()
242
+
243
+ # Check for various progress indicators
244
+ if "research" in text_lower or "literature" in text_lower or "searching" in text_lower:
245
+ if current_stage != "research":
246
+ return "research", 30, "Conducting literature research"
247
+
248
+ if "writing" in text_lower or "introduction" in text_lower or "methods" in text_lower:
249
+ if current_stage != "writing":
250
+ return "writing", 50, "Writing paper sections"
251
+ elif current_percentage < 70:
252
+ return "writing", min(current_percentage + 10, 70), "Writing paper sections"
253
+
254
+ if "compil" in text_lower or "latex" in text_lower or "pdf" in text_lower:
255
+ if current_stage != "compilation":
256
+ return "compilation", 80, "Compiling LaTeX to PDF"
257
+
258
+ if "complete" in text_lower or "finished" in text_lower or "done" in text_lower:
259
+ return "complete", 90, "Finalizing paper"
260
+
261
+ # No change detected
262
+ return current_stage, current_percentage, "Processing..."
263
+
264
+
265
+ def _find_most_recent_paper(output_folder: Path, start_time: float) -> Optional[Path]:
266
+ """
267
+ Find the most recently created/modified paper directory.
268
+
269
+ Args:
270
+ output_folder: Path to paper_outputs folder
271
+ start_time: Start time of generation (to filter relevant directories)
272
+
273
+ Returns:
274
+ Path to paper directory or None
275
+ """
276
+ try:
277
+ paper_dirs = [d for d in output_folder.iterdir() if d.is_dir()]
278
+ if not paper_dirs:
279
+ return None
280
+
281
+ # Filter to only directories modified after start_time
282
+ recent_dirs = [
283
+ d for d in paper_dirs
284
+ if d.stat().st_mtime >= start_time - 5 # 5 second buffer
285
+ ]
286
+
287
+ if not recent_dirs:
288
+ # Fallback to most recent directory overall
289
+ recent_dirs = paper_dirs
290
+
291
+ # Return the most recent
292
+ most_recent = max(recent_dirs, key=lambda d: d.stat().st_mtime)
293
+ return most_recent
294
+ except Exception:
295
+ return None
296
+
297
+
298
+ def _build_paper_result(paper_dir: Path, file_info: Dict[str, Any]) -> PaperResult:
299
+ """
300
+ Build a comprehensive PaperResult from scanned files.
301
+
302
+ Args:
303
+ paper_dir: Path to paper directory
304
+ file_info: Dictionary of file information from scan_paper_directory
305
+
306
+ Returns:
307
+ PaperResult object
308
+ """
309
+ # Extract metadata
310
+ tex_file = file_info['tex_final'] or (file_info['tex_drafts'][0] if file_info['tex_drafts'] else None)
311
+
312
+ title = extract_title_from_tex(tex_file)
313
+ word_count = count_words_in_tex(tex_file)
314
+
315
+ # Extract topic from directory name
316
+ topic = ""
317
+ parts = paper_dir.name.split('_', 2)
318
+ if len(parts) >= 3:
319
+ topic = parts[2].replace('_', ' ')
320
+
321
+ metadata = PaperMetadata(
322
+ title=title,
323
+ created_at=datetime.fromtimestamp(paper_dir.stat().st_ctime).isoformat() + "Z",
324
+ topic=topic,
325
+ word_count=word_count,
326
+ )
327
+
328
+ # Build files object
329
+ files = PaperFiles(
330
+ pdf_final=file_info['pdf_final'],
331
+ tex_final=file_info['tex_final'],
332
+ pdf_drafts=file_info['pdf_drafts'],
333
+ tex_drafts=file_info['tex_drafts'],
334
+ bibliography=file_info['bibliography'],
335
+ figures=file_info['figures'],
336
+ data=file_info['data'],
337
+ progress_log=file_info['progress_log'],
338
+ summary=file_info['summary'],
339
+ )
340
+
341
+ # Citations info
342
+ citation_count = count_citations_in_bib(file_info['bibliography'])
343
+ citation_style = extract_citation_style(file_info['bibliography'])
344
+
345
+ citations = {
346
+ 'count': citation_count,
347
+ 'style': citation_style,
348
+ 'file': file_info['bibliography'],
349
+ }
350
+
351
+ # Determine status
352
+ status = "success"
353
+ compilation_success = file_info['pdf_final'] is not None
354
+
355
+ if not compilation_success:
356
+ if file_info['tex_final']:
357
+ status = "partial" # TeX created but PDF failed
358
+ else:
359
+ status = "failed"
360
+
361
+ result = PaperResult(
362
+ status=status,
363
+ paper_directory=str(paper_dir),
364
+ paper_name=paper_dir.name,
365
+ metadata=metadata,
366
+ files=files,
367
+ citations=citations,
368
+ figures_count=len(file_info['figures']),
369
+ compilation_success=compilation_success,
370
+ errors=[],
371
+ )
372
+
373
+ return result
374
+
375
+
376
+ def _create_error_result(error_message: str) -> Dict[str, Any]:
377
+ """
378
+ Create an error result dictionary.
379
+
380
+ Args:
381
+ error_message: Error message string
382
+
383
+ Returns:
384
+ Dictionary with error information
385
+ """
386
+ result = PaperResult(
387
+ status="failed",
388
+ paper_directory="",
389
+ paper_name="",
390
+ errors=[error_message],
391
+ )
392
+ return result.to_dict()
393
+