genome-spy-python 0.6.0__tar.gz → 0.8.0__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 (589) hide show
  1. genome_spy_python-0.8.0/.agents/skills/commit/SKILL.md +48 -0
  2. genome_spy_python-0.8.0/.agents/skills/contribute-genomespy/SKILL.md +21 -0
  3. genome_spy_python-0.8.0/.agents/skills/proper-code-review/SKILL.md +73 -0
  4. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.github/workflows/ci.yml +113 -1
  5. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.github/workflows/docs.yml +2 -0
  6. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.github/workflows/release.yml +2 -0
  7. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.gitignore +8 -0
  8. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.pre-commit-config.yaml +8 -1
  9. genome_spy_python-0.8.0/AGENTS.md +101 -0
  10. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/CHANGELOG.md +58 -0
  11. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/CONTRIBUTING.md +20 -0
  12. genome_spy_python-0.8.0/LICENSES/SCANPY-BSD-3-Clause.txt +30 -0
  13. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/PKG-INFO +34 -1
  14. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/README.md +28 -0
  15. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/THIRD_PARTY_NOTICES.md +62 -0
  16. genome_spy_python-0.8.0/docs/_ext/genomespy_agents.py +36 -0
  17. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_ext/genomespy_gallery.py +9 -0
  18. genome_spy_python-0.8.0/docs/_ext/genomespy_notebook.py +172 -0
  19. genome_spy_python-0.8.0/docs/_static/gallery/clustered_heatmap.png +0 -0
  20. genome_spy_python-0.8.0/docs/_static/gallery/pbmc_cell_heatmap.png +0 -0
  21. genome_spy_python-0.8.0/docs/_static/gallery/pbmc_expression_tracks.png +0 -0
  22. genome_spy_python-0.8.0/docs/_static/gallery/pbmc_marker_matrix.png +0 -0
  23. genome_spy_python-0.8.0/docs/_static/gallery/pbmc_umap.png +0 -0
  24. genome_spy_python-0.8.0/docs/_static/gallery/pbmc_umap_genes.png +0 -0
  25. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/genomespy.css +17 -0
  26. genome_spy_python-0.8.0/docs/agents/data.md +121 -0
  27. genome_spy_python-0.8.0/docs/agents/embed-api.md +238 -0
  28. genome_spy_python-0.8.0/docs/agents/encodings.md +198 -0
  29. genome_spy_python-0.8.0/docs/agents/manifest.json +124 -0
  30. genome_spy_python-0.8.0/docs/agents/quickstart.md +82 -0
  31. genome_spy_python-0.8.0/docs/agents/rendering.md +66 -0
  32. genome_spy_python-0.8.0/docs/agents/scales-axes-legends.md +100 -0
  33. genome_spy_python-0.8.0/docs/agents/skill-distribution.md +62 -0
  34. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/api.md +35 -0
  35. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/conf.py +4 -1
  36. genome_spy_python-0.8.0/docs/contributing/standards.md +78 -0
  37. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/datasets.md +9 -0
  38. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/ascat_fitting.py +40 -33
  39. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/bam_read_alignments.py +5 -4
  40. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/bam_read_pileup.py +3 -2
  41. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/bigbed_ccre_track.py +3 -2
  42. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/clinvar_variants.py +3 -2
  43. genome_spy_python-0.8.0/docs/examples/clustered_heatmap.md +47 -0
  44. genome_spy_python-0.8.0/docs/examples/clustered_heatmap.py +394 -0
  45. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/combined_laml_oncoplot.py +1 -1
  46. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/composing_genome_browser.py +3 -2
  47. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/dynseq_adaptive_bqtl.py +22 -16
  48. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/dynseq_bqtl.py +22 -16
  49. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/hcc1954_sv_cnv.py +4 -3
  50. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/independent_scales.md +14 -0
  51. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/indexed_fasta_sequence.py +3 -2
  52. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/luad_oncoprint.py +12 -10
  53. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/multiple_sequence_alignment.py +2 -1
  54. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/oncoprint.py +14 -12
  55. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/p53_sequence_comparison.py +1 -1
  56. genome_spy_python-0.8.0/docs/examples/pbmc_cell_heatmap.md +24 -0
  57. genome_spy_python-0.8.0/docs/examples/pbmc_cell_heatmap.py +103 -0
  58. genome_spy_python-0.8.0/docs/examples/pbmc_expression_tracks.md +18 -0
  59. genome_spy_python-0.8.0/docs/examples/pbmc_expression_tracks.py +124 -0
  60. genome_spy_python-0.8.0/docs/examples/pbmc_marker_matrix.md +24 -0
  61. genome_spy_python-0.8.0/docs/examples/pbmc_marker_matrix.py +160 -0
  62. genome_spy_python-0.8.0/docs/examples/pbmc_umap.md +15 -0
  63. genome_spy_python-0.8.0/docs/examples/pbmc_umap.py +58 -0
  64. genome_spy_python-0.8.0/docs/examples/pbmc_umap_genes.md +18 -0
  65. genome_spy_python-0.8.0/docs/examples/pbmc_umap_genes.py +96 -0
  66. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pik3ca_tcga_brca_lollipop.py +1 -1
  67. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pisa_interaction_matrix.md +4 -4
  68. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pisa_interaction_matrix.py +28 -18
  69. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pisa_squid.py +18 -12
  70. genome_spy_python-0.8.0/docs/examples/point_mark.md +14 -0
  71. genome_spy_python-0.8.0/docs/examples/rect_heatmap.md +15 -0
  72. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/rnf7_direct_rna.py +1 -1
  73. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/six_frame_translation.py +5 -4
  74. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/upset_mutations.md +4 -3
  75. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/upset_mutations.py +29 -39
  76. genome_spy_python-0.8.0/docs/examples/vertical_concat.md +14 -0
  77. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/index.md +4 -0
  78. genome_spy_python-0.8.0/docs/integrations/index.md +14 -0
  79. genome_spy_python-0.8.0/docs/integrations/scanpy/api.md +19 -0
  80. genome_spy_python-0.8.0/docs/integrations/scanpy/export.md +5 -0
  81. genome_spy_python-0.8.0/docs/integrations/scanpy/expression.md +2 -0
  82. genome_spy_python-0.8.0/docs/integrations/scanpy/index.md +65 -0
  83. genome_spy_python-0.8.0/docs/integrations/scanpy/linked_expression.md +2 -0
  84. genome_spy_python-0.8.0/docs/integrations/scanpy/paga.md +2 -0
  85. genome_spy_python-0.8.0/docs/integrations/scanpy/pca.md +2 -0
  86. genome_spy_python-0.8.0/docs/integrations/scanpy/profiles.md +2 -0
  87. genome_spy_python-0.8.0/docs/integrations/scanpy/quality.md +2 -0
  88. genome_spy_python-0.8.0/docs/integrations/scanpy/ranked.md +2 -0
  89. genome_spy_python-0.8.0/docs/integrations/scanpy/supported.md +75 -0
  90. genome_spy_python-0.8.0/docs/integrations/scanpy/tracks.md +2 -0
  91. genome_spy_python-0.8.0/docs/integrations/scanpy/umap.md +2 -0
  92. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/composition.py +63 -21
  93. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/encoding_channels.py +9 -0
  94. genome_spy_python-0.8.0/docs/tutorials/expressions.py +34 -0
  95. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/interaction.py +10 -0
  96. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/composition.md +80 -39
  97. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/data.md +54 -5
  98. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/embed-api.md +3 -0
  99. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/encodings.md +23 -2
  100. genome_spy_python-0.8.0/docs/user-guide/expressions.md +90 -0
  101. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/index.md +4 -1
  102. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/interaction.md +21 -9
  103. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/transforms.md +6 -41
  104. genome_spy_python-0.8.0/integrations/README.md +101 -0
  105. genome_spy_python-0.8.0/integrations/scanpy/COMPATIBILITY.md +2023 -0
  106. genome_spy_python-0.8.0/integrations/scanpy/FUTURE.md +55 -0
  107. genome_spy_python-0.8.0/integrations/scanpy/PLAN.md +1896 -0
  108. genome_spy_python-0.8.0/integrations/scanpy/README.md +267 -0
  109. genome_spy_python-0.8.0/integrations/scanpy/STATUS.md +487 -0
  110. genome_spy_python-0.8.0/integrations/scanpy/guides/export.ipynb +184 -0
  111. genome_spy_python-0.8.0/integrations/scanpy/guides/expression.ipynb +447 -0
  112. genome_spy_python-0.8.0/integrations/scanpy/guides/linked_expression.ipynb +317 -0
  113. genome_spy_python-0.8.0/integrations/scanpy/guides/paga.ipynb +468 -0
  114. genome_spy_python-0.8.0/integrations/scanpy/guides/pca.ipynb +158 -0
  115. genome_spy_python-0.8.0/integrations/scanpy/guides/profiles.ipynb +436 -0
  116. genome_spy_python-0.8.0/integrations/scanpy/guides/quality.ipynb +234 -0
  117. genome_spy_python-0.8.0/integrations/scanpy/guides/ranked.ipynb +338 -0
  118. genome_spy_python-0.8.0/integrations/scanpy/guides/tracks.ipynb +246 -0
  119. genome_spy_python-0.8.0/integrations/scanpy/guides/umap.ipynb +790 -0
  120. genome_spy_python-0.8.0/integrations/scanpy/notebooks/scanpy_expression.ipynb +1618 -0
  121. genome_spy_python-0.8.0/integrations/scanpy/notebooks/scanpy_umap.ipynb +793 -0
  122. genome_spy_python-0.8.0/integrations/scanpy/prepare_guide_data.py +96 -0
  123. genome_spy_python-0.8.0/notebooks/penguin_python_roundtrip.ipynb +291 -0
  124. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/pyproject.toml +47 -2
  125. genome_spy_python-0.8.0/skills/create-genomespy-visualization/SKILL.md +93 -0
  126. genome_spy_python-0.8.0/skills/create-genomespy-visualization/agents/openai.yaml +4 -0
  127. genome_spy_python-0.8.0/skills/create-genomespy-visualization/references/grouped-charts.md +102 -0
  128. genome_spy_python-0.8.0/skills/create-genomespy-visualization/references/table-chart.md +157 -0
  129. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/__init__.py +102 -57
  130. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_chart_authoring.py +6 -1
  131. genome_spy_python-0.8.0/src/genome_spy/_skill_install.py +158 -0
  132. genome_spy_python-0.8.0/src/genome_spy/anndata.py +159 -0
  133. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/api.py +71 -27
  134. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/arrow.py +7 -2
  135. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/channels.py +5 -2
  136. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/chart.py +66 -6
  137. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/__init__.py +1 -0
  138. genome_spy_python-0.8.0/src/genome_spy/datasets/_pbmc.py +87 -0
  139. genome_spy_python-0.8.0/src/genome_spy/datasets/data/pbmc_markers.json.gz +0 -0
  140. genome_spy_python-0.8.0/src/genome_spy/integrations/__init__.py +3 -0
  141. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/__init__.py +10 -0
  142. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_data.py +151 -0
  143. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_dendrogram_chart.py +217 -0
  144. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_dendrogram_data.py +252 -0
  145. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/chart.py +553 -0
  146. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/data.py +551 -0
  147. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/density_data.py +209 -0
  148. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/interactions.py +160 -0
  149. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/scatter_data.py +427 -0
  150. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/selection.py +108 -0
  151. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/summary_builder.py +649 -0
  152. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/summary_chart.py +590 -0
  153. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding/summary_data.py +81 -0
  154. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/clustermap_chart.py +334 -0
  155. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/clustermap_data.py +247 -0
  156. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/colors.py +38 -0
  157. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/correlation_chart.py +162 -0
  158. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/dotplot_builder.py +368 -0
  159. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/dotplot_chart.py +298 -0
  160. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/grouped_builder.py +202 -0
  161. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/grouped_chart.py +570 -0
  162. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/grouped_data.py +549 -0
  163. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/heatmap_chart.py +345 -0
  164. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/matrix_chart.py +460 -0
  165. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/matrixplot_builder.py +301 -0
  166. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/matrixplot_chart.py +148 -0
  167. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/tracksplot_chart.py +277 -0
  168. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_grid_interactions.py +296 -0
  169. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_guards.py +95 -0
  170. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_labels.py +63 -0
  171. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_paga/__init__.py +0 -0
  172. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_paga/chart.py +523 -0
  173. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_paga/data.py +393 -0
  174. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_paga/path_chart.py +471 -0
  175. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_paga/path_data.py +188 -0
  176. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/__init__.py +0 -0
  177. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/highest_expr_chart.py +138 -0
  178. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/highest_expr_data.py +102 -0
  179. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/hvg_chart.py +222 -0
  180. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/scrublet_chart.py +189 -0
  181. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_qc/scrublet_data.py +97 -0
  182. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_ranking/__init__.py +0 -0
  183. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_ranking/chart.py +103 -0
  184. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_ranking/data.py +455 -0
  185. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_style.py +599 -0
  186. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_timeseries/__init__.py +0 -0
  187. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_timeseries/chart.py +353 -0
  188. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_timeseries/data.py +292 -0
  189. genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/pl.py +4512 -0
  190. genome_spy_python-0.8.0/src/genome_spy/py.typed +0 -0
  191. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/__init__.py +31 -1
  192. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/_kwds.py +72 -45
  193. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/_typing.py +3 -0
  194. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/capabilities.json +25 -2
  195. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/channels.py +1115 -282
  196. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/composition.py +464 -21
  197. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/core.py +35222 -24526
  198. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/ergonomics.py +105 -48
  199. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/expressions.py +7 -0
  200. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/genome-spy-schema.json +13754 -5658
  201. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/lazy.py +3 -0
  202. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schema/mixins.py +2500 -780
  203. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/schemapi.py +1 -5
  204. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/static/controls.js +1 -1
  205. genome_spy_python-0.8.0/src/genome_spy/static/genome-spy.js +1131 -0
  206. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/static/inspector.js +4 -4
  207. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/static/widget.js +3 -0
  208. genome_spy_python-0.8.0/tests/__init__.py +0 -0
  209. genome_spy_python-0.8.0/tests/browser/__init__.py +1 -0
  210. genome_spy_python-0.8.0/tests/browser/test_core_upgrade.py +80 -0
  211. genome_spy_python-0.8.0/tests/browser/test_docs_composition.py +165 -0
  212. genome_spy_python-0.8.0/tests/browser/test_docs_linked_expression.py +507 -0
  213. genome_spy_python-0.8.0/tests/browser/test_docs_notebook.py +790 -0
  214. genome_spy_python-0.8.0/tests/browser/test_docs_theme.py +68 -0
  215. genome_spy_python-0.8.0/tests/fixtures/upstream_examples/README.md +15 -0
  216. genome_spy_python-0.8.0/tests/fixtures/upstream_examples/bpreveal-pisa-matrix.json +445 -0
  217. genome_spy_python-0.8.0/tests/fixtures/upstream_examples/clustered-heatmap.json +594 -0
  218. genome_spy_python-0.8.0/tests/fixtures/upstream_examples/upsetr-mutations.json +403 -0
  219. genome_spy_python-0.8.0/tests/integrations/__init__.py +1 -0
  220. genome_spy_python-0.8.0/tests/integrations/scanpy/__init__.py +1 -0
  221. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/__init__.py +1 -0
  222. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/conftest.py +64 -0
  223. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/interactions.py +169 -0
  224. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/references.py +410 -0
  225. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/rendering.py +145 -0
  226. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_dendrogram.py +565 -0
  227. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_dpt.py +448 -0
  228. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_embedding_style.py +778 -0
  229. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_embeddings.py +795 -0
  230. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_grid_interactions.py +851 -0
  231. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_grouped_builders.py +191 -0
  232. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_grouped_expression.py +808 -0
  233. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_heatmaps.py +1452 -0
  234. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_linked_embeddings.py +1085 -0
  235. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_paga.py +764 -0
  236. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_paga_adjacency.py +430 -0
  237. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_paga_path.py +533 -0
  238. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_pca.py +173 -0
  239. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_profiles.py +1163 -0
  240. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_qc.py +584 -0
  241. genome_spy_python-0.8.0/tests/integrations/scanpy/browser/test_ranked.py +413 -0
  242. genome_spy_python-0.8.0/tests/integrations/scanpy/embedding_fixtures.py +288 -0
  243. genome_spy_python-0.8.0/tests/integrations/scanpy/expression_fixtures.py +337 -0
  244. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/README.md +19 -0
  245. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/api.json +505 -0
  246. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/clustermap.json +1387 -0
  247. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/dendrogram.json +2384 -0
  248. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/dotplot.json +1146 -0
  249. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/embedding.json +634 -0
  250. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/grouped.json +1735 -0
  251. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/heatmap.json +1353 -0
  252. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/matrix.json +303 -0
  253. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/matrixplot.json +1622 -0
  254. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/ranked.json +891 -0
  255. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/scatter.json +500 -0
  256. genome_spy_python-0.8.0/tests/integrations/scanpy/fixtures/umap.json +1114 -0
  257. genome_spy_python-0.8.0/tests/integrations/scanpy/grid_fixture_support.py +55 -0
  258. genome_spy_python-0.8.0/tests/integrations/scanpy/helpers.py +120 -0
  259. genome_spy_python-0.8.0/tests/integrations/scanpy/paga_fixtures.py +304 -0
  260. genome_spy_python-0.8.0/tests/integrations/scanpy/profile_fixtures.py +215 -0
  261. genome_spy_python-0.8.0/tests/integrations/scanpy/qc_fixtures.py +82 -0
  262. genome_spy_python-0.8.0/tests/integrations/scanpy/ranked_fixture.py +85 -0
  263. genome_spy_python-0.8.0/tests/integrations/scanpy/test_contract.py +419 -0
  264. genome_spy_python-0.8.0/tests/integrations/scanpy/test_dendrogram.py +502 -0
  265. genome_spy_python-0.8.0/tests/integrations/scanpy/test_dpt.py +404 -0
  266. genome_spy_python-0.8.0/tests/integrations/scanpy/test_embedding_style.py +1063 -0
  267. genome_spy_python-0.8.0/tests/integrations/scanpy/test_embeddings.py +1458 -0
  268. genome_spy_python-0.8.0/tests/integrations/scanpy/test_grid_interactions.py +327 -0
  269. genome_spy_python-0.8.0/tests/integrations/scanpy/test_grouped_builders.py +575 -0
  270. genome_spy_python-0.8.0/tests/integrations/scanpy/test_grouped_expression.py +1016 -0
  271. genome_spy_python-0.8.0/tests/integrations/scanpy/test_heatmaps.py +1167 -0
  272. genome_spy_python-0.8.0/tests/integrations/scanpy/test_linked_embeddings.py +774 -0
  273. genome_spy_python-0.8.0/tests/integrations/scanpy/test_notebooks.py +136 -0
  274. genome_spy_python-0.8.0/tests/integrations/scanpy/test_paga.py +1002 -0
  275. genome_spy_python-0.8.0/tests/integrations/scanpy/test_paga_adjacency.py +327 -0
  276. genome_spy_python-0.8.0/tests/integrations/scanpy/test_paga_path.py +582 -0
  277. genome_spy_python-0.8.0/tests/integrations/scanpy/test_pca.py +464 -0
  278. genome_spy_python-0.8.0/tests/integrations/scanpy/test_profiles.py +707 -0
  279. genome_spy_python-0.8.0/tests/integrations/scanpy/test_qc.py +776 -0
  280. genome_spy_python-0.8.0/tests/integrations/scanpy/test_ranked.py +741 -0
  281. genome_spy_python-0.8.0/tests/test_agent_docs.py +294 -0
  282. genome_spy_python-0.8.0/tests/test_anndata.py +287 -0
  283. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_arrow.py +4 -1
  284. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_chart.py +1 -1
  285. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_datasets.py +1 -0
  286. genome_spy_python-0.8.0/tests/test_distribution.py +81 -0
  287. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_docs_api_reference.py +8 -0
  288. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_docs_gallery.py +46 -22
  289. genome_spy_python-0.8.0/tests/test_docs_linked_expression.py +58 -0
  290. genome_spy_python-0.8.0/tests/test_docs_notebook.py +731 -0
  291. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_docs_tutorial.py +31 -14
  292. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_generated_schema_package.py +46 -0
  293. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_licensing.py +1 -0
  294. genome_spy_python-0.8.0/tests/test_new_compositions.py +159 -0
  295. genome_spy_python-0.8.0/tests/test_pbmc_gallery.py +354 -0
  296. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_pisa_gallery.py +6 -4
  297. genome_spy_python-0.8.0/tests/test_scanpy_imports.py +56 -0
  298. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_schema_codegen.py +48 -4
  299. genome_spy_python-0.8.0/tests/test_skill_install.py +130 -0
  300. genome_spy_python-0.8.0/tests/test_upstream_surround_gallery.py +161 -0
  301. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_workflow_notebooks.py +30 -0
  302. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/widget.test.mjs +17 -2
  303. genome_spy_python-0.8.0/tools/agent_docs.py +279 -0
  304. genome_spy_python-0.8.0/tools/agent_markdown.py +277 -0
  305. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/check_notebook_rendering.py +231 -3
  306. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/docs_gallery.py +8 -0
  307. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/generate_api_docs.py +12 -0
  308. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/generate_schema_wrapper.py +24 -4
  309. genome_spy_python-0.8.0/tools/prepare_pbmc_gallery_data.py +244 -0
  310. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/schemapi/codegen.py +68 -59
  311. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/uv.lock +1495 -192
  312. genome_spy_python-0.6.0/.agents/skills/proper-code-review/SKILL.md +0 -165
  313. genome_spy_python-0.6.0/.claude/skills/commit/SKILL.md +0 -105
  314. genome_spy_python-0.6.0/AGENTS.md +0 -153
  315. genome_spy_python-0.6.0/src/genome_spy/static/genome-spy.js +0 -1005
  316. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.agents/skills/proper-code-review/references/correctness.md +0 -0
  317. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.agents/skills/proper-code-review/references/design.md +0 -0
  318. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.agents/skills/proper-code-review/references/performance.md +0 -0
  319. {genome_spy_python-0.6.0/.agents → genome_spy_python-0.8.0/.claude}/skills/commit/SKILL.md +0 -0
  320. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.claude/skills/proper-code-review/SKILL.md +0 -0
  321. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.claude/skills/proper-code-review/references/correctness.md +0 -0
  322. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.claude/skills/proper-code-review/references/design.md +0 -0
  323. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.claude/skills/proper-code-review/references/performance.md +0 -0
  324. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.gitattributes +0 -0
  325. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/.python-version +0 -0
  326. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/CLAUDE.md +0 -0
  327. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSE +0 -0
  328. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/ALTAIR-BSD-3-Clause.txt +0 -0
  329. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/CC-BY-4.0.txt +0 -0
  330. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/CC-BY-NC-SA-4.0.txt +0 -0
  331. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/CC0-1.0.txt +0 -0
  332. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/DATA-SOURCE-REPOSITORIES-MIT.txt +0 -0
  333. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/GENOMESPY-MIT.txt +0 -0
  334. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/LATO-OFL-1.1.txt +0 -0
  335. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/VEGA-BSD-3-Clause.txt +0 -0
  336. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/LICENSES/VEGA-LITE-BSD-3-Clause.txt +0 -0
  337. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/README.md +0 -0
  338. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/airway_metadata.csv +0 -0
  339. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/airway_scaledcounts.csv +0 -0
  340. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/hapmap_gwas.csv +0 -0
  341. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/oncoprint_dataset3.json +0 -0
  342. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/data/pik3ca_mutations.json +0 -0
  343. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/external-links.js +0 -0
  344. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/airway_ma_plot.png +0 -0
  345. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/airway_volcano_plot.png +0 -0
  346. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/ascat_copy_number.png +0 -0
  347. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/ascat_fitting.png +0 -0
  348. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/bam_read_alignments.png +0 -0
  349. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/bam_read_pileup.png +0 -0
  350. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/bigbed_ccre_track.png +0 -0
  351. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/brush_linked_genome_tracks.png +0 -0
  352. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/clinvar_variants.png +0 -0
  353. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/combined_laml_oncoplot.png +0 -0
  354. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/composing_genome_browser.png +0 -0
  355. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/copy_number.png +0 -0
  356. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/coverage_pileup.png +0 -0
  357. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/cytobands.png +0 -0
  358. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/diverging_bars.png +0 -0
  359. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/dynseq_adaptive_bqtl.png +0 -0
  360. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/dynseq_bqtl.png +0 -0
  361. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/genome_tracks.png +0 -0
  362. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/geometric_zoom.png +0 -0
  363. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/gff3_gene_annotations.png +0 -0
  364. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/hcc1954_sv_cnv.png +0 -0
  365. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/heatmap_with_text.png +0 -0
  366. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/independent_scales.png +0 -0
  367. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/indexed_fasta_sequence.png +0 -0
  368. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/layered_lollipop.png +0 -0
  369. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/link_mark.png +0 -0
  370. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/luad_oncoprint.png +0 -0
  371. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/manhattan_plot.png +0 -0
  372. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/multiple_sequence_alignment.png +0 -0
  373. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/needle_plot.png +0 -0
  374. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/oncoprint.png +0 -0
  375. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/p53_sequence_comparison.png +0 -0
  376. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/penguin_brush.png +0 -0
  377. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/pik3ca_tcga_brca_lollipop.png +0 -0
  378. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/pisa_interaction_matrix.png +0 -0
  379. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/pisa_squid.png +0 -0
  380. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/point_mark.png +0 -0
  381. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/point_styles.png +0 -0
  382. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/rainfall_plot.png +0 -0
  383. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/ranged_rule.png +0 -0
  384. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/rect_heatmap.png +0 -0
  385. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/refseq_scored_genes.png +0 -0
  386. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/rnf7_direct_rna.png +0 -0
  387. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/sashimi_plot.png +0 -0
  388. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/scrollable_viewport.png +0 -0
  389. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/sequence_logo.png +0 -0
  390. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/six_frame_translation.png +0 -0
  391. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/stacked_bar.png +0 -0
  392. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/stacked_genome_browser.png +0 -0
  393. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/tcga_ov_gistic.png +0 -0
  394. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/tsne.png +0 -0
  395. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/upset_mutations.png +0 -0
  396. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/vertical_concat.png +0 -0
  397. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/gallery/volcano_plot.png +0 -0
  398. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/readme-manhattan.webp +0 -0
  399. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/readme-sequence-logo.webp +0 -0
  400. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/showcase.js +0 -0
  401. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/snaketie.svg +0 -0
  402. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/workflows.css +0 -0
  403. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_static/workflows.js +0 -0
  404. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_templates/autosummary/class.rst +0 -0
  405. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_templates/autosummary/class_own_members.rst +0 -0
  406. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_templates/base.html +0 -0
  407. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/_templates/components/view-this-page.html +0 -0
  408. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/about.md +0 -0
  409. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/airway_ma_plot.md +0 -0
  410. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/airway_ma_plot.py +0 -0
  411. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/airway_volcano_plot.md +0 -0
  412. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/airway_volcano_plot.py +0 -0
  413. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/ascat_copy_number.md +0 -0
  414. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/ascat_copy_number.py +0 -0
  415. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/ascat_fitting.md +0 -0
  416. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/bam_read_alignments.md +0 -0
  417. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/bam_read_pileup.md +0 -0
  418. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/brush_linked_genome_tracks.md +0 -0
  419. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/brush_linked_genome_tracks.py +0 -0
  420. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/clinvar_variants.md +0 -0
  421. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/combined_laml_oncoplot.md +0 -0
  422. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/composing_genome_browser.md +0 -0
  423. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/copy_number.py +0 -0
  424. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/coverage_pileup.md +0 -0
  425. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/coverage_pileup.py +0 -0
  426. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/cytobands.md +0 -0
  427. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/cytobands.py +0 -0
  428. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/diverging_bars.md +0 -0
  429. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/diverging_bars.py +0 -0
  430. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/dynseq_adaptive_bqtl.md +0 -0
  431. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/dynseq_bqtl.md +0 -0
  432. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/genome_tracks.py +0 -0
  433. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/geometric_zoom.md +0 -0
  434. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/geometric_zoom.py +0 -0
  435. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/gff3_gene_annotations.md +0 -0
  436. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/gff3_gene_annotations.py +0 -0
  437. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/hcc1954_sv_cnv.md +0 -0
  438. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/heatmap_with_text.md +0 -0
  439. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/heatmap_with_text.py +0 -0
  440. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/independent_scales.py +0 -0
  441. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/layered_lollipop.md +0 -0
  442. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/layered_lollipop.py +0 -0
  443. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/link_mark.py +0 -0
  444. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/luad_oncoprint.md +0 -0
  445. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/manhattan_plot.md +0 -0
  446. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/manhattan_plot.py +0 -0
  447. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/multiple_sequence_alignment.md +0 -0
  448. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/needle_plot.py +0 -0
  449. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/oncoprint.md +0 -0
  450. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/p53_sequence_comparison.md +0 -0
  451. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/penguin_brush.md +0 -0
  452. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/penguin_brush.py +0 -0
  453. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pik3ca_tcga_brca_lollipop.md +0 -0
  454. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/pisa_squid.md +0 -0
  455. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/point_mark.py +0 -0
  456. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/point_styles.md +0 -0
  457. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/point_styles.py +0 -0
  458. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/rainfall_plot.md +0 -0
  459. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/rainfall_plot.py +0 -0
  460. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/ranged_rule.py +0 -0
  461. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/rect_heatmap.py +0 -0
  462. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/refseq_scored_genes.md +0 -0
  463. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/refseq_scored_genes.py +0 -0
  464. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/rnf7_direct_rna.md +0 -0
  465. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/sashimi_plot.md +0 -0
  466. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/sashimi_plot.py +0 -0
  467. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/scrollable_viewport.py +0 -0
  468. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/sequence_logo.py +0 -0
  469. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/six_frame_translation.md +0 -0
  470. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/stacked_bar.md +0 -0
  471. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/stacked_bar.py +0 -0
  472. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/stacked_genome_browser.py +0 -0
  473. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/tcga_ov_gistic.md +0 -0
  474. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/tcga_ov_gistic.py +0 -0
  475. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/tsne.md +0 -0
  476. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/tsne.py +0 -0
  477. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/vertical_concat.py +0 -0
  478. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/volcano_plot.md +0 -0
  479. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/examples/volcano_plot.py +0 -0
  480. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/getting-started.md +0 -0
  481. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/integration/component.py +0 -0
  482. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/integration/index.html +0 -0
  483. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/integration/notebook.ipynb +0 -0
  484. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/integration/server.py +0 -0
  485. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/annotations.py +0 -0
  486. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/charts_and_marks.py +0 -0
  487. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/configuration.py +0 -0
  488. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/data_inputs.py +0 -0
  489. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/display_controls.py +0 -0
  490. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/genome_browser_layouts.py +0 -0
  491. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/genomic_coordinates.py +0 -0
  492. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/genomic_data.py +0 -0
  493. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/getting_started.py +0 -0
  494. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/importing_specifications.py +0 -0
  495. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/notebooks.py +0 -0
  496. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/scales_and_guides.py +0 -0
  497. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/serialization.py +0 -0
  498. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/tutorials/transforms.py +0 -0
  499. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/annotations.md +0 -0
  500. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/charts.md +0 -0
  501. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/configuration.md +0 -0
  502. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/connect-python.md +0 -0
  503. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/display-controls.md +0 -0
  504. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/genome-browser-layouts.md +0 -0
  505. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/genomic-axes.md +0 -0
  506. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/genomic-data.md +0 -0
  507. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/importing-specifications.md +0 -0
  508. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/notebooks.md +0 -0
  509. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/scales-axes-legends.md +0 -0
  510. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/serialization.md +0 -0
  511. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/using-charts.md +0 -0
  512. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/workflows/annotate-intervals.md +0 -0
  513. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/workflows/edit-sequence.md +0 -0
  514. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/workflows/index.md +0 -0
  515. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/workflows/pick-genes.md +0 -0
  516. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/docs/user-guide/workflows/select-genes.md +0 -0
  517. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/annotate_genomic_intervals.ipynb +0 -0
  518. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/brush_linked_genome_tracks.ipynb +0 -0
  519. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/edit_sequence.ipynb +0 -0
  520. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/embed_api.ipynb +0 -0
  521. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/pick_genes.ipynb +0 -0
  522. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/notebooks/select_genes.ipynb +0 -0
  523. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_conditions.py +0 -0
  524. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_embed.py +0 -0
  525. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_expressions.py +0 -0
  526. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_parameters.py +0 -0
  527. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_render.py +0 -0
  528. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_utils.py +0 -0
  529. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/_widget.py +0 -0
  530. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/data.py +0 -0
  531. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/data_transformers.py +0 -0
  532. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_airway.py +0 -0
  533. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_annotations.py +0 -0
  534. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_direct_rna.py +0 -0
  535. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_gistic.py +0 -0
  536. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_grammar.py +0 -0
  537. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_hapmap.py +0 -0
  538. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_mutation.py +0 -0
  539. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/_oncoprint.py +0 -0
  540. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/airway_metadata.csv +0 -0
  541. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/airway_review.json.gz +0 -0
  542. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/airway_scaledcounts.csv +0 -0
  543. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/brca.maf.gz +0 -0
  544. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/hapmap_gwas.csv +0 -0
  545. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/mutation_impact_reference.json +0 -0
  546. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/oncoprint_dataset3.json +0 -0
  547. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/p53_sequence_comparison_aligned.fasta.gz +0 -0
  548. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/pik3ca_mutations.json +0 -0
  549. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/pik3ca_tcga_brca_lollipop.json +0 -0
  550. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/refseq_gene_bodies.csv.gz +0 -0
  551. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/rnf7_direct_rna.json.gz +0 -0
  552. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tal1_alphagenome_reference.json.gz +0 -0
  553. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga.tsv +0 -0
  554. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga_laml.maf.gz +0 -0
  555. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga_laml_annot.tsv +0 -0
  556. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga_laml_combined_oncoplot.json.gz +0 -0
  557. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga_ov_gistic_lesions.tsv.gz +0 -0
  558. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/datasets/data/tcga_ov_gistic_scores.tsv.gz +0 -0
  559. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/embed.py +0 -0
  560. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/helpers.py +0 -0
  561. {genome_spy_python-0.6.0/tests → genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_embedding}/__init__.py +0 -0
  562. /genome_spy_python-0.6.0/src/genome_spy/py.typed → /genome_spy_python-0.8.0/src/genome_spy/integrations/scanpy/_expression/__init__.py +0 -0
  563. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/jupyter.py +0 -0
  564. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/src/genome_spy/static/embed-bridge.js +0 -0
  565. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/browser/test_docs_workflows.py +0 -0
  566. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/browser/test_embed_api.py +0 -0
  567. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/browser/test_offline_rendering.py +0 -0
  568. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/browser/test_python_web_example.py +0 -0
  569. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/embed-bridge.test.mjs +0 -0
  570. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_combined_gallery_data.py +0 -0
  571. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_conditions.py +0 -0
  572. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_data_transformers.py +0 -0
  573. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_embed.py +0 -0
  574. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_embed_notebook.py +0 -0
  575. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_expressions.py +0 -0
  576. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_generated_transform_methods.py +0 -0
  577. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_javascript_assets.py +0 -0
  578. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_python_connection_example.py +0 -0
  579. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_render_thumbnails.py +0 -0
  580. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_rnf7_direct_rna_example.py +0 -0
  581. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tests/test_widget.py +0 -0
  582. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/docs_workflows.py +0 -0
  583. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/prepare_airway_review.py +0 -0
  584. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/prepare_combined_gallery_data.py +0 -0
  585. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/prepare_refseq_gene_annotations.py +0 -0
  586. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/render_thumbnails.py +0 -0
  587. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/schemapi/__init__.py +0 -0
  588. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/schemapi/expression_codegen.py +0 -0
  589. {genome_spy_python-0.6.0 → genome_spy_python-0.8.0}/tools/vendor_javascript.py +0 -0
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: commit
3
+ description: Commit repository changes in small thematic chunks using conventional commits and concise changelog staging.
4
+ ---
5
+
6
+ # Commit workflow
7
+
8
+ Prefer small, independently understandable commits. Keep unrelated user changes
9
+ unstaged. Do not amend, rewrite history, revert, force-push, or add co-author
10
+ trailers unless explicitly requested.
11
+
12
+ ## Inspect and commit
13
+
14
+ 1. Start with `git status --short` and `git diff --stat`.
15
+ 2. Group changes into thematic slices. Split separate features, fixes, refactors,
16
+ tooling/configuration, documentation, and unrelated test work when separable;
17
+ do not split mechanically by file.
18
+ 3. Keep implementation with its direct tests, API/schema changes with required
19
+ supporting code, and generated files with their source change.
20
+ 4. Read targeted diffs only when needed, including when grouping is unclear:
21
+ `git diff -- <files>`. Minimize token use; do not read the full diff or re-review
22
+ code by default.
23
+ 5. Stage one slice, check `git diff --cached --stat`, and commit with a conventional
24
+ message. Repeat for remaining slices.
25
+ 6. Finish with `git status --short`, update changelog staging once if needed, and
26
+ report commit hashes and remaining uncommitted files.
27
+
28
+ ## Commit messages
29
+
30
+ Use `<type>(<scope>): <description>`. Common types: `feat`, `fix`, `refactor`,
31
+ `perf`, `test`, `docs`, `chore`, `build`, and `ci`.
32
+
33
+ ```text
34
+ feat(parser): add strand-aware bigwig loading
35
+ fix(cache): invalidate stale entries
36
+ refactor(pipeline): simplify track dispatch
37
+ ```
38
+
39
+ ## Changelog staging
40
+
41
+ `CHANGELOG_STAGING.md` holds future release notes. Update it once per commit
42
+ session only for release-relevant changes:
43
+
44
+ - Read only the context needed.
45
+ - Add concise bullets under `Added`, `Changed`, `Fixed`, `Removed`, or `Performance`.
46
+ - Prefer one resulting-change bullet over one per commit; avoid duplicates.
47
+ - Omit routine refactors, formatting, test-only work, and internal details unless
48
+ release-relevant.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: contribute-genomespy
3
+ description: Use whenever work in genome-spy-python requires creating or updating an upstream GenomeSpy PR, including feature, fix, documentation and workflow changes.
4
+ ---
5
+
6
+ # Contribute to GenomeSpy
7
+
8
+ 1. Keep Python-specific work here. Put reusable engine behavior upstream when
9
+ the existing native API cannot cover it cleanly.
10
+ 2. Locate the intended GenomeSpy checkout and verify its Git remotes and branch;
11
+ do not assume a temporary clone is current. Read its `AGENTS.md`.
12
+ 3. Use that checkout's `.agents/skills/plan-genomespy-change/SKILL.md` before
13
+ implementation and before opening or updating any upstream PR. If code is
14
+ already written, run its architecture-fit check before PR preparation.
15
+ Use `.agents/skills/prepare-genomespy-change/SKILL.md` for commits and PR
16
+ preparation. Follow those upstream workflows rather than copying them here.
17
+ If either skill is absent, locate the current instructions before proceeding.
18
+ 4. Keep upstream edits separate from Python integration work and coordinate file
19
+ ownership with active chats when authorized. Preserve the agreed release/source
20
+ dependency; do not silently ship a local unreleased Core build.
21
+ 5. Report the upstream PR/commit, verification and remaining integration dependency.
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: proper-code-review
3
+ description: Review code changes for correctness, simplicity, readability, maintainability, architectural fit, and meaningful system-level performance. Use when asked to review a diff, implementation, branch, or recent code changes.
4
+ ---
5
+
6
+ # Code review
7
+
8
+ Review as a senior engineer. Prioritize correctness and low lifecycle complexity:
9
+ simple, readable, maintainable code that fits the repository and performs well for
10
+ realistic workloads. Prefer a few high-confidence findings over exhaustive
11
+ commentary; do not manufacture findings.
12
+
13
+ Added complexity must provide a concrete benefit: correctness, meaningful reuse,
14
+ change locality, real variation, necessary scalability, or material performance.
15
+ Prefer local reasoning and localized changes. Reuse suitable repository concepts,
16
+ avoid duplicated knowledge and parallel mechanisms, and reject speculative
17
+ abstraction/extensibility. Judge performance across the system, not just locally.
18
+
19
+ ## Review method
20
+
21
+ 1. **Understand the change.** Read the diff first. Identify its problem, behavior
22
+ changes, affected interfaces, invariants, state, and architectural concepts.
23
+ Read only enough surrounding code to answer concrete questions, not the whole
24
+ repository. When relevant, inspect callers for compatibility, tests for intended
25
+ behavior/invariants, existing mechanisms before proposing new ones, analogous
26
+ implementations for duplication/fit, and broader execution paths for performance.
27
+ 2. **Verify hypotheses.** Check concerns against repository evidence when possible.
28
+ Locate duplicated representations, inspect callers before claiming breakage,
29
+ search for existing abstractions, and establish performance significance before
30
+ criticizing or recommending optimization. Do not present assumptions as facts.
31
+ 3. **Review correctness.** Look for concrete behavioral bugs/regressions, broken
32
+ invariants, invalid assumptions, relevant edge cases, unsafe mutations/state
33
+ transitions, error/resource lifecycle issues, concurrency problems, and
34
+ unintended compatibility changes. Passing tests are evidence, not proof.
35
+ Read [correctness](references/correctness.md) for deeper analysis.
36
+ 4. **Review design.** Consider simplicity (KISS), readability, maintainability,
37
+ cohesion, coupling, abstraction, change locality, blast radius, and fit together.
38
+ Check whether a simpler solution supports local understanding/change, whether
39
+ synchronized edits duplicate knowledge, whether machinery is unnecessary,
40
+ whether abstractions share real semantics, and whether scope is proportional.
41
+ Apply YAGNI: avoid cleverness or future machinery without concrete benefit.
42
+ Read [design](references/design.md) for deeper analysis.
43
+ 5. **Review performance.** Check algorithmic complexity, repeated expensive work,
44
+ I/O, memory/copying, serialization/data movement, CPU/GPU synchronization, and
45
+ realistic scaling. Judge end-to-end impact; reject meaningful complexity for
46
+ negligible local gains. Read [performance](references/performance.md) when relevant.
47
+ 6. **Validate findings.** Each problem must be concrete, consequential, supported
48
+ by evidence, and paired with a proportionate fix that reduces total complexity.
49
+ Remove speculative, cosmetic, generic, and low-value comments. No finding is
50
+ better than a weak finding.
51
+
52
+ ## Output
53
+
54
+ Order findings by practical impact. For each, use:
55
+
56
+ ### `[Severity] Short problem statement`
57
+
58
+ - **Location:** Smallest useful code region.
59
+ - **Problem:** What is wrong.
60
+ - **Impact:** Why it matters here.
61
+ - **Recommendation:** Smallest reasonable fix.
62
+
63
+ Severity:
64
+
65
+ - **Critical:** Correctness, data loss, security, or severe failure.
66
+ - **Important:** Substantial behavioral, architectural, maintainability,
67
+ performance, or scalability issue.
68
+ - **Minor:** Worthwhile simplification or readability improvement.
69
+
70
+ Combine findings with the same root cause and state uncertainty explicitly.
71
+ Normally omit stylistic nits. Do not add generic best-practice advice, speculative
72
+ future concerns, praise for unaffected code, or alternative architectures merely
73
+ because they are possible. If none remain, say no significant issues were found.
@@ -4,8 +4,22 @@ on:
4
4
  push:
