🚀 Features
- milo: speed up pydeseq2 da_nhoods ~100x via poscounts size factors (#992) @Zethson
- Guide RNA assignment: crispat-matching JAX MAP fit (10–30× faster) (#987) @Zethson
- DIALOGUE: from-scratch port of the R reference (PMD + HLM + iterative NNLS) (#988) @Zethson
- PyDESeq2: optional apeGLM LFC shrinkage (#985) @Zethson
- Add layout option to coda plot_boxplots (#718) (#932) @emekaokoli19
🐛 Bug Fixes
- scCODA: fix run_hmc TypeError; clarify log2-fold-change sign (#993) @Zethson
- scCODA/tascCODA: make make_arviz stateless (#991) @Zethson
- scCODA: unify covariate index format across get_effect_df / summary / credible_effects (#989) @Zethson
- Reject all-zero contrasts in test_contrasts (#981) @Zethson
- Fix PseudobulkSpace.compute losing X with anndata main (#979) @Zethson
- Fix plot_effects_umap KeyError on Sccoda output (#780) (#971) @LiudengZhang
- Fix marker positions: calculate marker positions from DataFrame, not rendered labels (#970) @kimjune01
- Fix plot_multicomparison_fc ValueError with default figsize (#965) @kimjune01
- Fix minor bugs (#960) @Zethson
- Fix
addandsubtract(#959) @Zethson