opencode-knowledge-work 0.0.0-stage → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/LICENSE +212 -0
  2. package/README.md +124 -2
  3. package/content/bio-research/.mcp.json +48 -0
  4. package/content/bio-research/CONNECTORS.md +23 -0
  5. package/content/bio-research/LICENSE +202 -0
  6. package/content/bio-research/README.md +83 -0
  7. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/LICENSE.txt +201 -0
  8. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/SKILL.md +280 -0
  9. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/references/asm_schema_overview.md +226 -0
  10. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/references/field_classification_guide.md +503 -0
  11. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/references/flattening_guide.md +254 -0
  12. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/references/supported_instruments.md +151 -0
  13. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/requirements.txt +26 -0
  14. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/scripts/convert_to_asm.py +543 -0
  15. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/scripts/export_parser.py +481 -0
  16. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/scripts/flatten_asm.py +254 -0
  17. package/content/bio-research/skills/bio-research-instrument-data-to-allotrope/scripts/validate_asm.py +1102 -0
  18. package/content/bio-research/skills/bio-research-nextflow-development/LICENSE.txt +201 -0
  19. package/content/bio-research/skills/bio-research-nextflow-development/SKILL.md +290 -0
  20. package/content/bio-research/skills/bio-research-nextflow-development/references/geo-sra-acquisition.md +416 -0
  21. package/content/bio-research/skills/bio-research-nextflow-development/references/installation.md +96 -0
  22. package/content/bio-research/skills/bio-research-nextflow-development/references/pipelines/atacseq.md +138 -0
  23. package/content/bio-research/skills/bio-research-nextflow-development/references/pipelines/rnaseq.md +118 -0
  24. package/content/bio-research/skills/bio-research-nextflow-development/references/pipelines/sarek.md +145 -0
  25. package/content/bio-research/skills/bio-research-nextflow-development/references/troubleshooting.md +137 -0
  26. package/content/bio-research/skills/bio-research-nextflow-development/scripts/check_environment.py +452 -0
  27. package/content/bio-research/skills/bio-research-nextflow-development/scripts/config/genomes.yaml +148 -0
  28. package/content/bio-research/skills/bio-research-nextflow-development/scripts/config/pipelines/atacseq.yaml +187 -0
  29. package/content/bio-research/skills/bio-research-nextflow-development/scripts/config/pipelines/rnaseq.yaml +147 -0
  30. package/content/bio-research/skills/bio-research-nextflow-development/scripts/config/pipelines/sarek.yaml +233 -0
  31. package/content/bio-research/skills/bio-research-nextflow-development/scripts/detect_data_type.py +300 -0
  32. package/content/bio-research/skills/bio-research-nextflow-development/scripts/generate_samplesheet.py +455 -0
  33. package/content/bio-research/skills/bio-research-nextflow-development/scripts/manage_genomes.py +521 -0
  34. package/content/bio-research/skills/bio-research-nextflow-development/scripts/sra_geo_fetch.py +732 -0
  35. package/content/bio-research/skills/bio-research-nextflow-development/scripts/utils/__init__.py +69 -0
  36. package/content/bio-research/skills/bio-research-nextflow-development/scripts/utils/file_discovery.py +189 -0
  37. package/content/bio-research/skills/bio-research-nextflow-development/scripts/utils/ncbi_utils.py +808 -0
  38. package/content/bio-research/skills/bio-research-nextflow-development/scripts/utils/sample_inference.py +290 -0
  39. package/content/bio-research/skills/bio-research-nextflow-development/scripts/utils/validators.py +256 -0
  40. package/content/bio-research/skills/bio-research-scientific-problem-selection/LICENSE.txt +201 -0
  41. package/content/bio-research/skills/bio-research-scientific-problem-selection/SKILL.md +269 -0
  42. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/01-intuition-pumps.md +264 -0
  43. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/02-risk-assessment.md +323 -0
  44. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/03-optimization-function.md +481 -0
  45. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/04-parameter-strategy.md +396 -0
  46. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/05-decision-tree.md +85 -0
  47. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/06-adversity-planning.md +123 -0
  48. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/07-problem-inversion.md +152 -0
  49. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/08-integration-synthesis.md +173 -0
  50. package/content/bio-research/skills/bio-research-scientific-problem-selection/references/09-meta-framework.md +504 -0
  51. package/content/bio-research/skills/bio-research-scvi-tools/LICENSE.txt +201 -0
  52. package/content/bio-research/skills/bio-research-scvi-tools/SKILL.md +155 -0
  53. package/content/bio-research/skills/bio-research-scvi-tools/references/atac_peakvi.md +398 -0
  54. package/content/bio-research/skills/bio-research-scvi-tools/references/batch_correction_sysvi.md +417 -0
  55. package/content/bio-research/skills/bio-research-scvi-tools/references/citeseq_totalvi.md +420 -0
  56. package/content/bio-research/skills/bio-research-scvi-tools/references/data_preparation.md +286 -0
  57. package/content/bio-research/skills/bio-research-scvi-tools/references/environment_setup.md +254 -0
  58. package/content/bio-research/skills/bio-research-scvi-tools/references/label_transfer.md +373 -0
  59. package/content/bio-research/skills/bio-research-scvi-tools/references/multiome_multivi.md +384 -0
  60. package/content/bio-research/skills/bio-research-scvi-tools/references/rna_velocity_velovi.md +410 -0
  61. package/content/bio-research/skills/bio-research-scvi-tools/references/scarches_mapping.md +401 -0
  62. package/content/bio-research/skills/bio-research-scvi-tools/references/scrna_integration.md +429 -0
  63. package/content/bio-research/skills/bio-research-scvi-tools/references/spatial_deconvolution.md +438 -0
  64. package/content/bio-research/skills/bio-research-scvi-tools/references/troubleshooting.md +420 -0
  65. package/content/bio-research/skills/bio-research-scvi-tools/scripts/cluster_embed.py +212 -0
  66. package/content/bio-research/skills/bio-research-scvi-tools/scripts/differential_expression.py +220 -0
  67. package/content/bio-research/skills/bio-research-scvi-tools/scripts/integrate_datasets.py +237 -0
  68. package/content/bio-research/skills/bio-research-scvi-tools/scripts/model_utils.py +634 -0
  69. package/content/bio-research/skills/bio-research-scvi-tools/scripts/prepare_data.py +169 -0
  70. package/content/bio-research/skills/bio-research-scvi-tools/scripts/train_model.py +370 -0
  71. package/content/bio-research/skills/bio-research-scvi-tools/scripts/transfer_labels.py +224 -0
  72. package/content/bio-research/skills/bio-research-scvi-tools/scripts/validate_adata.py +397 -0
  73. package/content/bio-research/skills/bio-research-single-cell-rna-qc/LICENSE.txt +201 -0
  74. package/content/bio-research/skills/bio-research-single-cell-rna-qc/SKILL.md +175 -0
  75. package/content/bio-research/skills/bio-research-single-cell-rna-qc/references/scverse_qc_guidelines.md +186 -0
  76. package/content/bio-research/skills/bio-research-single-cell-rna-qc/scripts/qc_analysis.py +232 -0
  77. package/content/bio-research/skills/bio-research-single-cell-rna-qc/scripts/qc_core.py +233 -0
  78. package/content/bio-research/skills/bio-research-single-cell-rna-qc/scripts/qc_plotting.py +235 -0
  79. package/content/bio-research/skills/bio-research-start/SKILL.md +79 -0
  80. package/content/customer-support/.mcp.json +40 -0
  81. package/content/customer-support/CONNECTORS.md +19 -0
  82. package/content/customer-support/LICENSE +202 -0
  83. package/content/customer-support/README.md +140 -0
  84. package/content/customer-support/skills/customer-support-customer-escalation/SKILL.md +248 -0
  85. package/content/customer-support/skills/customer-support-customer-research/SKILL.md +252 -0
  86. package/content/customer-support/skills/customer-support-draft-response/SKILL.md +418 -0
  87. package/content/customer-support/skills/customer-support-kb-article/SKILL.md +351 -0
  88. package/content/customer-support/skills/customer-support-ticket-triage/SKILL.md +275 -0
  89. package/content/data/.mcp.json +36 -0
  90. package/content/data/CONNECTORS.md +18 -0
  91. package/content/data/LICENSE +202 -0
  92. package/content/data/README.md +121 -0
  93. package/content/data/skills/data-analyze/SKILL.md +119 -0
  94. package/content/data/skills/data-build-dashboard/SKILL.md +924 -0
  95. package/content/data/skills/data-create-viz/SKILL.md +154 -0
  96. package/content/data/skills/data-data-context-extractor/SKILL.md +227 -0
  97. package/content/data/skills/data-data-context-extractor/references/domain-template.md +147 -0
  98. package/content/data/skills/data-data-context-extractor/references/example-output.md +198 -0
  99. package/content/data/skills/data-data-context-extractor/references/skill-template.md +148 -0
  100. package/content/data/skills/data-data-context-extractor/references/sql-dialects.md +121 -0
  101. package/content/data/skills/data-data-context-extractor/scripts/package_data_skill.py +126 -0
  102. package/content/data/skills/data-data-visualization/SKILL.md +305 -0
  103. package/content/data/skills/data-explore-data/SKILL.md +325 -0
  104. package/content/data/skills/data-sql-queries/SKILL.md +428 -0
  105. package/content/data/skills/data-statistical-analysis/SKILL.md +245 -0
  106. package/content/data/skills/data-validate-data/SKILL.md +383 -0
  107. package/content/data/skills/data-write-query/SKILL.md +122 -0
  108. package/content/design/.mcp.json +44 -0
  109. package/content/design/CONNECTORS.md +18 -0
  110. package/content/design/README.md +117 -0
  111. package/content/design/skills/design-accessibility-review/SKILL.md +128 -0
  112. package/content/design/skills/design-design-critique/SKILL.md +118 -0
  113. package/content/design/skills/design-design-handoff/SKILL.md +131 -0
  114. package/content/design/skills/design-design-system/SKILL.md +190 -0
  115. package/content/design/skills/design-research-synthesis/SKILL.md +92 -0
  116. package/content/design/skills/design-user-research/SKILL.md +41 -0
  117. package/content/design/skills/design-ux-copy/SKILL.md +107 -0
  118. package/content/engineering/.mcp.json +48 -0
  119. package/content/engineering/CONNECTORS.md +19 -0
  120. package/content/engineering/README.md +136 -0
  121. package/content/engineering/skills/engineering-architecture/SKILL.md +85 -0
  122. package/content/engineering/skills/engineering-code-review/SKILL.md +118 -0
  123. package/content/engineering/skills/engineering-debug/SKILL.md +95 -0
  124. package/content/engineering/skills/engineering-deploy-checklist/SKILL.md +78 -0
  125. package/content/engineering/skills/engineering-documentation/SKILL.md +49 -0
  126. package/content/engineering/skills/engineering-incident-response/SKILL.md +158 -0
  127. package/content/engineering/skills/engineering-standup/SKILL.md +75 -0
  128. package/content/engineering/skills/engineering-system-design/SKILL.md +42 -0
  129. package/content/engineering/skills/engineering-tech-debt/SKILL.md +32 -0
  130. package/content/engineering/skills/engineering-testing-strategy/SKILL.md +33 -0
  131. package/content/enterprise-search/.mcp.json +36 -0
  132. package/content/enterprise-search/CONNECTORS.md +21 -0
  133. package/content/enterprise-search/LICENSE +202 -0
  134. package/content/enterprise-search/README.md +157 -0
  135. package/content/enterprise-search/skills/enterprise-search-digest/SKILL.md +173 -0
  136. package/content/enterprise-search/skills/enterprise-search-knowledge-synthesis/SKILL.md +258 -0
  137. package/content/enterprise-search/skills/enterprise-search-search/SKILL.md +178 -0
  138. package/content/enterprise-search/skills/enterprise-search-search-strategy/SKILL.md +222 -0
  139. package/content/enterprise-search/skills/enterprise-search-source-management/SKILL.md +173 -0
  140. package/content/finance/.mcp.json +32 -0
  141. package/content/finance/CONNECTORS.md +20 -0
  142. package/content/finance/LICENSE +202 -0
  143. package/content/finance/README.md +92 -0
  144. package/content/finance/skills/finance-audit-support/SKILL.md +374 -0
  145. package/content/finance/skills/finance-close-management/SKILL.md +221 -0
  146. package/content/finance/skills/finance-financial-statements/SKILL.md +335 -0
  147. package/content/finance/skills/finance-journal-entry/SKILL.md +131 -0
  148. package/content/finance/skills/finance-journal-entry-prep/SKILL.md +186 -0
  149. package/content/finance/skills/finance-reconciliation/SKILL.md +175 -0
  150. package/content/finance/skills/finance-sox-testing/SKILL.md +218 -0
  151. package/content/finance/skills/finance-variance-analysis/SKILL.md +266 -0
  152. package/content/human-resources/.mcp.json +28 -0
  153. package/content/human-resources/CONNECTORS.md +19 -0
  154. package/content/human-resources/README.md +138 -0
  155. package/content/human-resources/skills/human-resources-comp-analysis/SKILL.md +92 -0
  156. package/content/human-resources/skills/human-resources-draft-offer/SKILL.md +82 -0
  157. package/content/human-resources/skills/human-resources-interview-prep/SKILL.md +37 -0
  158. package/content/human-resources/skills/human-resources-onboarding/SKILL.md +104 -0
  159. package/content/human-resources/skills/human-resources-org-planning/SKILL.md +28 -0
  160. package/content/human-resources/skills/human-resources-people-report/SKILL.md +99 -0
  161. package/content/human-resources/skills/human-resources-performance-review/SKILL.md +149 -0
  162. package/content/human-resources/skills/human-resources-policy-lookup/SKILL.md +94 -0
  163. package/content/human-resources/skills/human-resources-recruiting-pipeline/SKILL.md +31 -0
  164. package/content/legal/.mcp.json +36 -0
  165. package/content/legal/CONNECTORS.md +21 -0
  166. package/content/legal/LICENSE +202 -0
  167. package/content/legal/README.md +234 -0
  168. package/content/legal/skills/legal-brief/SKILL.md +208 -0
  169. package/content/legal/skills/legal-compliance-check/SKILL.md +274 -0
  170. package/content/legal/skills/legal-legal-response/SKILL.md +457 -0
  171. package/content/legal/skills/legal-legal-risk-assessment/SKILL.md +265 -0
  172. package/content/legal/skills/legal-meeting-briefing/SKILL.md +220 -0
  173. package/content/legal/skills/legal-review-contract/SKILL.md +358 -0
  174. package/content/legal/skills/legal-signature-request/SKILL.md +104 -0
  175. package/content/legal/skills/legal-triage-nda/SKILL.md +262 -0
  176. package/content/legal/skills/legal-vendor-check/SKILL.md +159 -0
  177. package/content/manifest.json +86 -0
  178. package/content/marketing/.mcp.json +60 -0
  179. package/content/marketing/CONNECTORS.md +20 -0
  180. package/content/marketing/LICENSE +202 -0
  181. package/content/marketing/README.md +90 -0
  182. package/content/marketing/skills/marketing-brand-review/SKILL.md +276 -0
  183. package/content/marketing/skills/marketing-campaign-plan/SKILL.md +308 -0
  184. package/content/marketing/skills/marketing-competitive-brief/SKILL.md +331 -0
  185. package/content/marketing/skills/marketing-content-creation/SKILL.md +157 -0
  186. package/content/marketing/skills/marketing-draft-content/SKILL.md +117 -0
  187. package/content/marketing/skills/marketing-email-sequence/SKILL.md +220 -0
  188. package/content/marketing/skills/marketing-performance-report/SKILL.md +392 -0
  189. package/content/marketing/skills/marketing-seo-audit/SKILL.md +190 -0
  190. package/content/operations/.mcp.json +32 -0
  191. package/content/operations/CONNECTORS.md +20 -0
  192. package/content/operations/README.md +135 -0
  193. package/content/operations/skills/operations-capacity-plan/SKILL.md +113 -0
  194. package/content/operations/skills/operations-change-request/SKILL.md +121 -0
  195. package/content/operations/skills/operations-compliance-tracking/SKILL.md +44 -0
  196. package/content/operations/skills/operations-process-doc/SKILL.md +82 -0
  197. package/content/operations/skills/operations-process-optimization/SKILL.md +39 -0
  198. package/content/operations/skills/operations-risk-assessment/SKILL.md +40 -0
  199. package/content/operations/skills/operations-runbook/SKILL.md +87 -0
  200. package/content/operations/skills/operations-status-report/SKILL.md +77 -0
  201. package/content/operations/skills/operations-vendor-review/SKILL.md +104 -0
  202. package/content/pdf-viewer/.mcp.json +8 -0
  203. package/content/pdf-viewer/CONNECTORS.md +15 -0
  204. package/content/pdf-viewer/LICENSE +202 -0
  205. package/content/pdf-viewer/README.md +57 -0
  206. package/content/pdf-viewer/commands/annotate.md +51 -0
  207. package/content/pdf-viewer/commands/fill-form.md +73 -0
  208. package/content/pdf-viewer/commands/open.md +34 -0
  209. package/content/pdf-viewer/commands/sign.md +54 -0
  210. package/content/pdf-viewer/skills/pdf-viewer-view-pdf/SKILL.md +147 -0
  211. package/content/product-management/.mcp.json +72 -0
  212. package/content/product-management/CONNECTORS.md +22 -0
  213. package/content/product-management/LICENSE +202 -0
  214. package/content/product-management/README.md +118 -0
  215. package/content/product-management/commands/brainstorm.md +120 -0
  216. package/content/product-management/skills/product-management-competitive-brief/SKILL.md +302 -0
  217. package/content/product-management/skills/product-management-metrics-review/SKILL.md +388 -0
  218. package/content/product-management/skills/product-management-product-brainstorming/SKILL.md +273 -0
  219. package/content/product-management/skills/product-management-roadmap-update/SKILL.md +266 -0
  220. package/content/product-management/skills/product-management-sprint-planning/SKILL.md +94 -0
  221. package/content/product-management/skills/product-management-stakeholder-update/SKILL.md +352 -0
  222. package/content/product-management/skills/product-management-synthesize-research/SKILL.md +312 -0
  223. package/content/product-management/skills/product-management-write-spec/SKILL.md +250 -0
  224. package/content/productivity/.mcp.json +44 -0
  225. package/content/productivity/CONNECTORS.md +18 -0
  226. package/content/productivity/LICENSE +202 -0
  227. package/content/productivity/README.md +97 -0
  228. package/content/productivity/skills/dashboard.html +3111 -0
  229. package/content/productivity/skills/productivity-memory-management/SKILL.md +323 -0
  230. package/content/productivity/skills/productivity-start/SKILL.md +158 -0
  231. package/content/productivity/skills/productivity-task-management/SKILL.md +91 -0
  232. package/content/productivity/skills/productivity-update/SKILL.md +168 -0
  233. package/content/sales/.mcp.json +100 -0
  234. package/content/sales/CONNECTORS.md +36 -0
  235. package/content/sales/LICENSE +202 -0
  236. package/content/sales/README.md +148 -0
  237. package/content/sales/skills/sales-account-context/SKILL.md +94 -0
  238. package/content/sales/skills/sales-account-plan/SKILL.md +95 -0
  239. package/content/sales/skills/sales-account-research/SKILL.md +99 -0
  240. package/content/sales/skills/sales-account-tiering/SKILL.md +101 -0
  241. package/content/sales/skills/sales-call-prep/SKILL.md +111 -0
  242. package/content/sales/skills/sales-call-summary/SKILL.md +111 -0
  243. package/content/sales/skills/sales-close-plan/SKILL.md +106 -0
  244. package/content/sales/skills/sales-competitive-intelligence/SKILL.md +102 -0
  245. package/content/sales/skills/sales-create-an-asset/SKILL.md +105 -0
  246. package/content/sales/skills/sales-crm-hygiene-check/SKILL.md +103 -0
  247. package/content/sales/skills/sales-customer-health/SKILL.md +108 -0
  248. package/content/sales/skills/sales-customer-voice/SKILL.md +94 -0
  249. package/content/sales/skills/sales-daily-briefing/SKILL.md +61 -0
  250. package/content/sales/skills/sales-deal-advance-gap/SKILL.md +102 -0
  251. package/content/sales/skills/sales-deal-review/SKILL.md +105 -0
  252. package/content/sales/skills/sales-deal-signals/SKILL.md +96 -0
  253. package/content/sales/skills/sales-deal-slip-scenario/SKILL.md +101 -0
  254. package/content/sales/skills/sales-draft-outreach/SKILL.md +116 -0
  255. package/content/sales/skills/sales-end-of-day/SKILL.md +114 -0
  256. package/content/sales/skills/sales-expansion-whitespace/SKILL.md +97 -0
  257. package/content/sales/skills/sales-forecast/SKILL.md +100 -0
  258. package/content/sales/skills/sales-handle-objection/SKILL.md +93 -0
  259. package/content/sales/skills/sales-inbox-sweep/SKILL.md +114 -0
  260. package/content/sales/skills/sales-lead-triage/SKILL.md +105 -0
  261. package/content/sales/skills/sales-log-activity/SKILL.md +111 -0
  262. package/content/sales/skills/sales-pipeline-review/SKILL.md +97 -0
  263. package/content/sales/skills/sales-renewal-radar/SKILL.md +95 -0
  264. package/content/sales/skills/sales-rep-context/SKILL.md +90 -0
  265. package/content/sales/skills/sales-route-lead/SKILL.md +111 -0
  266. package/content/sales/skills/sales-schedule-meeting/SKILL.md +99 -0
  267. package/content/sales/skills/sales-setup/SKILL.md +195 -0
  268. package/content/sales/skills/sales-stakeholder-map/SKILL.md +107 -0
  269. package/content/sales/skills/sales-team-pipeline/SKILL.md +105 -0
  270. package/content/sales/skills/sales-update-opportunity/SKILL.md +111 -0
  271. package/content/sales/skills/sales-weekly-wrap/SKILL.md +90 -0
  272. package/content/sales/skills/sales-win-loss-review/SKILL.md +88 -0
  273. package/content/small-business/.mcp.json +148 -0
  274. package/content/small-business/README.md +117 -0
  275. package/content/small-business/skills/small-business-ad-manager/SKILL.md +128 -0
  276. package/content/small-business/skills/small-business-ad-manager/reference/ad_copy.md +112 -0
  277. package/content/small-business/skills/small-business-ad-manager/reference/change_playbook.md +127 -0
  278. package/content/small-business/skills/small-business-ad-manager/reference/data_sources.md +100 -0
  279. package/content/small-business/skills/small-business-ad-manager/reference/diagnostics.md +89 -0
  280. package/content/small-business/skills/small-business-ad-manager/reference/gotchas.md +181 -0
  281. package/content/small-business/skills/small-business-ap-processor/SKILL.md +158 -0
  282. package/content/small-business/skills/small-business-ap-processor/reference/coding_rules.md +70 -0
  283. package/content/small-business/skills/small-business-ap-processor/reference/gotchas.md +131 -0
  284. package/content/small-business/skills/small-business-ap-processor/reference/intake_and_extraction.md +82 -0
  285. package/content/small-business/skills/small-business-ap-processor/reference/matching_and_exceptions.md +80 -0
  286. package/content/small-business/skills/small-business-ap-processor/reference/payment_run.md +77 -0
  287. package/content/small-business/skills/small-business-brand-style/SKILL.md +106 -0
  288. package/content/small-business/skills/small-business-build-agent/SKILL.md +105 -0
  289. package/content/small-business/skills/small-business-build-agent/reference/capture.md +133 -0
  290. package/content/small-business/skills/small-business-build-agent/reference/gotchas.md +204 -0
  291. package/content/small-business/skills/small-business-build-agent/reference/skill_authoring.md +165 -0
  292. package/content/small-business/skills/small-business-build-connector/SKILL.md +102 -0
  293. package/content/small-business/skills/small-business-build-connector/reference/discovery.md +120 -0
  294. package/content/small-business/skills/small-business-build-connector/reference/gotchas.md +237 -0
  295. package/content/small-business/skills/small-business-build-connector/reference/paths.md +106 -0
  296. package/content/small-business/skills/small-business-build-connector/reference/use-zapier.md +128 -0
  297. package/content/small-business/skills/small-business-business-pulse/SKILL.md +181 -0
  298. package/content/small-business/skills/small-business-business-pulse/reference/data_sources.md +173 -0
  299. package/content/small-business/skills/small-business-business-pulse/reference/gotchas.md +103 -0
  300. package/content/small-business/skills/small-business-business-pulse/reference/output_template.md +109 -0
  301. package/content/small-business/skills/small-business-business-pulse/reference/thresholds.md +71 -0
  302. package/content/small-business/skills/small-business-business-pulse/reference/v2_sources.md +63 -0
  303. package/content/small-business/skills/small-business-call-list/SKILL.md +82 -0
  304. package/content/small-business/skills/small-business-canva-creator/SKILL.md +448 -0
  305. package/content/small-business/skills/small-business-canva-creator/reference/canva-api.md +208 -0
  306. package/content/small-business/skills/small-business-canva-creator/reference/examples/boutique-brief-campaign.md +181 -0
  307. package/content/small-business/skills/small-business-canva-creator/reference/gotchas.md +380 -0
  308. package/content/small-business/skills/small-business-canva-creator/reference/hubspot-staging.md +137 -0
  309. package/content/small-business/skills/small-business-cash-flow-snapshot/SKILL.md +251 -0
  310. package/content/small-business/skills/small-business-cash-flow-snapshot/reference/examples/worked-example.md +92 -0
  311. package/content/small-business/skills/small-business-cash-flow-snapshot/reference/gotchas.md +62 -0
  312. package/content/small-business/skills/small-business-cash-flow-snapshot/reference/v2_sources.md +84 -0
  313. package/content/small-business/skills/small-business-close-month/SKILL.md +86 -0
  314. package/content/small-business/skills/small-business-content-strategy/SKILL.md +152 -0
  315. package/content/small-business/skills/small-business-content-strategy/reference/examples/retail-boutique-example.md +71 -0
  316. package/content/small-business/skills/small-business-content-strategy/reference/gotchas.md +104 -0
  317. package/content/small-business/skills/small-business-content-strategy/reference/v2_sources.md +40 -0
  318. package/content/small-business/skills/small-business-contract-review/SKILL.md +158 -0
  319. package/content/small-business/skills/small-business-contract-review/reference/docusign-fetch.md +32 -0
  320. package/content/small-business/skills/small-business-contract-review/reference/examples/flagged-summary-saas.md +97 -0
  321. package/content/small-business/skills/small-business-contract-review/reference/gmail-fetch.md +30 -0
  322. package/content/small-business/skills/small-business-contract-review/reference/gotchas.md +105 -0
  323. package/content/small-business/skills/small-business-contract-review/reference/m365-fetch.md +60 -0
  324. package/content/small-business/skills/small-business-crm-autopilot/SKILL.md +162 -0
  325. package/content/small-business/skills/small-business-crm-autopilot/reference/cleanup-checklist.md +82 -0
  326. package/content/small-business/skills/small-business-crm-autopilot/reference/examples/cleanup-deal.md +83 -0
  327. package/content/small-business/skills/small-business-crm-autopilot/reference/examples/log-call-happy-path.md +68 -0
  328. package/content/small-business/skills/small-business-crm-autopilot/reference/examples/log-email-happy-path.md +50 -0
  329. package/content/small-business/skills/small-business-crm-autopilot/reference/gotchas.md +110 -0
  330. package/content/small-business/skills/small-business-crm-autopilot/reference/hubspot-fields.md +62 -0
  331. package/content/small-business/skills/small-business-crm-autopilot/reference/lightweight_crm.md +125 -0
  332. package/content/small-business/skills/small-business-crm-autopilot/reference/salesforce-fields.md +122 -0
  333. package/content/small-business/skills/small-business-crm-autopilot/reference/standing_mode.md +144 -0
  334. package/content/small-business/skills/small-business-grant-rfp-writer/SKILL.md +162 -0
  335. package/content/small-business/skills/small-business-grant-rfp-writer/reference/drafting.md +129 -0
  336. package/content/small-business/skills/small-business-grant-rfp-writer/reference/go_no_go.md +125 -0
  337. package/content/small-business/skills/small-business-grant-rfp-writer/reference/gotchas.md +180 -0
  338. package/content/small-business/skills/small-business-grant-rfp-writer/reference/opportunity_sources.md +90 -0
  339. package/content/small-business/skills/small-business-grant-rfp-writer/reference/org_profile.md +81 -0
  340. package/content/small-business/skills/small-business-grow-pipeline/SKILL.md +92 -0
  341. package/content/small-business/skills/small-business-growth-pulse/SKILL.md +143 -0
  342. package/content/small-business/skills/small-business-growth-pulse/reference/data_sources.md +113 -0
  343. package/content/small-business/skills/small-business-growth-pulse/reference/gotchas.md +175 -0
  344. package/content/small-business/skills/small-business-growth-pulse/reference/output_template.md +122 -0
  345. package/content/small-business/skills/small-business-growth-pulse/reference/thresholds.md +110 -0
  346. package/content/small-business/skills/small-business-hiring-screener/SKILL.md +137 -0
  347. package/content/small-business/skills/small-business-hiring-screener/reference/candidate_comms.md +132 -0
  348. package/content/small-business/skills/small-business-hiring-screener/reference/fair_screening.md +103 -0
  349. package/content/small-business/skills/small-business-hiring-screener/reference/gotchas.md +183 -0
  350. package/content/small-business/skills/small-business-hiring-screener/reference/onboarding.md +82 -0
  351. package/content/small-business/skills/small-business-hiring-screener/reference/rubric.md +122 -0
  352. package/content/small-business/skills/small-business-inbox-manager/SKILL.md +130 -0
  353. package/content/small-business/skills/small-business-inbox-manager/reference/digest_format.md +110 -0
  354. package/content/small-business/skills/small-business-inbox-manager/reference/gotchas.md +220 -0
  355. package/content/small-business/skills/small-business-inbox-manager/reference/handoffs.md +77 -0
  356. package/content/small-business/skills/small-business-inbox-manager/reference/reply_drafting.md +116 -0
  357. package/content/small-business/skills/small-business-inbox-manager/reference/triage_rules.md +72 -0
  358. package/content/small-business/skills/small-business-inventory-planner/SKILL.md +126 -0
  359. package/content/small-business/skills/small-business-inventory-planner/reference/data_sources.md +94 -0
  360. package/content/small-business/skills/small-business-inventory-planner/reference/gotchas.md +153 -0
  361. package/content/small-business/skills/small-business-inventory-planner/reference/po_drafting.md +92 -0
  362. package/content/small-business/skills/small-business-inventory-planner/reference/seasonality.md +112 -0
  363. package/content/small-business/skills/small-business-inventory-planner/reference/velocity_and_reorder.md +154 -0
  364. package/content/small-business/skills/small-business-invoice-chase/SKILL.md +131 -0
  365. package/content/small-business/skills/small-business-invoice-chase/reference/examples/firm-reminder.md +28 -0
  366. package/content/small-business/skills/small-business-invoice-chase/reference/examples/gentle-reminder.md +27 -0
  367. package/content/small-business/skills/small-business-invoice-chase/reference/gotchas.md +75 -0
  368. package/content/small-business/skills/small-business-invoice-chase/reference/tone-matching.md +44 -0
  369. package/content/small-business/skills/small-business-invoice-chase/reference/v2_sources.md +78 -0
  370. package/content/small-business/skills/small-business-job-post-builder/SKILL.md +204 -0
  371. package/content/small-business/skills/small-business-job-post-builder/reference/docusign-routing.md +63 -0
  372. package/content/small-business/skills/small-business-job-post-builder/reference/examples/worked-example.md +110 -0
  373. package/content/small-business/skills/small-business-job-post-builder/reference/existing-document-merge.md +58 -0
  374. package/content/small-business/skills/small-business-job-post-builder/reference/gotchas.md +68 -0
  375. package/content/small-business/skills/small-business-job-post-builder/reference/interview-guide-structure.md +93 -0
  376. package/content/small-business/skills/small-business-job-post-builder/reference/job-post-structure.md +62 -0
  377. package/content/small-business/skills/small-business-job-post-builder/reference/offer-letter-template.md +145 -0
  378. package/content/small-business/skills/small-business-job-post-builder/reference/role-intake.md +73 -0
  379. package/content/small-business/skills/small-business-lead-finder/SKILL.md +119 -0
  380. package/content/small-business/skills/small-business-lead-finder/reference/gotchas.md +152 -0
  381. package/content/small-business/skills/small-business-lead-finder/reference/icp_method.md +97 -0
  382. package/content/small-business/skills/small-business-lead-finder/reference/output_template.md +124 -0
  383. package/content/small-business/skills/small-business-lead-finder/reference/scoring.md +92 -0
  384. package/content/small-business/skills/small-business-lead-finder/reference/sourcing.md +78 -0
  385. package/content/small-business/skills/small-business-lead-triage/SKILL.md +81 -0
  386. package/content/small-business/skills/small-business-lead-triage/reference/examples/happy-path-triage.md +68 -0
  387. package/content/small-business/skills/small-business-lead-triage/reference/gotchas.md +76 -0
  388. package/content/small-business/skills/small-business-lead-triage/reference/hubspot-scoring.md +169 -0
  389. package/content/small-business/skills/small-business-marketing-monday/SKILL.md +108 -0
  390. package/content/small-business/skills/small-business-monday-brief/SKILL.md +97 -0
  391. package/content/small-business/skills/small-business-month-end-prep/SKILL.md +331 -0
  392. package/content/small-business/skills/small-business-month-end-prep/reference/close-packet-format.md +127 -0
  393. package/content/small-business/skills/small-business-month-end-prep/reference/examples/pl-narrative.md +52 -0
  394. package/content/small-business/skills/small-business-month-end-prep/reference/gotchas.md +113 -0
  395. package/content/small-business/skills/small-business-month-end-prep/reference/paypal-settlements.md +110 -0
  396. package/content/small-business/skills/small-business-month-end-prep/reference/quickbooks-reconcile.md +71 -0
  397. package/content/small-business/skills/small-business-month-end-prep/reference/v2_sources.md +125 -0
  398. package/content/small-business/skills/small-business-month-end-prep/reference/xero-reconcile.md +175 -0
  399. package/content/small-business/skills/small-business-month-end-prep/reference/zoho-books-reconcile.md +168 -0
  400. package/content/small-business/skills/small-business-outreach-composer/SKILL.md +144 -0
  401. package/content/small-business/skills/small-business-outreach-composer/reference/gotchas.md +213 -0
  402. package/content/small-business/skills/small-business-outreach-composer/reference/output_template.md +147 -0
  403. package/content/small-business/skills/small-business-outreach-composer/reference/sequence_patterns.md +99 -0
  404. package/content/small-business/skills/small-business-outreach-composer/reference/slop_test.md +164 -0
  405. package/content/small-business/skills/small-business-pay-the-bills/SKILL.md +101 -0
  406. package/content/small-business/skills/small-business-payroll-prep/SKILL.md +139 -0
  407. package/content/small-business/skills/small-business-payroll-prep/reference/anomaly_rules.md +99 -0
  408. package/content/small-business/skills/small-business-payroll-prep/reference/books_sync.md +72 -0
  409. package/content/small-business/skills/small-business-payroll-prep/reference/gotchas.md +153 -0
  410. package/content/small-business/skills/small-business-payroll-prep/reference/run_sheet_format.md +90 -0
  411. package/content/small-business/skills/small-business-payroll-prep/reference/timesheet_intake.md +118 -0
  412. package/content/small-business/skills/small-business-plan-payroll/SKILL.md +88 -0
  413. package/content/small-business/skills/small-business-proposal-builder/SKILL.md +168 -0
  414. package/content/small-business/skills/small-business-proposal-builder/reference/discovery_extraction.md +138 -0
  415. package/content/small-business/skills/small-business-proposal-builder/reference/gotchas.md +184 -0
  416. package/content/small-business/skills/small-business-proposal-builder/reference/output_template.md +128 -0
  417. package/content/small-business/skills/small-business-proposal-builder/reference/pricing_method.md +125 -0
  418. package/content/small-business/skills/small-business-proposal-builder/reference/proposal_structure.md +120 -0
  419. package/content/small-business/skills/small-business-reactivate/SKILL.md +109 -0
  420. package/content/small-business/skills/small-business-report-builder/SKILL.md +142 -0
  421. package/content/small-business/skills/small-business-report-builder/reference/data_sources.md +168 -0
  422. package/content/small-business/skills/small-business-report-builder/reference/gotchas.md +155 -0
  423. package/content/small-business/skills/small-business-report-builder/reference/output_template.md +109 -0
  424. package/content/small-business/skills/small-business-report-builder/reference/report_spec.md +109 -0
  425. package/content/small-business/skills/small-business-report-builder/reference/saved_reports.md +50 -0
  426. package/content/small-business/skills/small-business-report-pack/SKILL.md +83 -0
  427. package/content/small-business/skills/small-business-restock/SKILL.md +88 -0
  428. package/content/small-business/skills/small-business-review-reputation/SKILL.md +130 -0
  429. package/content/small-business/skills/small-business-review-reputation/reference/churn-signals.md +110 -0
  430. package/content/small-business/skills/small-business-review-reputation/reference/examples/example-report.md +150 -0
  431. package/content/small-business/skills/small-business-review-reputation/reference/gotchas.md +164 -0
  432. package/content/small-business/skills/small-business-review-reputation/reference/response-patterns.md +123 -0
  433. package/content/small-business/skills/small-business-review-reputation/reference/sources.md +116 -0
  434. package/content/small-business/skills/small-business-seo-ai-visibility/SKILL.md +143 -0
  435. package/content/small-business/skills/small-business-seo-ai-visibility/reference/ai_visibility.md +173 -0
  436. package/content/small-business/skills/small-business-seo-ai-visibility/reference/audit_checklist.md +134 -0
  437. package/content/small-business/skills/small-business-seo-ai-visibility/reference/catalog_refresh.md +126 -0
  438. package/content/small-business/skills/small-business-seo-ai-visibility/reference/content_rewrite.md +113 -0
  439. package/content/small-business/skills/small-business-seo-ai-visibility/reference/gotchas.md +211 -0
  440. package/content/small-business/skills/small-business-smb-onboard/SKILL.md +82 -0
  441. package/content/small-business/skills/small-business-smb-onboard/reference/examples/happy-path.md +190 -0
  442. package/content/small-business/skills/small-business-smb-onboard/reference/gotchas.md +111 -0
  443. package/content/small-business/skills/small-business-smb-onboard/reference/onboard-checklist.md +99 -0
  444. package/content/small-business/skills/small-business-smb-onboard/reference/website-research.md +82 -0
  445. package/content/small-business/skills/small-business-smb-router/SKILL.md +216 -0
  446. package/content/small-business/skills/small-business-smb-router/reference/connector-map.md +96 -0
  447. package/content/small-business/skills/small-business-social-content-engine/SKILL.md +162 -0
  448. package/content/small-business/skills/small-business-social-content-engine/reference/calendar.md +116 -0
  449. package/content/small-business/skills/small-business-social-content-engine/reference/canva-api.md +208 -0
  450. package/content/small-business/skills/small-business-social-content-engine/reference/examples/okonkwo-campaign.md +190 -0
  451. package/content/small-business/skills/small-business-social-content-engine/reference/gotchas.md +447 -0
  452. package/content/small-business/skills/small-business-social-content-engine/reference/publishing.md +166 -0
  453. package/content/small-business/skills/small-business-social-content-engine/reference/shopify-assets.md +77 -0
  454. package/content/small-business/skills/small-business-speed-to-lead/SKILL.md +172 -0
  455. package/content/small-business/skills/small-business-speed-to-lead/reference/approval.md +61 -0
  456. package/content/small-business/skills/small-business-speed-to-lead/reference/gotchas.md +167 -0
  457. package/content/small-business/skills/small-business-speed-to-lead/reference/qualification.md +153 -0
  458. package/content/small-business/skills/small-business-speed-to-lead/reference/response_patterns.md +184 -0
  459. package/content/small-business/skills/small-business-tax-prep/SKILL.md +85 -0
  460. package/content/small-business/skills/small-business-tax-season-organizer/SKILL.md +210 -0
  461. package/content/small-business/skills/small-business-tax-season-organizer/reference/calculation-assumptions.md +177 -0
  462. package/content/small-business/skills/small-business-tax-season-organizer/reference/connector-queries.md +267 -0
  463. package/content/small-business/skills/small-business-tax-season-organizer/reference/examples/quarterly-estimate.md +92 -0
  464. package/content/small-business/skills/small-business-tax-season-organizer/reference/examples/year-end-1099.md +102 -0
  465. package/content/small-business/skills/small-business-tax-season-organizer/reference/gotchas.md +104 -0
  466. package/content/small-business/skills/small-business-tax-season-organizer/reference/output-formats.md +68 -0
  467. package/content/small-business/skills/small-business-ticket-deflector/SKILL.md +164 -0
  468. package/content/small-business/skills/small-business-ticket-deflector/reference/examples/deny-refund-request.md +98 -0
  469. package/content/small-business/skills/small-business-ticket-deflector/reference/examples/respond-refund-request.md +77 -0
  470. package/content/small-business/skills/small-business-ticket-deflector/reference/gotchas.md +57 -0
  471. package/index.ts +83 -0
  472. package/package.json +28 -3