5
5
  branches: [main]
6
6
  pull_request:
7
+ workflow_dispatch:
8
+ inputs:
9
+ full_scanpy:
10
+ description: Run all Scanpy references, browsers and workflows
11
+ type: boolean
12
+ default: false
7
13
  # Reused by the release workflow as a pre-publish gate.
8
14
  workflow_call:
15
+ inputs:
16
+ full_scanpy:
17
+ type: boolean
18
+ default: false
19
+
20
+ concurrency:
21
+ group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
22
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
9
23
 
10
24
  jobs:
11
25
  test:
@@ -34,7 +48,7 @@ jobs:
34
48
  run: uv run mypy src/
35
49
  - name: Run package tests
36
50
  run: >-
37
- uv run pytest tests/ -x
51
+ uv run pytest tests/ -x --ignore=tests/integrations/scanpy
38
52
  -m "not docs and not codegen"
39
53
  --durations=10
40
54
  - run: node --test tests/*.test.mjs
@@ -71,6 +85,94 @@ jobs:
71
85
  --with "$GITHUB_WORKSPACE"/dist/*.whl
72
86
  python -c "from importlib.resources import files; import genome_spy as gs; package = files('genome_spy'); assert package.joinpath('schema/genome-spy-schema.json').is_file(); assert package.joinpath('schema/capabilities.json').is_file(); assert package.joinpath('static/widget.js').is_file(); assert package.joinpath('static/genome-spy.js').is_file(); assert package.joinpath('static/controls.js').is_file(); assert package.joinpath('static/inspector.js').is_file(); chart = gs.Chart([{'x': 1}]).mark_point().encode(x='x:Q'); spec = chart.to_dict(); assert spec['mark'] == 'point'; assert spec['encoding']['x']['field'] == 'x'; assert spec[chr(36) + 'schema'].endswith('/schema.json')"
73
87
 
88
+ scanpy:
89
+ runs-on: ubuntu-latest
90
+ timeout-minutes: 75
91
+ strategy:
92
+ fail-fast: false
93
+ matrix:
94
+ python: ${{ fromJSON((github.ref == 'refs/heads/main' || inputs.full_scanpy) && '["3.11", "3.12", "3.13"]' || '["3.11"]') }}
95
+ env:
96
+ MPLBACKEND: Agg
97
+ steps:
98
+ - uses: actions/checkout@v7
99
+ - uses: astral-sh/setup-uv@v9.0.0
100
+ with:
101
+ enable-cache: true
102
+ python-version: ${{ matrix.python }}
103
+ - run: uv sync --locked --dev --extra scanpy --group scanpy-test
104
+ - name: Fast Scanpy checks
105
+ if: github.ref != 'refs/heads/main' && !inputs.full_scanpy
106
+ run: >-
107
+ uv run --no-sync pytest tests/integrations/scanpy
108
+ --ignore=tests/integrations/scanpy/browser
109
+ -m "not reference and not workflow" -q --durations=10
110
+ - name: Full Scanpy checks
111
+ if: github.ref == 'refs/heads/main' || inputs.full_scanpy
112
+ run: >-
113
+ uv run --no-sync pytest tests/integrations/scanpy
114
+ --ignore=tests/integrations/scanpy/browser -q --durations=10
115
+ # The renderer is JavaScript; repeat it once, rather than for each Python.
116
+ - if: matrix.python == '3.11'
117
+ run: uv run --no-sync python -m playwright install --with-deps chromium
118
+ - name: Browser smoke checks
119
+ if: matrix.python == '3.11' && github.ref != 'refs/heads/main' && !inputs.full_scanpy
120
+ run: >-
121
+ uv run --no-sync pytest tests/integrations/scanpy/browser -m smoke -q
122
+ --basetemp="${{ runner.temp }}/scanpy-browser"
123
+ - name: Full browser checks
124
+ if: matrix.python == '3.11' && (github.ref == 'refs/heads/main' || inputs.full_scanpy)
125
+ run: >-
126
+ uv run --no-sync pytest tests/integrations/scanpy/browser -q
127
+ --basetemp="${{ runner.temp }}/scanpy-browser"
128
+ - name: Render the workflow notebooks in JupyterLab
129
+ if: matrix.python == '3.11' && (github.ref == 'refs/heads/main' || inputs.full_scanpy)
130
+ run: |
131
+ uv run --no-sync python tools/check_notebook_rendering.py integrations/scanpy/notebooks/scanpy_umap.ipynb --screenshot "${{ runner.temp }}/scanpy-browser/umap-notebook.png"
132
+ uv run --no-sync python tools/check_notebook_rendering.py integrations/scanpy/notebooks/scanpy_expression.ipynb --screenshot "${{ runner.temp }}/scanpy-browser/expression-notebook.png"
133
+ - uses: actions/upload-artifact@v7
134
+ if: always() && matrix.python == '3.11'
135
+ with:
136
+ name: scanpy-browser
137
+ path: ${{ runner.temp }}/scanpy-browser
138
+ if-no-files-found: ignore
139
+
140
+ scanpy-compatibility:
141
+ runs-on: ubuntu-latest
142
+ timeout-minutes: 30
143
+ env:
144
+ MPLBACKEND: Agg
145
+ steps:
146
+ - uses: actions/checkout@v7
147
+ - uses: astral-sh/setup-uv@v9.0.0
148
+ with:
149
+ python-version: "3.12"
150
+ - name: Install current Scanpy separately from the reference environment
151
+ run: |
152
+ uv venv --python 3.12 "$RUNNER_TEMP/scanpy-compat"
153
+ uv pip install --python "$RUNNER_TEMP/scanpy-compat/bin/python" \
154
+ -e '.[scanpy]' 'scanpy==1.12.4' pytest pillow playwright pyarrow
155
+ - name: Fast compatibility checks
156
+ if: github.ref != 'refs/heads/main' && !inputs.full_scanpy
157
+ run: >-
158
+ "$RUNNER_TEMP/scanpy-compat/bin/python" -m pytest
159
+ tests/integrations/scanpy --ignore=tests/integrations/scanpy/browser
160
+ -m "not reference and not workflow" -q --durations=10
161
+ - name: Full compatibility checks
162
+ if: github.ref == 'refs/heads/main' || inputs.full_scanpy
163
+ run: >-
164
+ "$RUNNER_TEMP/scanpy-compat/bin/python" -m pytest
165
+ tests/integrations/scanpy --ignore=tests/integrations/scanpy/browser -q
166
+ - if: github.ref == 'refs/heads/main' || inputs.full_scanpy
167
+ run: '"$RUNNER_TEMP/scanpy-compat/bin/python" -m playwright install --with-deps chromium'
168
+ - name: Check native interactions with current Scanpy
169
+ if: github.ref == 'refs/heads/main' || inputs.full_scanpy
170
+ run: >-
171
+ "$RUNNER_TEMP/scanpy-compat/bin/python" -m pytest
172
+ tests/integrations/scanpy/browser/test_grid_interactions.py::TestGridInteractions
173
+ tests/integrations/scanpy/browser/test_linked_embeddings.py
174
+ -q --basetemp="${{ runner.temp }}/scanpy-compat-browser"
175
+
74
176
  codegen:
75
177
  runs-on: ubuntu-latest
76
178
  steps:
@@ -134,6 +236,16 @@ jobs:
134
236
  "$RUNNER_TEMP/notebook-env/bin/python" tools/check_notebook_rendering.py \
135
237
  notebooks/edit_sequence.ipynb --workflow sequence \
136
238
  --screenshot "$RUNNER_TEMP/edit-sequence.png"
239
+ - name: Verify the agent guide notebook roundtrip
240
+ run: |
241
+ "$RUNNER_TEMP/notebook-env/bin/python" tools/check_notebook_rendering.py \
242
+ docs/agents/embed-api.md --workflow agent-embed \
243
+ --screenshot "$RUNNER_TEMP/agent-embed.png"
244
+ - name: Exercise Python-linked chart widgets
245
+ run: |
246
+ "$RUNNER_TEMP/notebook-env/bin/python" tools/check_notebook_rendering.py \
247
+ notebooks/penguin_python_roundtrip.ipynb --workflow python-rows \
248
+ --screenshot "$RUNNER_TEMP/python-rows.png"
137
249
  - uses: actions/upload-artifact@v7
138
250
  if: always()
139
251
  with:
@@ -31,6 +31,8 @@ jobs:
31
31
  # Example modules that back the gallery need the example runtime
32
32
  # (pandas/numpy) plus the docs toolchain.
33
33
  - run: uv sync --locked --group docs --group dev
34
+ - name: Prepare Scanpy guide data
35
+ run: uv run integrations/scanpy/prepare_guide_data.py
34
36
  # Render real chart screenshots for the gallery cards.
35
37
  - name: Render gallery thumbnails
36
38
  run: |
@@ -23,6 +23,8 @@ concurrency:
23
23
  jobs:
24
24
  check:
25
25
  uses: ./.github/workflows/ci.yml
26
+ with:
27
+ full_scanpy: true
26
28
 
27
29
  build:
28
30
  needs: check
@@ -54,6 +54,11 @@ coverage.xml
54
54
  .pytest_cache/
55
55
  cover/
56
56
 
57
+ # Generated test images stay local or in temporary CI artifacts.
58
+ /tests/**/*.png
59
+ # Scanpy downloads this count dataset on first use; it is never vendored.
60
+ **/data/pbmc3k_raw.h5ad
61
+
57
62
  # Translations
