gapit 0.4.0__tar.gz → 0.5.1__tar.gz

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 (430) hide show
  1. {gapit-0.4.0 → gapit-0.5.1}/AGENTS.md +61 -28
  2. gapit-0.5.1/CHANGELOG.md +591 -0
  3. {gapit-0.4.0 → gapit-0.5.1}/PKG-INFO +30 -17
  4. {gapit-0.4.0 → gapit-0.5.1}/PLAN.md +49 -0
  5. {gapit-0.4.0 → gapit-0.5.1}/README.md +29 -16
  6. {gapit-0.4.0 → gapit-0.5.1}/SPEC.md +28 -28
  7. {gapit-0.4.0 → gapit-0.5.1}/docs/agents.md +18 -11
  8. gapit-0.5.1/docs/agents.zh.md +205 -0
  9. gapit-0.5.1/docs/custom-db.zh.md +434 -0
  10. {gapit-0.4.0 → gapit-0.5.1}/docs/databases.md +208 -94
  11. gapit-0.5.1/docs/databases.zh.md +701 -0
  12. {gapit-0.4.0 → gapit-0.5.1}/docs/faq.md +32 -15
  13. gapit-0.5.1/docs/faq.zh.md +113 -0
  14. {gapit-0.4.0 → gapit-0.5.1}/docs/index.md +7 -4
  15. gapit-0.5.1/docs/index.zh.md +48 -0
  16. {gapit-0.4.0 → gapit-0.5.1}/docs/installation.md +19 -14
  17. gapit-0.5.1/docs/installation.zh.md +107 -0
  18. {gapit-0.4.0 → gapit-0.5.1}/docs/mcp.md +12 -12
  19. gapit-0.5.1/docs/mcp.zh.md +294 -0
  20. {gapit-0.4.0 → gapit-0.5.1}/docs/outputs.md +123 -16
  21. gapit-0.5.1/docs/outputs.zh.md +569 -0
  22. {gapit-0.4.0 → gapit-0.5.1}/docs/quickstart.md +44 -8
  23. gapit-0.5.1/docs/quickstart.zh.md +177 -0
  24. {gapit-0.4.0 → gapit-0.5.1}/docs/reads.md +150 -31
  25. gapit-0.5.1/docs/reads.zh.md +682 -0
  26. {gapit-0.4.0 → gapit-0.5.1}/docs/screen.md +134 -27
  27. gapit-0.5.1/docs/screen.zh.md +380 -0
  28. {gapit-0.4.0 → gapit-0.5.1}/docs/summary.md +51 -13
  29. gapit-0.5.1/docs/summary.zh.md +212 -0
  30. gapit-0.5.1/docs/typing.md +331 -0
  31. gapit-0.5.1/docs/typing.zh.md +310 -0
  32. gapit-0.5.1/mkdocs.yml +69 -0
  33. {gapit-0.4.0 → gapit-0.5.1}/pixi.lock +11 -2
  34. {gapit-0.4.0 → gapit-0.5.1}/pixi.toml +2 -1
  35. {gapit-0.4.0 → gapit-0.5.1}/pyproject.toml +7 -7
  36. {gapit-0.4.0 → gapit-0.5.1}/recipe/meta.yaml +9 -9
  37. {gapit-0.4.0 → gapit-0.5.1}/scripts/cluster_calibration.py +6 -3
  38. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/__init__.py +1 -1
  39. gapit-0.5.1/src/gapit/bundled.py +148 -0
  40. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cli.py +14 -7
  41. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cluster.py +2 -1
  42. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/clusterbuild.py +23 -8
  43. gapit-0.5.1/src/gapit/cmd_db.py +124 -0
  44. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cmd_db_build.py +20 -7
  45. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cmd_db_install.py +6 -6
  46. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cmd_db_outdated.py +11 -9
  47. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cmd_db_search.py +15 -6
  48. gapit-0.5.1/src/gapit/cmd_screen.py +354 -0
  49. gapit-0.5.1/src/gapit/cmd_screen_positionals.py +43 -0
  50. gapit-0.5.1/src/gapit/cmd_screen_reads_args.py +102 -0
  51. gapit-0.5.1/src/gapit/cmd_summary.py +125 -0
  52. gapit-0.5.1/src/gapit/cmd_typing.py +107 -0
  53. gapit-0.5.1/src/gapit/data/dbs/ecoh/bundled.json +7 -0
  54. gapit-0.5.1/src/gapit/data/dbs/ecoh/sequences +13445 -0
  55. gapit-0.5.1/src/gapit/data/dbs/ecoli_dec/bundled.json +7 -0
  56. gapit-0.5.1/src/gapit/data/dbs/ecoli_dec/sequences +352 -0
  57. gapit-0.5.1/src/gapit/data/dbs/ecoli_dec/typing.json +125 -0
  58. gapit-0.5.1/src/gapit/data/dbs/ncbi/bundled.json +7 -0
  59. gapit-0.5.1/src/gapit/data/dbs/ncbi/sequences +143433 -0
  60. gapit-0.5.1/src/gapit/data/dbs/resfinder/bundled.json +7 -0
  61. gapit-0.5.1/src/gapit/data/dbs/resfinder/sequences +54493 -0
  62. gapit-0.5.1/src/gapit/data/dbs/upec_expec_vf/bundled.json +7 -0
  63. gapit-0.5.1/src/gapit/data/dbs/upec_expec_vf/sequences +2648 -0
  64. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/db_build_ops.py +16 -7
  65. gapit-0.5.1/src/gapit/db_ops.py +286 -0
  66. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/db_query_ops.py +4 -29
  67. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/dbbuild.py +10 -0
  68. gapit-0.5.1/src/gapit/dispatch.py +72 -0
  69. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/engines.py +7 -1
  70. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/formats/cluster.py +18 -6
  71. gapit-0.5.1/src/gapit/formats/cluster_md.py +164 -0
  72. gapit-0.5.1/src/gapit/formats/json.py +158 -0
  73. gapit-0.5.1/src/gapit/formats/md.py +255 -0
  74. gapit-0.4.0/src/gapit/formats/json.py → gapit-0.5.1/src/gapit/formats/reads_json.py +8 -142
  75. gapit-0.5.1/src/gapit/formats/reads_tsv.py +69 -0
  76. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/formats/schemas.py +4 -6
  77. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/formats/summary.py +15 -9
  78. gapit-0.5.1/src/gapit/formats/tsv.py +67 -0
  79. gapit-0.5.1/src/gapit/formats/typing_result.py +158 -0
  80. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/mcp_schemas.py +14 -9
  81. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/mcp_tools.py +8 -14
  82. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/minimap2_run.py +7 -0
  83. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/__init__.py +14 -8
  84. gapit-0.5.1/src/gapit/providers/ab_k.py +38 -0
  85. gapit-0.5.1/src/gapit/providers/ab_o.py +39 -0
  86. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/argannot.py +1 -1
  87. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/bacmet2.py +1 -1
  88. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/card.py +6 -1
  89. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/cluster_common.py +8 -6
  90. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/common.py +15 -52
  91. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/ecoh.py +1 -1
  92. gapit-0.5.1/src/gapit/providers/ecoli_kps.py +39 -0
  93. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/ecoli_vf.py +6 -1
  94. gapit-0.5.1/src/gapit/providers/kosc_k.py +41 -0
  95. gapit-0.5.1/src/gapit/providers/kosc_o.py +41 -0
  96. gapit-0.5.1/src/gapit/providers/kpsc_k.py +40 -0
  97. gapit-0.5.1/src/gapit/providers/kpsc_o.py +40 -0
  98. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/megares.py +1 -1
  99. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/ncbi.py +1 -1
  100. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/plasmidfinder.py +1 -1
  101. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/resfinder.py +1 -1
  102. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/upec_expec_vf.py +1 -1
  103. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/vfdb.py +5 -1
  104. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/providers/victors.py +1 -1
  105. gapit-0.5.1/src/gapit/readpairs.py +110 -0
  106. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/reads.py +5 -2
  107. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/records.py +8 -0
  108. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/report.py +3 -1
  109. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/screening.py +70 -37
  110. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/screening_cluster.py +67 -39
  111. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/screening_reads.py +44 -28
  112. gapit-0.5.1/src/gapit/screening_reads_positional.py +168 -0
  113. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/summary.py +60 -23
  114. gapit-0.5.1/src/gapit/typing_decide.py +106 -0
  115. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/typing_engine.py +74 -61
  116. gapit-0.5.1/src/gapit/typing_gene.py +172 -0
  117. gapit-0.5.1/src/gapit/typing_input.py +234 -0
  118. gapit-0.5.1/src/gapit/typing_models.py +299 -0
  119. gapit-0.5.1/src/gapit/typing_ops.py +104 -0
  120. gapit-0.5.1/src/gapit/typing_results.py +110 -0
  121. gapit-0.5.1/src/gapit/typing_rules.py +179 -0
  122. gapit-0.5.1/tests/data/bundled_differential/resfinder/HEAD.zip +0 -0
  123. gapit-0.5.1/tests/data/bundled_differential/resfinder/README.md +15 -0
  124. gapit-0.5.1/tests/data/cluster/typing_screen_v2.json +27 -0
  125. gapit-0.5.1/tests/data/reads/s1_1.fq.gz +0 -0
  126. gapit-0.5.1/tests/data/reads/s1_2.fq.gz +0 -0
  127. gapit-0.5.1/tests/data/reads/s2_R1.fq.gz +0 -0
  128. gapit-0.5.1/tests/data/reads/s2_R2.fq.gz +0 -0
  129. gapit-0.5.1/tests/data/typing/dec_s1_aggR_pic_uidA.fasta +100 -0
  130. gapit-0.5.1/tests/data/typing/dec_s2_pic_astA_uidA.fasta +90 -0
  131. gapit-0.5.1/tests/data/typing/dec_s3_stx2a_escV_aggR_uidA.fasta +85 -0
  132. gapit-0.5.1/tests/data/typing/exact.fa +39 -0
  133. gapit-0.5.1/tests/data/typing/listeria_1c.fa +29 -0
  134. gapit-0.5.1/tests/data/typing/listeria_4b.fa +32 -0
  135. gapit-0.5.1/tests/data/typing/listeria_nogate.fa +9 -0
  136. gapit-0.5.1/tests/data/typing/markers.fa +39 -0
  137. gapit-0.5.1/tests/data/typing/mutated.fa +39 -0
  138. gapit-0.5.1/tests/data/typing/negative.fa +30 -0
  139. gapit-0.5.1/tests/data/typing/partial.fa +19 -0
  140. gapit-0.5.1/tests/data/typing/schemes/cholerae.gbk +153 -0
  141. gapit-0.5.1/tests/data/typing/schemes/cholerae.json +58 -0
  142. gapit-0.5.1/tests/data/typing/schemes/dec.fa +144 -0
  143. gapit-0.5.1/tests/data/typing/schemes/dec.json +125 -0
  144. gapit-0.5.1/tests/data/typing/schemes/doumith.fa +49 -0
  145. gapit-0.5.1/tests/data/typing/schemes/doumith.json +42 -0
  146. gapit-0.5.1/tests/data/typing/schemes/meningotype.fa +66 -0
  147. gapit-0.5.1/tests/data/typing/schemes/meningotype.json +60 -0
  148. gapit-0.5.1/tests/data/typing/schemes/shigella.fa +151 -0
  149. gapit-0.5.1/tests/data/typing/schemes/shigella.json +74 -0
  150. gapit-0.5.1/tests/data/typing/schemes/vp_ok.gbk +241 -0
  151. gapit-0.5.1/tests/data/typing/schemes/vp_ok.json +66 -0
  152. gapit-0.5.1/tests/data/typing/serotyping.fa +99 -0
  153. gapit-0.5.1/tests/data/typing/typing_markers_v1.json +22 -0
  154. gapit-0.5.1/tests/data/typing/typing_markers_v2.json +47 -0
  155. gapit-0.5.1/tests/data/typing/typing_serotyping_v2.json +71 -0
  156. gapit-0.5.1/tests/data/typing/vp_mixed.fa +39 -0
  157. gapit-0.5.1/tests/data/typing/vp_typed.fa +19 -0
  158. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_exact.json +1 -1
  159. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_exact.md +3 -4
  160. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_fragmented.json +1 -1
  161. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_fragmented.md +3 -4
  162. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_ambiguous.json +1 -1
  163. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_ambiguous.md +3 -4
  164. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_cm_exact.json +1 -1
  165. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_cm_exact.md +3 -4
  166. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_exact.json +1 -1
  167. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_exact.md +3 -4
  168. gapit-0.5.1/tests/golden/cluster_vc_inaba.json +95 -0
  169. gapit-0.5.1/tests/golden/cluster_vc_inaba.md +30 -0
  170. gapit-0.5.1/tests/golden/cluster_vc_inaba.tsv +2 -0
  171. gapit-0.5.1/tests/golden/ecoli_dec_typed.tsv +8 -0
  172. gapit-0.5.1/tests/golden/ecoli_dec_typing.tsv +5 -0
  173. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/fragments_merge.json +1 -1
  174. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/fragments_merge.md +1 -3
  175. gapit-0.5.1/tests/golden/gene_dec_pic_astA.json +69 -0
  176. gapit-0.5.1/tests/golden/gene_dec_pic_astA.md +20 -0
  177. gapit-0.5.1/tests/golden/gene_doumith_4b.json +69 -0
  178. gapit-0.5.1/tests/golden/gene_doumith_4b.md +20 -0
  179. gapit-0.5.1/tests/golden/gene_serotyping_l4b.json +69 -0
  180. gapit-0.5.1/tests/golden/gene_serotyping_l4b.md +20 -0
  181. gapit-0.5.1/tests/golden/gene_serotyping_mixed.json +85 -0
  182. gapit-0.5.1/tests/golden/gene_serotyping_mixed.md +21 -0
  183. gapit-0.5.1/tests/golden/gene_serotyping_vp_typed.json +53 -0
  184. gapit-0.5.1/tests/golden/gene_serotyping_vp_typed.md +19 -0
  185. gapit-0.5.1/tests/golden/gene_shigella_mixed.json +101 -0
  186. gapit-0.5.1/tests/golden/gene_shigella_mixed.md +22 -0
  187. gapit-0.5.1/tests/golden/gene_typing_exact.json +85 -0
  188. gapit-0.5.1/tests/golden/gene_typing_exact.md +21 -0
  189. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/reads_tinyamr.json +3 -3
  190. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/reads_tinyamr.md +2 -2
  191. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/screen_multi.json +1 -1
  192. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/screen_multi.md +1 -3
  193. gapit-0.5.1/tests/golden/summary_dutch.tsv +4 -0
  194. gapit-0.5.1/tests/golden/summary_multi.csv +3 -0
  195. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/summary_multi.json +1 -1
  196. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/summary_multi.md +4 -4
  197. gapit-0.5.1/tests/golden/summary_multi.tsv +4 -0
  198. gapit-0.5.1/tests/golden/typing_markers.json +157 -0
  199. gapit-0.5.1/tests/golden/typing_markers.md +20 -0
  200. gapit-0.5.1/tests/golden/typing_markers.tsv +7 -0
  201. gapit-0.5.1/tests/golden/typing_serotyping.tsv +21 -0
  202. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/run_summary_parity.py +4 -4
  203. gapit-0.5.1/tests/test_bundled.py +517 -0
  204. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_aligner.py +51 -23
  205. gapit-0.5.1/tests/test_cli_bare_help.py +128 -0
  206. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_db_build_cluster.py +13 -8
  207. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_db_fetch.py +143 -108
  208. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_db_query.py +14 -46
  209. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_reads.py +133 -26
  210. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_reads2.py +39 -14
  211. gapit-0.5.1/tests/test_cli_reads_glob.py +311 -0
  212. gapit-0.5.1/tests/test_cli_reads_glob_jobs.py +437 -0
  213. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_screen.py +209 -2
  214. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_setupdb.py +50 -17
  215. gapit-0.5.1/tests/test_cli_short_options.py +490 -0
  216. gapit-0.5.1/tests/test_cli_summary.py +351 -0
  217. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cluster_db.py +11 -4
  218. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cluster_typing.py +9 -2
  219. gapit-0.5.1/tests/test_db_list_extras.py +169 -0
  220. {gapit-0.4.0 → gapit-0.5.1}/tests/test_error_envelope.py +15 -2
  221. {gapit-0.4.0 → gapit-0.5.1}/tests/test_gapit_db_e2e.py +14 -3
  222. gapit-0.5.1/tests/test_gene_typing.py +537 -0
  223. gapit-0.5.1/tests/test_gene_typing2.py +389 -0
  224. {gapit-0.4.0 → gapit-0.5.1}/tests/test_mcp.py +19 -2
  225. {gapit-0.4.0 → gapit-0.5.1}/tests/test_mcp_db_tools.py +67 -48
  226. {gapit-0.4.0 → gapit-0.5.1}/tests/test_mcp_reads.py +17 -2
  227. {gapit-0.4.0 → gapit-0.5.1}/tests/test_md_format.py +0 -4
  228. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_kaptive.py +78 -37
  229. {gapit-0.4.0 → gapit-0.5.1}/tests/test_providers_common.py +27 -0
  230. gapit-0.5.1/tests/test_readpairs.py +210 -0
  231. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads2_homologs.py +3 -1
  232. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads2_model.py +1 -1
  233. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads_streaming.py +2 -2
  234. {gapit-0.4.0 → gapit-0.5.1}/tests/test_screening_reads_unit.py +29 -3
  235. gapit-0.5.1/tests/test_streaming_chunks.py +522 -0
  236. {gapit-0.4.0 → gapit-0.5.1}/tests/test_summary_formats.py +5 -5
  237. gapit-0.5.1/tests/test_typing_command.py +660 -0
  238. {gapit-0.4.0 → gapit-0.5.1}/tests/test_typing_engine.py +31 -22
  239. gapit-0.5.1/tests/test_typing_models.py +678 -0
  240. gapit-0.5.1/tests/test_typing_schemes.py +663 -0
  241. gapit-0.5.1/tests/test_typing_schemes_cluster.py +320 -0
  242. gapit-0.5.1/tests/test_typing_stage2.py +509 -0
  243. gapit-0.4.0/.github/workflows/snapshot-refresh.yml +0 -129
  244. gapit-0.4.0/CHANGELOG.md +0 -193
  245. gapit-0.4.0/mkdocs.yml +0 -36
  246. gapit-0.4.0/src/gapit/cmd_db.py +0 -113
  247. gapit-0.4.0/src/gapit/cmd_screen.py +0 -257
  248. gapit-0.4.0/src/gapit/cmd_summary.py +0 -65
  249. gapit-0.4.0/src/gapit/data/snapshots/card.tar.gz +0 -0
  250. gapit-0.4.0/src/gapit/data/snapshots/vfdb.tar.gz +0 -0
  251. gapit-0.4.0/src/gapit/db_ops.py +0 -145
  252. gapit-0.4.0/src/gapit/dispatch.py +0 -31
  253. gapit-0.4.0/src/gapit/formats/cluster_md.py +0 -149
  254. gapit-0.4.0/src/gapit/formats/md.py +0 -198
  255. gapit-0.4.0/src/gapit/formats/tsv.py +0 -45
  256. gapit-0.4.0/src/gapit/providers/kaptive_ak.py +0 -27
  257. gapit-0.4.0/src/gapit/providers/kaptive_k.py +0 -34
  258. gapit-0.4.0/src/gapit/providers/kaptive_o.py +0 -26
  259. gapit-0.4.0/src/gapit/providers/kaptive_oc.py +0 -27
  260. gapit-0.4.0/src/gapit/providers/snapshots.py +0 -119
  261. gapit-0.4.0/src/gapit/typing_models.py +0 -213
  262. gapit-0.4.0/tests/golden/summary_dutch.tsv +0 -4
  263. gapit-0.4.0/tests/golden/summary_multi.csv +0 -3
  264. gapit-0.4.0/tests/golden/summary_multi.tsv +0 -4
  265. gapit-0.4.0/tests/test_cli_summary.py +0 -201
  266. gapit-0.4.0/tests/test_snapshots.py +0 -204
  267. gapit-0.4.0/tests/test_typing_models.py +0 -140
  268. {gapit-0.4.0 → gapit-0.5.1}/.gitattributes +0 -0
  269. {gapit-0.4.0 → gapit-0.5.1}/.github/workflows/ci.yml +0 -0
  270. {gapit-0.4.0 → gapit-0.5.1}/.github/workflows/docs.yml +0 -0
  271. {gapit-0.4.0 → gapit-0.5.1}/.github/workflows/release.yml +0 -0
  272. {gapit-0.4.0 → gapit-0.5.1}/.gitignore +0 -0
  273. {gapit-0.4.0 → gapit-0.5.1}/LICENSE +0 -0
  274. {gapit-0.4.0 → gapit-0.5.1}/docs/custom-db.md +0 -0
  275. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/blast.py +0 -0
  276. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/cluster_math.py +0 -0
  277. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/config.py +0 -0
  278. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/db.py +0 -0
  279. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/dbcodec.py +0 -0
  280. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/errors.py +0 -0
  281. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/fasta.py +0 -0
  282. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/formats/__init__.py +0 -0
  283. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/fragments.py +0 -0
  284. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/gbfeatures.py +0 -0
  285. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/gffparse.py +0 -0
  286. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/hits.py +0 -0
  287. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/mcp.py +0 -0
  288. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/minimap.py +0 -0
  289. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/paf.py +0 -0
  290. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/proctools.py +0 -0
  291. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/py.typed +0 -0
  292. {gapit-0.4.0 → gapit-0.5.1}/src/gapit/seqconvert.py +0 -0
  293. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/bakta_style.gbk +0 -0
  294. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/clusters.gff3 +0 -0
  295. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/clusters_gz.gff3.gz +0 -0
  296. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/clusters_sidecar.fa +0 -0
  297. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/clusters_sidecar.gff3 +0 -0
  298. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/compound.gbk +0 -0
  299. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/gz_input.gbk.gz +0 -0
  300. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/kaptive_style.gbk +0 -0
  301. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/nofasta.gff3 +0 -0
  302. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/screening.gbk +0 -0
  303. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/typing_invalid.json +0 -0
  304. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/typing_screen.json +0 -0
  305. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/typing_screen_cm.json +0 -0
  306. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/typing_valid.json +0 -0
  307. {gapit-0.4.0 → gapit-0.5.1}/tests/data/cluster/unnamed_cds.gbk +0 -0
  308. {gapit-0.4.0 → gapit-0.5.1}/tests/data/contigs/full.fa +0 -0
  309. {gapit-0.4.0 → gapit-0.5.1}/tests/data/contigs/gap.fa +0 -0
  310. {gapit-0.4.0 → gapit-0.5.1}/tests/data/contigs/none.fa +0 -0
  311. {gapit-0.4.0 → gapit-0.5.1}/tests/data/contigs/partial.fa +0 -0
  312. {gapit-0.4.0 → gapit-0.5.1}/tests/data/contigs/sort.fa +0 -0
  313. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.embl +0 -0
  314. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.embl.bz2 +0 -0
  315. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.fa +0 -0
  316. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.fa.gz +0 -0
  317. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.fq +0 -0
  318. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.gbk +0 -0
  319. {gapit-0.4.0 → gapit-0.5.1}/tests/data/convert/sample.gbk.gz +0 -0
  320. {gapit-0.4.0 → gapit-0.5.1}/tests/data/db/tinyamr/sequences +0 -0
  321. {gapit-0.4.0 → gapit-0.5.1}/tests/data/fragments/fragdb/sequences +0 -0
  322. {gapit-0.4.0 → gapit-0.5.1}/tests/data/fragments/split3040.fa +0 -0
  323. {gapit-0.4.0 → gapit-0.5.1}/tests/data/fragments/split4060.fa +0 -0
  324. {gapit-0.4.0 → gapit-0.5.1}/tests/data/fragments/split5050.fa +0 -0
  325. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/argannot/ARG-ANNOT_NT_V6_July2019.txt +0 -0
  326. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/bacmet2/BacMet2_EXP_database.fasta +0 -0
  327. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/card/card.json +0 -0
  328. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/ecoh/EcOH.fasta +0 -0
  329. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/ecoli_vf/repaired_ecoli_vfs_shortnames.ffn +0 -0
  330. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/megares/megares_drugs_demo.fasta +0 -0
  331. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/ncbi/AMR_CDS.fa +0 -0
  332. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/ncbi/ReferenceGeneCatalog.txt +0 -0
  333. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/plasmidfinder/plasmids_a.fsa +0 -0
  334. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/plasmidfinder/plasmids_b.fsa +0 -0
  335. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/resfinder/aminoglycoside.fsa +0 -0
  336. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/resfinder/beta-lactam.fsa +0 -0
  337. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/resfinder/phenotypes.txt +0 -0
  338. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/upec_expec_vf/UPEC_ExPEC_VF.tsv +0 -0
  339. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/vfdb/VFDB_setA_nt.fas +0 -0
  340. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/victors/gen_downloads.php +0 -0
  341. {gapit-0.4.0 → gapit-0.5.1}/tests/data/providers/victors/gen_downloads_protein.php +0 -0
  342. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/bla_partial.fq +0 -0
  343. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/junk.fq +0 -0
  344. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/suly_partial.fq +0 -0
  345. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_R1.fq +0 -0
  346. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_R2.fq +0 -0
  347. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_full.fq +0 -0
  348. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_full.fq.gz +0 -0
  349. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_lane1.fq +0 -0
  350. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_lane2.fq +0 -0
  351. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_pe1_R1.fq +0 -0
  352. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_pe1_R2.fq +0 -0
  353. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_pe2_R1.fq +0 -0
  354. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads/tetx_pe2_R2.fq +0 -0
  355. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads2/ont_homologs.fq +0 -0
  356. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads2/sr_homologs.fq +0 -0
  357. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads2_db/homologs/sequences +0 -0
  358. {gapit-0.4.0 → gapit-0.5.1}/tests/data/reads_db/tinyreads/sequences +0 -0
  359. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/empty.tsv +0 -0
  360. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/multi_sample.tsv +0 -0
  361. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/sample_a.csv +0 -0
  362. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/sample_a.tsv +0 -0
  363. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/sample_b.csv +0 -0
  364. {gapit-0.4.0 → gapit-0.5.1}/tests/data/summary/sample_b.tsv +0 -0
  365. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_exact.tsv +0 -0
  366. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_fragmented.tsv +0 -0
  367. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_ambiguous.tsv +0 -0
  368. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_cm_exact.tsv +0 -0
  369. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/cluster_typing_exact.tsv +0 -0
  370. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/fragments_merge.tsv +0 -0
  371. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/tinyamr_multi_nopath.csv +0 -0
  372. {gapit-0.4.0 → gapit-0.5.1}/tests/golden/tinyamr_multi_nopath.tsv +0 -0
  373. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/corpus/01_exact_and_junk.fa +0 -0
  374. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/corpus/02_mutated.fa +0 -0
  375. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/corpus/03_truncated.fa +0 -0
  376. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/corpus/04_reverse.fa +0 -0
  377. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/corpus/05_threshold.fa +0 -0
  378. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/make_corpus.py +0 -0
  379. {gapit-0.4.0 → gapit-0.5.1}/tests/parity/run_parity.py +0 -0
  380. {gapit-0.4.0 → gapit-0.5.1}/tests/test_blast_parse.py +0 -0
  381. {gapit-0.4.0 → gapit-0.5.1}/tests/test_blast_pipeline.py +0 -0
  382. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_completion.py +0 -0
  383. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_db_build.py +0 -0
  384. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_fragments.py +0 -0
  385. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_schema.py +0 -0
  386. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cli_screen_jobs.py +0 -0
  387. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cluster_calibration.py +0 -0
  388. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cluster_math.py +0 -0
  389. {gapit-0.4.0 → gapit-0.5.1}/tests/test_cluster_screen.py +0 -0
  390. {gapit-0.4.0 → gapit-0.5.1}/tests/test_config.py +0 -0
  391. {gapit-0.4.0 → gapit-0.5.1}/tests/test_db.py +0 -0
  392. {gapit-0.4.0 → gapit-0.5.1}/tests/test_db_fetch.py +0 -0
  393. {gapit-0.4.0 → gapit-0.5.1}/tests/test_db_headers.py +0 -0
  394. {gapit-0.4.0 → gapit-0.5.1}/tests/test_dbbuild.py +0 -0
  395. {gapit-0.4.0 → gapit-0.5.1}/tests/test_dbcodec.py +0 -0
  396. {gapit-0.4.0 → gapit-0.5.1}/tests/test_fasta.py +0 -0
  397. {gapit-0.4.0 → gapit-0.5.1}/tests/test_fragments.py +0 -0
  398. {gapit-0.4.0 → gapit-0.5.1}/tests/test_gbfeatures.py +0 -0
  399. {gapit-0.4.0 → gapit-0.5.1}/tests/test_gffparse.py +0 -0
  400. {gapit-0.4.0 → gapit-0.5.1}/tests/test_hits.py +0 -0
  401. {gapit-0.4.0 → gapit-0.5.1}/tests/test_json_format.py +0 -0
  402. {gapit-0.4.0 → gapit-0.5.1}/tests/test_mcp_protocol.py +0 -0
  403. {gapit-0.4.0 → gapit-0.5.1}/tests/test_minimap.py +0 -0
  404. {gapit-0.4.0 → gapit-0.5.1}/tests/test_mol_type.py +0 -0
  405. {gapit-0.4.0 → gapit-0.5.1}/tests/test_oversubscription.py +0 -0
  406. {gapit-0.4.0 → gapit-0.5.1}/tests/test_paf.py +0 -0
  407. {gapit-0.4.0 → gapit-0.5.1}/tests/test_paf_identity.py +0 -0
  408. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_argannot.py +0 -0
  409. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_bacmet2.py +0 -0
  410. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_card.py +0 -0
  411. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_ecoh.py +0 -0
  412. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_ecoli_vf.py +0 -0
  413. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_megares.py +0 -0
  414. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_ncbi.py +0 -0
  415. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_plasmidfinder.py +0 -0
  416. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_resfinder.py +0 -0
  417. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_upec_expec_vf.py +0 -0
  418. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_vfdb.py +0 -0
  419. {gapit-0.4.0 → gapit-0.5.1}/tests/test_provider_victors.py +0 -0
  420. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads_aggregate.py +0 -0
  421. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads_integration.py +0 -0
  422. {gapit-0.4.0 → gapit-0.5.1}/tests/test_reads_interval_union.py +0 -0
  423. {gapit-0.4.0 → gapit-0.5.1}/tests/test_records.py +0 -0
  424. {gapit-0.4.0 → gapit-0.5.1}/tests/test_report.py +0 -0
  425. {gapit-0.4.0 → gapit-0.5.1}/tests/test_screen_integration.py +0 -0
  426. {gapit-0.4.0 → gapit-0.5.1}/tests/test_seqconvert.py +0 -0
  427. {gapit-0.4.0 → gapit-0.5.1}/tests/test_seqconvert_differential.py +0 -0
  428. {gapit-0.4.0 → gapit-0.5.1}/tests/test_summary.py +0 -0
  429. {gapit-0.4.0 → gapit-0.5.1}/tests/test_tsv.py +0 -0
  430. {gapit-0.4.0 → gapit-0.5.1}/tests/test_version.py +0 -0