@@ -0,0 +1,732 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ GEO/SRA Data Fetcher
4
+ ====================
5
+ Download raw sequencing data from NCBI GEO/SRA and prepare for nf-core pipelines.
6
+
7
+ Usage:
8
+ python sra_geo_fetch.py info <GEO_ID> # Get study information
9
+ python sra_geo_fetch.py list <GEO_ID> # List all samples/runs
10
+ python sra_geo_fetch.py download <GEO_ID> -o DIR # Download FASTQ files
11
+ python sra_geo_fetch.py samplesheet <GEO_ID> ... # Generate samplesheet
12
+
13
+ Examples:
14
+ python sra_geo_fetch.py info GSE110004
15
+ python sra_geo_fetch.py list GSE110004 --filter "RNA-Seq:PAIRED"
16
+ python sra_geo_fetch.py download GSE110004 -o ./fastq --parallel 4
17
+ python sra_geo_fetch.py samplesheet GSE110004 --fastq-dir ./fastq -o samplesheet.csv
18
+ """
19
+
20
+ import argparse
21
+ import json
22
+ import logging
23
+ import os
24
+ import re
25
+ import subprocess
26
+ import sys
27
+ from concurrent.futures import ThreadPoolExecutor, as_completed
28
+ from dataclasses import dataclass, asdict
29
+ from pathlib import Path
30
+ from typing import Dict, List, Optional, Tuple
31
+
32
+ # Add utils to path
33
+ sys.path.insert(0, str(Path(__file__).parent))
34
+ from utils.ncbi_utils import (
35
+ check_network_access,
36
+ fetch_geo_metadata,
37
+ fetch_sra_study_accession,
38
+ fetch_sra_run_info,
39
+ fetch_sra_run_info_detailed,
40
+ fetch_ena_fastq_urls,
41
+ download_file,
42
+ format_file_size,
43
+ estimate_download_size,
44
+ group_samples_by_type,
45
+ format_sample_groups_table,
46
+ )
47
+
48
+ # Set up logging
49
+ logging.basicConfig(
50
+ level=logging.INFO,
51
+ format='%(message)s'
52
+ )
53
+ logger = logging.getLogger(__name__)
54
+
55
+ # Load genome mapping
56
+ SCRIPT_DIR = Path(__file__).parent
57
+ GENOMES_FILE = SCRIPT_DIR / "config" / "genomes.yaml"
58
+
59
+
60
+ @dataclass
61
+ class StudyInfo:
62
+ """Information about a GEO study."""
63
+ geo_id: str
64
+ title: str
65
+ organism: str
66
+ n_samples: int
67
+ summary: str
68
+ sra_study: Optional[str]
69
+ suggested_genome: Optional[str]
70
+ suggested_pipeline: Optional[str]
71
+
72
+
73
+ def load_genome_mapping() -> Dict:
74
+ """Load organism to genome mapping from config."""
75
+ if not GENOMES_FILE.exists():
76
+ return {}
77
+
78
+ try:
79
+ import yaml
80
+ with open(GENOMES_FILE) as f:
81
+ config = yaml.safe_load(f)
82
+ return config.get('organisms', {})
83
+ except ImportError:
84
+ # Fallback: parse YAML manually for simple cases
85
+ mapping = {}
86
+ try:
87
+ with open(GENOMES_FILE) as f:
88
+ content = f.read()
89
+ # Simple regex parsing for organism blocks
90
+ pattern = r'"([^"]+)":\s*\n\s*genome:\s*"([^"]+)"'
91
+ for match in re.finditer(pattern, content):
92
+ mapping[match.group(1)] = {'genome': match.group(2)}
93
+ except Exception:
94
+ pass
95
+ return mapping
96
+
97
+
98
+ def suggest_genome(organism: str) -> Optional[str]:
99
+ """Suggest a genome based on organism name."""
100
+ genome_map = load_genome_mapping()
101
+
102
+ # Direct match
103
+ if organism in genome_map:
104
+ return genome_map[organism].get('genome')
105
+
106
+ # Case-insensitive search
107
+ organism_lower = organism.lower()
108
+ for org_name, info in genome_map.items():
109
+ if org_name.lower() == organism_lower:
110
+ return info.get('genome')
111
+ # Check aliases
112
+ aliases = info.get('aliases', [])
113
+ if any(alias.lower() == organism_lower for alias in aliases):
114
+ return info.get('genome')
115
+
116
+ # Common fallbacks
117
+ fallbacks = {
118
+ 'homo sapiens': 'GRCh38',
119
+ 'human': 'GRCh38',
120
+ 'mus musculus': 'GRCm39',
121
+ 'mouse': 'GRCm39',
122
+ 'saccharomyces cerevisiae': 'R64-1-1',
123
+ 'yeast': 'R64-1-1',
124
+ 'drosophila melanogaster': 'BDGP6',
125
+ 'caenorhabditis elegans': 'WBcel235',
126
+ 'danio rerio': 'GRCz11',
127
+ 'arabidopsis thaliana': 'TAIR10',
128
+ 'rattus norvegicus': 'Rnor_6.0',
129
+ }
130
+
131
+ return fallbacks.get(organism_lower)
132
+
133
+
134
+ def suggest_pipeline(library_strategy: str, library_source: str = '') -> str:
135
+ """Suggest nf-core pipeline based on library strategy."""
136
+ strategy = library_strategy.upper()
137
+
138
+ pipeline_map = {
139
+ 'RNA-SEQ': 'rnaseq',
140
+ 'ATAC-SEQ': 'atacseq',
141
+ 'CHIP-SEQ': 'chipseq',
142
+ 'WGS': 'sarek',
143
+ 'WXS': 'sarek',
144
+ 'AMPLICON': 'ampliseq',
145
+ 'BISULFITE-SEQ': 'methylseq',
146
+ 'HI-C': 'hic',
147
+ }
148
+
149
+ return pipeline_map.get(strategy, 'rnaseq')
150
+
151
+
152
+ def cmd_info(args):
153
+ """Display study information."""
154
+ geo_id = args.geo_id.upper()
155
+
156
+ print(f"\nFetching information for {geo_id}...")
157
+
158
+ # Check network
159
+ network_ok, network_msg = check_network_access()
160
+ if not network_ok:
161
+ print(f"\n⚠️ Network issues detected:\n{network_msg}")
162
+
163
+ # Get GEO metadata
164
+ metadata = fetch_geo_metadata(geo_id)
165
+ if not metadata:
166
+ print(f"\n❌ Could not fetch metadata for {geo_id}")
167
+ return 1
168
+
169
+ # Get SRA study accession
170
+ sra_study = fetch_sra_study_accession(geo_id)
171
+
172
+ # Get detailed run info
173
+ print("Fetching SRA run information...")
174
+ runs = fetch_sra_run_info_detailed(geo_id)
175
+ if not runs:
176
+ # Fallback to basic method
177
+ runs = fetch_sra_run_info(geo_id)
178
+
179
+ # Group samples by type
180
+ groups = group_samples_by_type(runs) if runs else {}
181
+
182
+ # Suggest genome and pipeline
183
+ organism = metadata.get('organism', 'Unknown')
184
+ genome = suggest_genome(organism)
185
+
186
+ # Determine primary data type
187
+ primary_strategy = 'RNA-SEQ'
188
+ if groups:
189
+ primary_group = max(groups.items(), key=lambda x: x[1]['count'])
190
+ primary_strategy = primary_group[1]['strategy']
191
+ pipeline = suggest_pipeline(primary_strategy)
192
+
193
+ # Estimate download size
194
+ est_size = estimate_download_size(runs)
195
+
196
+ # Display info
197
+ print("\n" + "━" * 70)
198
+ print(f"{geo_id}: {metadata.get('title', 'N/A')}")
199
+ print("━" * 70)
200
+ print(f"Organism: {organism}")
201
+ print(f"Samples: {metadata.get('n_samples', 'N/A')}")
202
+ print(f"SRA Study: {sra_study or 'Not found'}")
203
+ print(f"Runs: {len(runs)}")
204
+ print(f"Est. Size: ~{format_file_size(est_size)}")
205
+ print(f"Genome: {genome or 'Unknown (manual selection required)'}")
206
+ print(f"Pipeline: nf-core/{pipeline} (suggested)")
207
+
208
+ # Show sample groups table
209
+ if groups:
210
+ print(format_sample_groups_table(groups))
211
+
212
+ if metadata.get('summary'):
213
+ summary = metadata['summary']
214
+ if len(summary) > 300:
215
+ summary = summary[:297] + "..."
216
+ print(f"\nSummary:\n {summary}")
217
+
218
+ print("━" * 70)
219
+
220
+ # Show download hints
221
+ if len(groups) > 1:
222
+ print("\n💡 To download a specific subset, use:")
223
+ for key in sorted(groups.keys()):
224
+ print(f" --subset \"{key}\"")
225
+
226
+ # Save study info JSON
227
+ if args.output_json:
228
+ info = {
229
+ 'geo_id': geo_id,
230
+ 'title': metadata.get('title'),
231
+ 'organism': organism,
232
+ 'n_samples': metadata.get('n_samples'),
233
+ 'sra_study': sra_study,
234
+ 'n_runs': len(runs),
235
+ 'groups': {k: {**v, 'runs': None, 'gsm_ids': list(v.get('gsm_ids', []))} for k, v in groups.items()},
236
+ 'suggested_genome': genome,
237
+ 'suggested_pipeline': pipeline,
238
+ 'summary': metadata.get('summary'),
239
+ }
240
+ output_path = Path(args.output_json)
241
+ with open(output_path, 'w') as f:
242
+ json.dump(info, f, indent=2)
243
+ print(f"\n📄 Study info saved to: {output_path}")
244
+
245
+ return 0
246
+
247
+
248
+ def cmd_groups(args):
249
+ """Display sample groups in a study for interactive selection."""
250
+ geo_id = args.geo_id.upper()
251
+
252
+ print(f"\nFetching sample groups for {geo_id}...")
253
+
254
+ # Get detailed run info
255
+ runs = fetch_sra_run_info_detailed(geo_id)
256
+ if not runs:
257
+ runs = fetch_sra_run_info(geo_id)
258
+
259
+ if not runs:
260
+ print(f"\n❌ No runs found for {geo_id}")
261
+ return 1
262
+
263
+ # Group samples
264
+ groups = group_samples_by_type(runs)
265
+
266
+ print(format_sample_groups_table(groups))
267
+
268
+ # Output for interactive selection
269
+ print("\n📋 Available groups for --subset option:")
270
+ for i, (key, info) in enumerate(sorted(groups.items(), key=lambda x: -x[1]['count']), 1):
271
+ size_str = format_file_size(info['size_estimate'])
272
+ print(f" {i}. \"{key}\" - {info['count']} samples (~{size_str})")
273
+
274
+ # Save to JSON if requested
275
+ if args.output:
276
+ output_path = Path(args.output)
277
+ output_data = {
278
+ 'geo_id': geo_id,
279
+ 'groups': {}
280
+ }
281
+ for key, info in groups.items():
282
+ output_data['groups'][key] = {
283
+ 'count': info['count'],
284
+ 'gsm_range': info['gsm_range'],
285
+ 'gsm_ids': info.get('gsm_ids', []),
286
+ 'size_estimate': info['size_estimate'],
287
+ 'strategy': info['strategy'],
288
+ 'layout': info['layout'],
289
+ 'srr_ids': [r['srr'] for r in info['runs']],
290
+ }
291
+ with open(output_path, 'w') as f:
292
+ json.dump(output_data, f, indent=2)
293
+ print(f"\n📄 Groups saved to: {output_path}")
294
+
295
+ return 0
296
+
297
+
298
+ def cmd_list(args):
299
+ """List all samples and runs in a study."""
300
+ geo_id = args.geo_id.upper()
301
+
302
+ print(f"\nFetching run list for {geo_id}...")
303
+
304
+ runs = fetch_sra_run_info(geo_id)
305
+ if not runs:
306
+ print(f"\n❌ No runs found for {geo_id}")
307
+ return 1
308
+
309
+ # Apply filter if specified
310
+ if args.filter:
311
+ filter_parts = args.filter.split(':')
312
+ strategy_filter = filter_parts[0].upper() if filter_parts else None
313
+ layout_filter = filter_parts[1].upper() if len(filter_parts) > 1 else None
314
+
315
+ filtered = []
316
+ for run in runs:
317
+ if strategy_filter and run.get('library_strategy', '').upper() != strategy_filter:
318
+ continue
319
+ if layout_filter and run.get('layout', '').upper() != layout_filter:
320
+ continue
321
+ filtered.append(run)
322
+ runs = filtered
323
+
324
+ print(f"\n{'SRR':<15} {'GSM':<12} {'Layout':<8} {'Strategy':<12} {'Size':>10}")
325
+ print("-" * 60)
326
+
327
+ for run in runs:
328
+ size = format_file_size(run.get('bases', 0) // 4)
329
+ print(f"{run['srr']:<15} {run.get('gsm', 'N/A'):<12} {run.get('layout', 'N/A'):<8} "
330
+ f"{run.get('library_strategy', 'N/A'):<12} {size:>10}")
331
+
332
+ print(f"\nTotal: {len(runs)} runs")
333
+
334
+ # Output as TSV if requested
335
+ if args.output:
336
+ output_path = Path(args.output)
337
+ with open(output_path, 'w') as f:
338
+ f.write("run_accession\tgsm\tlayout\tlibrary_strategy\tbases\n")
339
+ for run in runs:
340
+ f.write(f"{run['srr']}\t{run.get('gsm', '')}\t{run.get('layout', '')}\t"
341
+ f"{run.get('library_strategy', '')}\t{run.get('bases', 0)}\n")
342
+ print(f"\n📄 Run list saved to: {output_path}")
343
+
344
+ return 0
345
+
346
+
347
+ def download_fastq_file(url: str, output_path: Path, timeout: int = 600) -> Tuple[str, bool]:
348
+ """Download a single FASTQ file."""
349
+ filename = output_path.name
350
+ if output_path.exists():
351
+ return filename, True # Already exists
352
+
353
+ success = download_file(url, output_path, timeout=timeout, show_progress=False)
354
+ return filename, success
355
+
356
+
357
+ def interactive_select_group(groups: Dict[str, Dict]) -> Optional[str]:
358
+ """Interactively select a sample group."""
359
+ if len(groups) <= 1:
360
+ return None # No selection needed
361
+
362
+ print("\n" + "=" * 60)
363
+ print(" SELECT SAMPLE GROUP TO DOWNLOAD")
364
+ print("=" * 60)
365
+
366
+ sorted_groups = sorted(groups.items(), key=lambda x: -x[1]['count'])
367
+
368
+ for i, (key, info) in enumerate(sorted_groups, 1):
369
+ size_str = format_file_size(info['size_estimate'])
370
+ print(f"\n [{i}] {info['strategy']} ({info['layout'].lower()})")
371
+ print(f" Samples: {info['count']}")
372
+ print(f" GSM: {info['gsm_range']}")
373
+ print(f" Size: ~{size_str}")
374
+
375
+ print(f"\n [0] Download ALL ({sum(g['count'] for g in groups.values())} samples)")
376
+ print("-" * 60)
377
+
378
+ try:
379
+ choice = input("\nEnter selection (0-{}): ".format(len(sorted_groups))).strip()
380
+ choice_num = int(choice)
381
+
382
+ if choice_num == 0:
383
+ return None # Download all
384
+ elif 1 <= choice_num <= len(sorted_groups):
385
+ selected_key = sorted_groups[choice_num - 1][0]
386
+ print(f"\n✓ Selected: {selected_key}")
387
+ return selected_key
388
+ else:
389
+ print("Invalid selection, downloading all.")
390
+ return None
391
+ except (ValueError, EOFError, KeyboardInterrupt):
392
+ print("\nInvalid input, downloading all.")
393
+ return None
394
+
395
+
396
+ def cmd_download(args):
397
+ """Download FASTQ files from ENA."""
398
+ geo_id = args.geo_id.upper()
399
+ output_dir = Path(args.output)
400
+ output_dir.mkdir(parents=True, exist_ok=True)
401
+
402
+ print(f"\nPreparing download for {geo_id}...")
403
+
404
+ # Get detailed run info (includes BioProject fallback for SuperSeries)
405
+ print("Fetching SRA run information...")
406
+ runs = fetch_sra_run_info_detailed(geo_id)
407
+ if not runs:
408
+ runs = fetch_sra_run_info(geo_id)
409
+
410
+ if not runs:
411
+ print(f"❌ No runs found for {geo_id}")
412
+ return 1
413
+
414
+ # Collect all unique SRA studies from runs (SuperSeries may have multiple)
415
+ sra_studies = set(r.get('sra_study', '') for r in runs if r.get('sra_study'))
416
+ if not sra_studies:
417
+ print(f"❌ Could not find any SRA studies for {geo_id}")
418
+ return 1
419
+
420
+ if len(sra_studies) > 1:
421
+ print(f"SuperSeries detected with {len(sra_studies)} SRA studies: {', '.join(sorted(sra_studies))}")
422
+ else:
423
+ print(f"SRA Study: {list(sra_studies)[0]}")
424
+
425
+ # Group samples
426
+ groups = group_samples_by_type(runs)
427
+
428
+ # Show sample groups if multiple types exist
429
+ if len(groups) > 1:
430
+ print(format_sample_groups_table(groups))
431
+
432
+ # Handle subset selection
433
+ selected_subset = args.subset
434
+
435
+ # Interactive mode if multiple groups and no subset specified
436
+ if args.interactive and len(groups) > 1 and not selected_subset:
437
+ selected_subset = interactive_select_group(groups)
438
+
439
+ # Get ENA FASTQ URLs from all SRA studies
440
+ print("\nFetching FASTQ URLs from ENA...")
441
+ fastq_urls = {}
442
+ for sra_study in sorted(sra_studies):
443
+ study_urls = fetch_ena_fastq_urls(sra_study)
444
+ if study_urls:
445
+ print(f" {sra_study}: {len(study_urls)} runs")
446
+ fastq_urls.update(study_urls)
447
+
448
+ if not fastq_urls:
449
+ print("❌ No FASTQ URLs found in ENA")
450
+ print("Tip: Try using SRA toolkit directly with prefetch + fasterq-dump")
451
+ return 1
452
+
453
+ # Apply filter if specified
454
+ if selected_subset:
455
+ filter_parts = selected_subset.split(':')
456
+ strategy_filter = filter_parts[0].upper() if filter_parts else None
457
+ layout_filter = filter_parts[1].upper() if len(filter_parts) > 1 else None
458
+
459
+ filtered_srrs = set()
460
+ for run in runs:
461
+ if strategy_filter and run.get('library_strategy', '').upper() != strategy_filter:
462
+ continue
463
+ if layout_filter and run.get('layout', '').upper() != layout_filter:
464
+ continue
465
+ filtered_srrs.add(run['srr'])
466
+
467
+ fastq_urls = {srr: urls for srr, urls in fastq_urls.items() if srr in filtered_srrs}
468
+ print(f"\n📦 Filtered to {len(fastq_urls)} runs matching \"{selected_subset}\"")
469
+
470
+ # Count files to download
471
+ total_files = sum(len(urls) for urls in fastq_urls.values())
472
+ print(f"\n📦 Found {len(fastq_urls)} runs, {total_files} FASTQ files to download")
473
+
474
+ # Check for existing files
475
+ existing = 0
476
+ downloads_needed = []
477
+ for srr, urls in fastq_urls.items():
478
+ for url in urls:
479
+ filename = url.split('/')[-1]
480
+ filepath = output_dir / filename
481
+ if filepath.exists():
482
+ existing += 1
483
+ else:
484
+ downloads_needed.append((url, filepath))
485
+
486
+ if existing:
487
+ print(f" ✓ {existing} files already exist, skipping")
488
+
489
+ if not downloads_needed:
490
+ print("\n✅ All files already downloaded!")
491
+ return 0
492
+
493
+ print(f" ↓ {len(downloads_needed)} files to download")
494
+ print()
495
+
496
+ # Download files
497
+ successful = 0
498
+ failed = []
499
+
500
+ if args.parallel > 1:
501
+ # Parallel download
502
+ with ThreadPoolExecutor(max_workers=args.parallel) as executor:
503
+ futures = {
504
+ executor.submit(download_fastq_file, url, filepath): filepath
505
+ for url, filepath in downloads_needed
506
+ }
507
+
508
+ for i, future in enumerate(as_completed(futures), 1):
509
+ filepath = futures[future]
510
+ filename, success = future.result()
511
+ status = "✓" if success else "✗"
512
+ print(f" [{i}/{len(downloads_needed)}] {status} {filename}")
513
+ if success:
514
+ successful += 1
515
+ else:
516
+ failed.append(filename)
517
+ else:
518
+ # Sequential download
519
+ for i, (url, filepath) in enumerate(downloads_needed, 1):
520
+ filename = filepath.name
521
+ print(f" [{i}/{len(downloads_needed)}] Downloading {filename}...")
522
+ success = download_file(url, filepath, timeout=args.timeout)
523
+ if success:
524
+ successful += 1
525
+ print(f" ✓ Done")
526
+ else:
527
+ failed.append(filename)
528
+ print(f" ✗ Failed")
529
+
530
+ print(f"\n📊 Download summary:")
531
+ print(f" ✓ Successful: {successful + existing}")
532
+ print(f" ✗ Failed: {len(failed)}")
533
+
534
+ if failed:
535
+ print(f"\nFailed downloads:")
536
+ for f in failed:
537
+ print(f" - {f}")
538
+ return 1
539
+
540
+ print(f"\n✅ All files downloaded to: {output_dir}")
541
+
542
+ # Save metadata
543
+ metadata_path = output_dir / "download_metadata.json"
544
+ metadata = {
545
+ 'geo_id': geo_id,
546
+ 'sra_studies': sorted(sra_studies),
547
+ 'n_runs': len(fastq_urls),
548
+ 'n_files': total_files,
549
+ 'output_dir': str(output_dir.absolute()),
550
+ }
551
+ with open(metadata_path, 'w') as f:
552
+ json.dump(metadata, f, indent=2)
553
+
554
+ return 0
555
+
556
+
557
+ def cmd_samplesheet(args):
558
+ """Generate samplesheet for nf-core pipeline."""
559
+ geo_id = args.geo_id.upper()
560
+ fastq_dir = Path(args.fastq_dir)
561
+ output_path = Path(args.output)
562
+
563
+ print(f"\nGenerating samplesheet for {geo_id}...")
564
+
565
+ # Get run info
566
+ runs = fetch_sra_run_info(geo_id)
567
+ if not runs:
568
+ print(f"❌ No runs found for {geo_id}")
569
+ return 1
570
+
571
+ # Get GEO metadata for sample naming
572
+ metadata = fetch_geo_metadata(geo_id)
573
+ organism = metadata.get('organism', 'Unknown') if metadata else 'Unknown'
574
+ genome = suggest_genome(organism)
575
+
576
+ # Detect pipeline from data
577
+ strategies = set(r.get('library_strategy', 'RNA-SEQ') for r in runs)
578
+ primary_strategy = list(strategies)[0] if strategies else 'RNA-SEQ'
579
+ pipeline = args.pipeline or suggest_pipeline(primary_strategy)
580
+
581
+ # Map SRR to local FASTQ files
582
+ samples = []
583
+ for run in runs:
584
+ srr = run['srr']
585
+ layout = run.get('layout', 'PAIRED')
586
+
587
+ # Find FASTQ files
588
+ if layout == 'PAIRED':
589
+ r1 = fastq_dir / f"{srr}_1.fastq.gz"
590
+ r2 = fastq_dir / f"{srr}_2.fastq.gz"
591
+ if not r1.exists() or not r2.exists():
592
+ logger.warning(f"FASTQ files not found for {srr}")
593
+ continue
594
+ samples.append({
595
+ 'srr': srr,
596
+ 'gsm': run.get('gsm', ''),
597
+ 'fastq_1': str(r1.absolute()),
598
+ 'fastq_2': str(r2.absolute()),
599
+ 'layout': 'PAIRED',
600
+ })
601
+ else:
602
+ r1 = fastq_dir / f"{srr}.fastq.gz"
603
+ if not r1.exists():
604
+ r1 = fastq_dir / f"{srr}_1.fastq.gz"
605
+ if not r1.exists():
606
+ logger.warning(f"FASTQ file not found for {srr}")
607
+ continue
608
+ samples.append({
609
+ 'srr': srr,
610
+ 'gsm': run.get('gsm', ''),
611
+ 'fastq_1': str(r1.absolute()),
612
+ 'fastq_2': '',
613
+ 'layout': 'SINGLE',
614
+ })
615
+
616
+ if not samples:
617
+ print(f"❌ No FASTQ files found in {fastq_dir}")
618
+ return 1
619
+
620
+ # Generate sample names
621
+ # Try to infer meaningful names from GSM IDs or use SRR
622
+ sample_names = {}
623
+ for sample in samples:
624
+ # Default to SRR accession
625
+ sample_names[sample['srr']] = sample['srr']
626
+
627
+ # Write samplesheet
628
+ with open(output_path, 'w') as f:
629
+ if pipeline == 'rnaseq':
630
+ f.write("sample,fastq_1,fastq_2,strandedness\n")
631
+ for sample in samples:
632
+ name = sample_names[sample['srr']]
633
+ f.write(f"{name},{sample['fastq_1']},{sample['fastq_2']},auto\n")
634
+ elif pipeline == 'atacseq':
635
+ f.write("sample,fastq_1,fastq_2,replicate\n")
636
+ for i, sample in enumerate(samples, 1):
637
+ name = sample_names[sample['srr']]
638
+ f.write(f"{name},{sample['fastq_1']},{sample['fastq_2']},1\n")
639
+ else:
640
+ # Generic format
641
+ f.write("sample,fastq_1,fastq_2\n")
642
+ for sample in samples:
643
+ name = sample_names[sample['srr']]
644
+ f.write(f"{name},{sample['fastq_1']},{sample['fastq_2']}\n")
645
+
646
+ print(f"\n✅ Generated samplesheet: {output_path}")
647
+ print(f" Samples: {len(samples)}")
648
+ print(f" Pipeline: nf-core/{pipeline}")
649
+ if genome:
650
+ print(f" Genome: {genome}")
651
+
652
+ print(f"\n💡 Suggested command:")
653
+ print(f" nextflow run nf-core/{pipeline} \\")
654
+ print(f" --input {output_path} \\")
655
+ print(f" --outdir results \\")
656
+ if genome:
657
+ print(f" --genome {genome} \\")
658
+ print(f" -profile docker")
659
+
660
+ return 0
661
+
662
+
663
+ def main():
664
+ parser = argparse.ArgumentParser(
665
+ description="Download GEO/SRA data and prepare for nf-core pipelines",
666
+ formatter_class=argparse.RawDescriptionHelpFormatter,
667
+ epilog="""
668
+ Examples:
669
+ %(prog)s info GSE110004 # Get study info with sample groups
670
+ %(prog)s groups GSE110004 # Show sample groups for selection
671
+ %(prog)s list GSE110004 --filter RNA-Seq # List RNA-seq runs
672
+ %(prog)s download GSE110004 -o ./fastq -i # Download with interactive selection
673
+ %(prog)s download GSE110004 -o ./fastq --subset "RNA-Seq:PAIRED"
674
+ %(prog)s samplesheet GSE110004 \\
675
+ --fastq-dir ./fastq -o samplesheet.csv # Generate samplesheet
676
+ """
677
+ )
678
+
679
+ subparsers = parser.add_subparsers(dest='command', help='Commands')
680
+
681
+ # info command
682
+ info_parser = subparsers.add_parser('info', help='Display study information with sample groups')
683
+ info_parser.add_argument('geo_id', help='GEO accession (e.g., GSE110004)')
684
+ info_parser.add_argument('--output-json', '-o', help='Save info to JSON file')
685
+
686
+ # groups command
687
+ groups_parser = subparsers.add_parser('groups', help='Show sample groups for interactive selection')
688
+ groups_parser.add_argument('geo_id', help='GEO accession')
689
+ groups_parser.add_argument('--output', '-o', help='Save groups to JSON file')
690
+
691
+ # list command
692
+ list_parser = subparsers.add_parser('list', help='List samples and runs')
693
+ list_parser.add_argument('geo_id', help='GEO accession')
694
+ list_parser.add_argument('--filter', '-f', help='Filter by strategy:layout (e.g., RNA-Seq:PAIRED)')
695
+ list_parser.add_argument('--output', '-o', help='Save to TSV file')
696
+
697
+ # download command
698
+ dl_parser = subparsers.add_parser('download', help='Download FASTQ files')
699
+ dl_parser.add_argument('geo_id', help='GEO accession')
700
+ dl_parser.add_argument('--output', '-o', required=True, help='Output directory')
701
+ dl_parser.add_argument('--subset', '-s', help='Filter subset (e.g., RNA-Seq:PAIRED)')
702
+ dl_parser.add_argument('--interactive', '-i', action='store_true',
703
+ help='Interactively select sample group to download')
704
+ dl_parser.add_argument('--parallel', '-p', type=int, default=4, help='Parallel downloads')
705
+ dl_parser.add_argument('--timeout', '-t', type=int, default=600, help='Download timeout (sec)')
706
+
707
+ # samplesheet command
708
+ ss_parser = subparsers.add_parser('samplesheet', help='Generate samplesheet')
709
+ ss_parser.add_argument('geo_id', help='GEO accession')
710
+ ss_parser.add_argument('--fastq-dir', '-f', required=True, help='Directory with FASTQ files')
711
+ ss_parser.add_argument('--output', '-o', default='samplesheet.csv', help='Output samplesheet')
712
+ ss_parser.add_argument('--pipeline', '-p', help='Target pipeline (auto-detected if not specified)')
713
+
714
+ args = parser.parse_args()
715
+
716
+ if not args.command:
717
+ parser.print_help()
718
+ return 1
719
+
720
+ commands = {
721
+ 'info': cmd_info,
722
+ 'groups': cmd_groups,
723
+ 'list': cmd_list,
724
+ 'download': cmd_download,
725
+ 'samplesheet': cmd_samplesheet,
726
+ }
727
+
728
+ return commands[args.command](args)
729
+
730
+
731
+ if __name__ == '__main__':
732
+ sys.exit(main())