58
63
  *.mo
59
64
  *.pot
@@ -251,3 +256,6 @@ scripts/_fetch_reference.py
251
256
 
252
257
  # Local recording demos and working files
253
258
  /demos/
259
+
260
+ # Generated Scanpy benchmark observations are not reference fixtures.
261
+ tests/integrations/scanpy/fixtures/*performance*.json
@@ -1,6 +1,13 @@
1
1
  repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: no-test-artifacts
5
+ name: keep generated test artifacts out of Git
6
+ language: fail
7
+ entry: Generated test media and benchmark reports belong in temporary directories, not Git.
8
+ files: '(?i)^tests/.*(?:\.(?:png|jpe?g|gif|webp|svg|pdf|mp4|webm|mov|avi|bmp|tiff?|avif|html|h5ad|h5|parquet|arrow|feather|npz|npy|pkl|pickle)|performance[^/]*\.json)$'
2
9
  - repo: https://github.com/astral-sh/ruff-pre-commit
3
- rev: v0.12.0
10
+ rev: v0.15.19
4
11
  hooks:
5
12
  - id: ruff
6
13
  args: [--fix]
@@ -0,0 +1,101 @@
1
+ # Repository instructions
2
+
3
+ `genome-spy-python` wraps GenomeSpy in an idiomatic Python API, as Altair wraps
4
+ Vega-Lite. Users author compatible specs, serialize JSON, and render in notebooks.
5
+ Treat it as a library with a clean public API. Build the reusable Core grammar
6
+ before app-specific concepts. Notebook rendering is first-class; prefer `anywidget`.
7
+
8
+ ## Layout
9
+
10
+ | Path | Purpose |
11
+ | --- | --- |
12
+ | `src/genome_spy/` | Installable library |
13
+ | `src/genome_spy/integrations/<library>/` | Optional integration implementations |
14
+ | `tests/` | pytest suite |
15
+ | `integrations/` | Tracked integration plans and per-library workflow notebooks |
16
+ | `scripts/` | Helpers run via `uv run` |
17
+ | `plans/` | Plans, context, and implementation notes |
18
+ | `material/` | Local reference documents; not committed |
19
+ | `tmp/` | External reference code/repos; not committed |
20
+
21
+ ## Working rules
22
+
23
+ - Think before coding: state assumptions and tradeoffs; push back when warranted.
24
+ - Apply YAGNI and the [Ponytail rules](https://github.com/DietrichGebert/ponytail/blob/main/.agents/rules/ponytail.md):
25
+ complete the task with the least new code. Avoid unrequested features,
26
+ wrappers, conversions, options, and speculative abstractions. If 200 lines
27
+ could be 50, rewrite them.
28
+ - Prefer existing repository code, then standard-library/platform features,
29
+ then installed dependencies, then minimal new code. Do not add a dependency
30
+ for a few lines of functionality.
31
+ - Before editing, trace affected callers, tests, fixtures, configuration, and
32
+ exports. Fix shared root causes once and complete every affected part.
33
+ - Make surgical changes: match existing style, remove imports/variables orphaned
34
+ by your edits, preserve existing layers and native value forms, and leave
35
+ unrelated code alone. Keep validation and error handling when moving code.
36
+ - Prefer equally small solutions that handle edge cases. Preserve security,
37
+ accessibility, trust-boundary checks, and required hardware calibration.
38
+ - Keep comments to one-line explanations of why. Document deliberate shortcuts
39
+ as `shortcut: <the limit>, <when to upgrade>`.
40
+ - Set verifiable goals and give a brief plan for multi-step work.
41
+ - When work requires an upstream GenomeSpy PR, use
42
+ [contribute-genomespy](.agents/skills/contribute-genomespy/SKILL.md).
43
+ - Keep core logic pure Python; isolate I/O and integration at the edges.
44
+ - Follow the linked [language, docstring, formatting, and gallery standards](docs/contributing/standards.md).
45
+ Read the relevant sections before Python or gallery edits; they are requirements.
46
+
47
+ ## Testing and handoff
48
+
49
+ Use pytest. Add or update tests for behavior changes, with fixed seeds for random
50
+ behavior. Keep tests small and focused on one behavior. Apply the "Suspicious
51
+ Check": tighten any test that could pass for the wrong reason.
52
+
53
+ Never commit or push generated test artifacts, including reference images,
54
+ screenshots, overlays, recordings and chart exports. Generate them in temporary
55
+ directories or ignored local caches; track test source, generators and deliberate
56
+ text fixtures. Keep committed notebooks free of execution outputs and widget
57
+ state. Check outgoing commit history before pushing: deleting artifacts from the
58
+ current tree does not remove old blobs.
59
+
60
+ Use `uv` for environments and dependencies. Before handoff, run targeted tests for
61
+ changed behavior and lint. Format before finalizing non-trivial edits; type-check
62
+ when public Python code changes. End the handoff with any skipped or unvalidated
63
+ work and material risks.
64
+ Ruff is the formatting/lint authority; fix issues rather than suppressing them by
65
+ default.
66
+
67
+ | Task | Command |
68
+ | --- | --- |
69
+ | Sync environment | `uv sync --dev` |
70
+ | Run tests | `uv run pytest tests/ -x` |
71
+ | Lint | `uv run ruff check .` |
72
+ | Format | `uv run ruff format .` |
73
+ | Type-check | `uv run mypy src/` |
74
+ | Install hooks | `uv run pre-commit install` |
75
+
76
+ Make small, thematic commits. Use conventional commits:
77
+ `<type>(<scope>): <description>` when a scope helps. Do not rewrite history unless
78
+ explicitly asked.
79
+
80
+ ## Plans and references
81
+
82
+ | Document | Read when |
83
+ | --- | --- |
84
+ | `integrations/README.md` | Integration layout, plan lifecycle, and clearance rules |
85
+ | `integrations/<library>/STATUS.md` | Current implementation, next slice, blockers, and retained evidence |
86
+ | `integrations/<library>/PLAN.md` | Planning or extending a library integration; update status with implementation |
87
+ | `plans/` | Optional ignored local context; may be absent. Tracked integration plans and status own current scope and delivery. |
88
+
89
+ ## GitHub review evidence
90
+
91
+ - For PR/issue screenshots and recordings, use the authenticated GitHub CLI's
92
+ native `--attach` support; it does not require a browser login. Check
93
+ `gh pr comment --help` before assuming the installed CLI supports uploads.
94
+ - The default `gh` on this machine is older. A working official CLI is cached at
95
+ `tmp/github-cli-2.103.2/gh_2.103.2_macOS_arm64/bin/gh` in this repository. Use
96
+ that binary when present, or a newer official CLI with `--attach` support.
97
+ - Write multiline comment text to a temporary file, then run the capable binary:
98
+ `gh pr comment NUMBER --repo OWNER/REPO --body-file /private/tmp/comment.md --attach /absolute/demo.webm`.
99
+ The upload becomes a playable GitHub attachment. Verify the posted comment
100
+ contains its `github.com/user-attachments/assets/` URL. Keep media out of Git,
101
+ reuse configured CLI authentication, and never print tokens.
@@ -5,6 +5,61 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.8.0] - 2026-10-29
9
+
10
+ ### Added
11
+
12
+ - Optional Scanpy plotting integration through
13
+ `import genome_spy.integrations.scanpy as gsc`, preserving supported plotting
14
+ names and arguments while Scanpy continues to own analysis.
15
+ - Interactive embeddings, PCA diagnostics, dotplots, matrixplots, heatmaps,
16
+ clustermaps, expression tracks, ranked-gene summaries, quality checks,
17
+ time-series, DPT and PAGA plots. Unsupported plots and options fail explicitly.
18
+ - `EmbeddingSummary` for linked cell selections, expression summaries,
19
+ histograms and marker tracks, with optional cell counts and selection retrieval
20
+ in Python.
21
+ - Scanpy guides with live examples, downloadable notebooks, installation and
22
+ export instructions, and documented coverage limits.
23
+
24
+ ### Changed
25
+
26
+ - Support Scanpy >=1.11.5,<1.13, tested with 1.11.5 and 1.12.4, while keeping
27
+ the reference environment pinned independently.
28
+
29
+ ### Fixed
30
+
31
+ - Follow Scanpy 1.12's swapped-dotplot scaling and report its unavailable
32
+ automatic PAGA tree layouts without substituting another layout.
33
+
34
+ ## [0.7.0] - 2026-10-20
35
+
36
+ ### Added
37
+
38
+ - Typed facet and surround compositions, dendrogram transforms, secondary-offset
39
+ channels, and the remaining schema and expression additions from GenomeSpy 1.2.0.
40
+ - Discoverable named field arguments on encoding constructors and named setters
41
+ for inline schema objects, with automatic public exports for generated channels.
42
+ - A DepMap clustered heatmap gallery example adapted from the official GenomeSpy
43
+ surround specification.
44
+
45
+ ### Changed
46
+
47
+ - Upgrade the bundled GenomeSpy Core, controls, Inspector, and schema to 1.2.0.
48
+ - Use surround layouts in the PISA interaction matrix, UpSet mutations, PBMC
49
+ marker matrix, and PBMC cell heatmap examples.
50
+ - Use named Python arguments and schema objects throughout gallery configuration,
51
+ and Python expression objects in the updated surround examples.
52
+
53
+ ### Fixed
54
+
55
+ - Keep chart colors aligned with the documentation's selected light or dark theme.
56
+ - Serialize named channel objects in shared surround-side encodings.
57
+ - Preserve secondary-offset field and expression types according to the schema.
58
+ - Support named resolution settings on unit charts and omit forbidden schema
59
+ properties from generated signatures.
60
+ - Avoid redundant validation of nested schema objects when validation is explicitly
61
+ disabled, while retaining default validation checks.
62
+
8
63
  ## [0.6.0] - 2026-10-01
9
64
 
10
65
  ### Added
@@ -152,6 +207,9 @@ First public alpha release, targeting GenomeSpy Core 0.87.0.
152
207
  - Packaged example datasets, documentation, tutorials, and an interactive
153
208
  visualization gallery.
154
209
 
210
+ [0.8.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.7.0...v0.8.0
211
+ [0.7.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.6.0...v0.7.0
212
+ [0.6.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.5.0...v0.6.0
155
213
  [0.5.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.4.0...v0.5.0
156
214
  [0.4.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.3.0...v0.4.0
157
215
  [0.3.0]: https://github.com/genome-spy/genome-spy-python/compare/v0.2.0...v0.3.0
@@ -90,6 +90,7 @@ Regenerate after changing that version or the generator:
90
90
 
91
91
  ```bash
92
92
  uv run python tools/generate_schema_wrapper.py
93
+ uv run python tools/vendor_javascript.py
93
94
  ```
94
95
 
95
96
  This requires `npm` and internet access. Use `--package-dir` for a local package,
@@ -111,6 +112,25 @@ New transforms should be generated from the schema. Add overrides in
111
112
  `tools/generate_schema_wrapper.py` only for Python conventions the schema
112
113
  cannot describe.
113
114
 
115
+ The generator emits explicit typed constructor and setter arguments from schema
116
+ properties, including inline objects; avoid replacing these with untyped
117
+ `**kwargs` or runtime-only signature patches. Channel imports and `__all__` are
118
+ generated too. A new channel must appear in the public namespace automatically.
119
+ New composition families still need renderable chart classes, serialization and
120
+ round-trip support. The schema-derived root coverage test must fail until that
121
+ support exists, rather than silently omitting unfamiliar roots.
122
+
123
+ When adapting examples, use named schema objects or nested setters such as
124
+ `gs.Scale().zoom(extent="data")`. Keep dictionaries for data records and authored
125
+ names such as datasets, templates and parameter values. Test generated signatures
126
+ and type-check a consumer example as well as validating its serialized JSON.
127
+
128
+ Altair uses the same separation between a generated schema API and handwritten
129
+ chart operations. Its [constructor and setter generator](https://github.com/vega/altair/blob/main/tools/schemapi/codegen.py)
130
+ emits typed signatures and overloads; its [property-setter runtime](https://github.com/vega/altair/blob/main/altair/utils/schemapi.py)
131
+ also supplies signatures for interactive completion. Prefer our existing explicit
132
+ Python methods so completion, static checking and runtime calls agree.
133
+
114
134
  ## Documentation
115
135
 
116
136
  ### API reference
@@ -0,0 +1,30 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2025 scverse
4
+ Copyright (c) 2017 F. Alexander Wolf, P. Angerer, Theis Lab
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ * Redistributions of source code must retain the above copyright notice, this
11
+ list of conditions and the following disclaimer.
12
+
13
+ * Redistributions in binary form must reproduce the above copyright notice,
14
+ this list of conditions and the following disclaimer in the documentation
15
+ and/or other materials provided with the distribution.
16
+
17
+ * Neither the name of the copyright holder nor the names of its
18
+ contributors may be used to endorse or promote products derived from
19
+ this software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: genome-spy-python
3
- Version: 0.6.0
3
+ Version: 0.8.0
4
4
  Summary: genome-spy-python is a declarative genomics visualization library for Python, built on top of the genome-spy JSON specification.
5
5
  Project-URL: Homepage, https://github.com/genome-spy/genome-spy-python
6
6
  Project-URL: Documentation, https://genomespy.app/genome-spy-python/
@@ -16,6 +16,7 @@ License-File: LICENSES/CC0-1.0.txt
16
16
  License-File: LICENSES/DATA-SOURCE-REPOSITORIES-MIT.txt
17
17
  License-File: LICENSES/GENOMESPY-MIT.txt
18
18
  License-File: LICENSES/LATO-OFL-1.1.txt
19
+ License-File: LICENSES/SCANPY-BSD-3-Clause.txt
19
20
  License-File: LICENSES/VEGA-BSD-3-Clause.txt
20
21
  License-File: LICENSES/VEGA-LITE-BSD-3-Clause.txt
21
22
  License-File: THIRD_PARTY_NOTICES.md
@@ -33,8 +34,12 @@ Requires-Python: >=3.11
33
34
  Requires-Dist: anywidget>=0.11.0
34
35
  Requires-Dist: jsonschema>=4.26.0
35
36
  Requires-Dist: traitlets>=5.14.3
37
+ Provides-Extra: anndata
38
+ Requires-Dist: anndata>=0.11.0; extra == 'anndata'
36
39
  Provides-Extra: arrow
37
40
  Requires-Dist: pyarrow>=18.0.0; extra == 'arrow'
41
+ Provides-Extra: scanpy
42
+ Requires-Dist: scanpy[paga]<1.13,>=1.11.5; extra == 'scanpy'
38
43
  Description-Content-Type: text/markdown
39
44
 
40
45
  <p align="center">
@@ -69,6 +74,13 @@ The project is under active development. The current focus is the reusable
69
74
  GenomeSpy Core grammar and notebook rendering; GenomeSpy App-specific features
70
75
  will come later.
71
76
 
77
+ Optional library integrations keep upstream analysis workflows and replace
78
+ supported plotting calls. The [integration workspace](integrations/README.md)
79
+ links each implementation, tracked plan, workflow notebooks, tests, and user guide.
80
+ The Scanpy integration is implemented in
81
+ [`src/genome_spy/integrations/scanpy/`](src/genome_spy/integrations/scanpy/), exposed as
82
+ `import genome_spy.integrations.scanpy as gsc` and `gsc.pl.umap(...)`.
83
+
72
84
  ## Installation
73
85
 
74
86
  The package requires Python 3.11 or newer.
@@ -79,6 +91,12 @@ From PyPI:
79
91
  pip install genome-spy-python
80
92
  ```
81
93
 
94
+ For Scanpy plotting:
95
+
96
+ ```bash
97
+ pip install --upgrade 'genome-spy-python[scanpy]'
98
+ ```
99
+
82
100
  From source:
83
101
 
84
102
  ```bash
@@ -100,6 +118,21 @@ for supported tables and live updates.
100
118
 
101
119
  See the [getting-started guide](docs/getting-started.md) for the first example.
102
120
 
121
+ ## Agent skill
122
+
123
+ The package bundles a visualization skill for Codex and Claude Code. Installation
124
+ is explicit; importing or installing the Python package does not modify agent
125
+ configuration. To install for both agents in the current project:
126
+
127
+ ```bash
128
+ genome-spy-install-skills
129
+ ```
130
+
131
+ Use `--agent codex` or `--agent claude` to select one agent, `--project PATH` for
132
+ another project, or `--user` for personal installation. Existing modified skills
133
+ are preserved unless `--force` is supplied. See
134
+ [installation and update details](docs/agents/skill-distribution.md).
135
+
103
136
  ## Examples
104
137
 
105
138
  A zoomable Manhattan plot using the bundled HapMap data (requires `pandas`):