@@ -1,15 +1,18 @@
1
1
  # AGENTS.md — gapit
2
2
 
3
- > Python reimplementation of [abricate](https://github.com/tseemann/abricate): mass screening of
4
- > contigs and reads for known genes. **Agent-first**: every output is
5
- > machine-readable (JSON / Markdown) by design, not as an afterthought.
3
+ > Python tool for mass screening of contigs and reads for known genes, with gene-cluster
4
+ > typing and phenotype designation. Originally a reimplementation of
5
+ > [abricate](https://github.com/tseemann/abricate); **from v0.5.0 onward gapit pursues its
6
+ > own contract** — abricate parity is no longer a design goal. **Agent-first**: every
7
+ > output is machine-readable (JSON / Markdown) by design, not as an afterthought.
6
8
 
7
9
  ## 1. Mission
8
10
 
9
11
  `gapit` answers one question: **which known genes are present in this assembly, and how confident
10
- are we?** It replaces abricate (Perl) with a modern, typed, testable Python tool that:
12
+ are we?** A modern, typed, testable Python tool that:
11
13
 
12
- 1. Produces byte-compatible TSV with abricate (drop-in replacement for existing pipelines).
14
+ 1. Ships an abricate-compatible contig TSV as the historical baseline surface (frozen
15
+ behavior, kept for existing pipelines), while new development follows gapit's own design.
13
16
  2. Adds first-class **JSON** and **Markdown** outputs so LLM agents and humans can consume
14
17
  results without parsing tab-delimited text.
15
18
  3. Exposes stable, versioned output contracts (schemas, exit codes, error envelopes) that
@@ -52,7 +55,7 @@ Every change must leave `lint`, `typecheck`, and `test` green.
52
55
  gapit/
53
56
  ├── AGENTS.md # this file
54
57
  ├── PLAN.md # development roadmap (phase-gated)
55
- ├── SPEC.md # distilled abricate behavior spec (source of truth for parity)
58
+ ├── SPEC.md # frozen contract for the baseline surface (distilled from abricate)
56
59
  ├── pixi.toml
57
60
  ├── recipe/
58
61
  │ └── meta.yaml # conda recipe (submission deferred)
@@ -62,7 +65,7 @@ gapit/
62
65
  │ ├── __init__.py
63
66
  │ ├── cli.py # typer entrypoint: screen / summary / db / setupdb / schema / mcp
64
67
  │ ├── config.py # datadir resolution, defaults, env vars
65
- │ ├── dispatch.py # shared CLI dispatch (error envelope → exit codes) + --datadir option
68
+ │ ├── dispatch.py # shared CLI dispatch (error envelope → exit codes) + --datadir option + --output target
66
69
  │ ├── proctools.py # external-tool plumbing: argv subprocess runner + stderr notes
67
70
  │ ├── fasta.py # streaming FASTA reader + shared gz/bz2 text opener
68
71
  │ ├── seqconvert.py # native input normalization: fa/fq/gbk/embl (±gz/bz2) → FASTA
@@ -73,13 +76,18 @@ gapit/
73
76
  │ ├── clusterbuild.py # cluster-db build pipeline: GBK/GFF → locus FASTA + features.json + typing copy
74
77
  │ ├── cluster.py # cluster-screening engine core: minimap2 asm20 → per-locus/per-gene calls
75
78
  │ ├── cluster_math.py # cs-walk → union coverage/identity math + verdicts (pure functions)
76
- │ ├── db_ops.py # db use-cases: provider fetch + list (shared CLI + MCP; no typer)
79
+ │ ├── db_ops.py # db use-cases: fetch + list (shared CLI + MCP; no typer)
77
80
  │ ├── db_query_ops.py # db use-cases: search + outdated over installed DBs (shared CLI + MCP)
78
81
  │ ├── db_build_ops.py # db use-case: custom FASTA+TSV → gene db, GBK/GFF → cluster db (shared CLI + MCP)
79
82
  │ ├── gbfeatures.py # GenBank FEATURES/ORIGIN parser → LocusFeatures/GeneFeature + gapit.features/1
80
83
  │ ├── gffparse.py # GFF3 parser (embedded ##FASTA or sidecar) → the same locus/gene models
81
- │ ├── typing_models.py # gapit.typing/1 scoring schema + the evaluation-result models
82
- │ ├── typing_engine.py # gapit.typing/1 evaluation: rule scoring → phenotype call + breakdown
84
+ │ ├── typing_models.py # gapit.typing schema (rules + named schemes; /1 degrades to one default scheme)
85
+ │ ├── typing_rules.py # gapit.typing rule models (weighted_genes/exact_set/cluster_match/learned_linear) + reference checks
86
+ │ ├── typing_decide.py # typing decision layer: ranking, control-gene gate, unique-group mixed override
87
+ │ ├── typing_results.py # typing evaluation-result models (PhenotypeDetail, SchemeCall)
88
+ │ ├── typing_engine.py # typing evaluation, cluster path: rule scoring → phenotype call + breakdown
89
+ │ ├── typing_gene.py # typing evaluation, gene path (DEC markers): hits → per-scheme report phenotypes
90
+ │ ├── bundled.py # bundled databases: discovery + materialize-into-datadir (public-domain panels)
83
91
  │ ├── blast.py # blastn invocation + tabular output parsing
84
92
  │ ├── hits.py # Hit model, identity/coverage computation, filtering, dedup
85
93
  │ ├── fragments.py # opt-in --merge-fragments cross-contig gene-fragment merging
@@ -88,13 +96,18 @@ gapit/
88
96
  │ ├── paf.py # PAF row parsing + interval arithmetic (minimap2 output boundary)
89
97
  │ ├── report.py # Report model: the canonical in-memory result
90
98
  │ ├── engines.py # shared OutputFormat / AlignerEnum (leaf module for the three engines)
91
- │ ├── screening.py # blastn screen use-case + the shared run_screen dispatcher
99
+ │ ├── screening.py # blastn screen use-case + the shared run_screen dispatcher
92
100
  │ ├── screening_cluster.py # cluster screen use-case: kind guards, typing wiring, rendering
93
101
  │ ├── screening_reads.py # minimap2 use-cases: --r1/--r2 reads + --aligner minimap2 assemblies
94
- │ ├── reads.py # FASTQ mode: minimap2 PAF parsing, coverage breadth/depth, presence
102
+ │ ├── typing_input.py # `gapit typing` input: screen TSV/CSV → per-FILE folded GeneCalls
103
+ │ ├── typing_ops.py # `gapit typing` use-case: resolve db, run the engine, render
104
+ │ ├── reads.py # FASTQ mode: minimap2 PAF parsing, coverage breadth/depth, presence
95
105
  │ ├── summary.py # summary core: parse report tables into a gene matrix
96
106
  │ ├── cmd_screen.py # `gapit screen` CLI (registered from cli.py)
107
+ │ ├── cmd_screen_positionals.py # screen positional guard: db-name-as-file usage error
108
+ │ ├── cmd_screen_reads_args.py # reads-mode CLI arg rules (comma split + flag rejects)
97
109
  │ ├── cmd_summary.py # `gapit summary` CLI (registered from cli.py)
110
+ │ ├── cmd_typing.py # `gapit typing` CLI (registered from cli.py)
98
111
  │ ├── cmd_db.py # `gapit db` command group (fetch | list; registers the subcommands)
99
112
  │ ├── cmd_db_install.py # `gapit db install`: SHA256-verified local-file install
100
113
  │ ├── cmd_db_build.py # `gapit db build` CLI (custom FASTA → native db)
@@ -105,15 +118,16 @@ gapit/
105
118
  │ ├── mcp_schemas.py # MCP tools/list declarations (names, descriptions, inputSchemas)
106
119
  │ ├── errors.py # typed errors + JSON error envelope
107
120
  │ ├── formats/
108
- │ │ ├── tsv.py # abricate-compatible TSV/CSV
121
+ │ │ ├── tsv.py # abricate-compatible TSV/CSV (phenotype-free in every typing version)
109
122
  │ │ ├── json.py # versioned JSON (gapit.report/1 et al.)
123
+ │ │ ├── reads_json.py # versioned JSON (gapit.reads/1, gapit.reads/2)
110
124
  │ │ ├── md.py # Markdown (human + agent readable, YAML frontmatter)
111
125
  │ │ ├── cluster.py # gapit.cluster/1 models + JSON/TSV renderers (typed variant)
112
126
  │ │ ├── cluster_md.py # gapit.cluster/1 Markdown renderer (Phenotype column when typed)
127
+ │ │ ├── typing_result.py # gapit.typing_result/1 models + TSV/JSON/MD renderers
113
128
  │ │ ├── schemas.py # registered output models behind `gapit schema`
114
129
  │ │ └── summary.py # summary matrix renderers (TSV/CSV/JSON/MD)
115
- │ ├── providers/ # 16 DB providers (12 gene + 4 kaptive cluster) + common.py + snapshots.py
116
- │ ├── data/snapshots/ # bundled card + vfdb snapshot archives (.tar.gz)
130
+ │ ├── providers/ # 19 database provider modules (12 gene + 7 kaptive cluster) + cluster_common.py + common.py
117
131
  │ └── py.typed
118
132
  ├── scripts/
119
133
  │ └── cluster_calibration.py # developer calibration harness for typed cluster dbs
@@ -145,7 +159,8 @@ This is what distinguishes gapit from abricate. Treat it as a public API.
145
159
 
146
160
  - **Formats**: `--format tsv|csv|json|md` (default `tsv` for abricate compatibility).
147
161
  - **JSON**: top-level `"schema": "gapit.report/1"`; schema introspectable via
148
- `gapit schema report | reads | reads2 | summary | list | error | version`. Keys are snake_case,
162
+ `gapit schema report | reads | reads2 | summary | list | error | version` (plus
163
+ `cluster | features | typing | typing_result`). Keys are snake_case,
149
164
  units explicit (`identity_pct`, `coverage_pct`). Semver the schema; never rename or
150
165
  retype a field in a minor bump.
151
166
  - **Markdown**: YAML frontmatter (tool version, db, params, ISO-8601 UTC timestamp) + tables a
@@ -153,16 +168,30 @@ This is what distinguishes gapit from abricate. Treat it as a public API.
153
168
  - **Errors**: failures print a JSON envelope to stderr
154
169
  `{"schema": "gapit.error/1", "code": "...", "message": "...", "context": {...}}` and exit with a
155
170
  documented non-zero code (2 = usage, 3 = missing dependency, 4 = db error, 5 = input error).
171
+ - **Typing** `[gapit-extension]`: two-stage designation — `gapit screen -o result.tsv --db NAME`
172
+ detects genes (screen output is phenotype-free; typed and untyped gene dbs screen
173
+ byte-identically), then `gapit typing result.tsv [-D|-f|-o|-q]` designates from the screen
174
+ table (`gapit.typing_result/1`; cluster dbs refuse — their typing rides the screen).
175
+ No typing MCP tool yet (future work).
156
176
  - **DB acquisition** `[gapit-extension]`: `gapit db fetch|list|search|outdated|build|install` —
157
- provider fetch (bundled card/vfdb snapshots install offline; `--from-source` forces upstream),
158
- provider listing, records.jsonl gene search, staleness report, custom FASTA→native-db build,
159
- GBK/GFF→cluster-db build (`--typing` installs a validated `gapit.typing/1` spec), the four
160
- download-on-fetch kaptive cluster providers (GPL content, never bundled), and SHA256-verified
161
- local-file install.
177
+ database fetch from the provider catalog (every provider downloads from upstream at fetch
178
+ time — nothing catalog-side is bundled inside the wheel beyond the sanctioned exceptions,
179
+ a license-compliance requirement: CARD/VFDB terms are non-commercial and Kaptive is GPL,
180
+ so none of those may ride an MIT distribution; the sanctioned exceptions are the five
181
+ content-provenance-audited bundles under `src/gapit/data/dbs/` — the public-domain
182
+ `ecoli_dec` panel plus four permissively licensed provider snapshots (`ncbi` public
183
+ domain, `resfinder` Apache-2.0, `ecoh` BSD-3-Clause, `upec_expec_vf` MIT; GPL/NC content
184
+ is never bundled) — materialized into the datadir on first use via `bundled.py`, with
185
+ `db fetch <name>` still the fresh-upstream refresh path),
186
+ database listing,
187
+ records.jsonl gene search, staleness
188
+ report, custom FASTA→native-db build, GBK/GFF→cluster-db build (`--typing` installs a
189
+ validated `gapit.typing/1` or `/2` spec on either kind), the four download-on-fetch kaptive cluster providers
190
+ (GPL content, never bundled), and SHA256-verified local-file install.
162
191
  - **MCP** `[gapit-extension]`: `gapit mcp` / `gapit-mcp` stdio server exposing nine tools:
163
192
  read-only `screen` (incl. `aligner minimap2` assembly survey), `screen_reads` (FASTQ via
164
193
  minimap2), `summary`, `schema`, `db_list`, `db_search`, `db_outdated`, plus the datadir-mutating
165
- `db_fetch` (installs provider databases; may download) and `db_build` (writes a custom db);
194
+ `db_fetch` (installs databases from the provider catalog; may download) and `db_build` (writes a custom db);
166
195
  tool failures carry the `gapit.error/1` envelope.
167
196
  - **stdout purity**: data on stdout, diagnostics on stderr, always. `--quiet` only affects stderr.
168
197
  - **Self-description**: `gapit --version --json`, `gapit db list --json`, `gapit schema` — an agent
@@ -175,7 +204,9 @@ This is what distinguishes gapit from abricate. Treat it as a public API.
175
204
  committed files deliberately and review diffs like code.
176
205
  - **Parity harness**: `pixi run -e parity parity` (and `summary-parity`) runs real abricate
177
206
  (conda) and gapit over a small genome corpus and diffs the gene calls byte-for-byte (file,
178
- gene, %identity, %coverage). Parity on the corpus is the release gate for v1.0.
207
+ gene, %identity, %coverage). **From v0.5.0 this is a regression reference for the frozen
208
+ baseline surface, not a release gate for new work** — new features need not check abricate
209
+ and may diverge deliberately.
179
210
  - Full suite + CI matrix 3.11/3.13/3.14; parity byte-diff is opt-in via the `parity` pixi env.
180
211
  Offline tests stay fast.
181
212
 
@@ -191,13 +222,15 @@ This is what distinguishes gapit from abricate. Treat it as a public API.
191
222
  query contigs against one db → 15-field
192
223
  tabular hits → filter by identity / coverage thresholds → **dedup hits sharing identical
193
224
  `(contig, qstart, qend)`** (first/best BLAST row wins) → one TSV row per surviving hit.
194
- abricate does **not** merge overlapping intervals — do not "improve" this on the default path (the
195
- opt-in `--merge-fragments` cross-contig extension is the one sanctioned exception:
196
- `fragments.py`).
225
+ The default path does **not** merge overlapping intervals (frozen baseline behavior;
226
+ the opt-in `--merge-fragments` cross-contic extension in `fragments.py` is the sanctioned
227
+ exception).
197
228
  - Key computed fields: `%COVERAGE = 100*(length-gaps)/slen` (filtered unrounded, displayed
198
229
  `%.2f`), `%IDENTITY` (BLAST pident, never post-filtered), `COVERAGE_MAP` (15-char minimap),
199
- `GAPS`. Exact formulas, the dedup rule, and the minimap arithmetic live in `SPEC.md` — when
200
- abricate and intuition disagree, **abricate wins** (parity is a feature).
230
+ `GAPS`. Exact formulas, the dedup rule, and the minimap arithmetic live in `SPEC.md` — they
231
+ are **gapit's frozen contract** for the baseline surface: do not change them silently. New
232
+ surfaces (reads, cluster, typing) follow their own documented contracts and may diverge from
233
+ abricate by design.
201
234
 
202
235
  ## 8. Git & workflow
203
236