I have monkey-patched Creep.move() and Creep.moveTo() methods, first one to save the creep's intended move direction, and second one to inject different defaults (reusePath: 50 and ignoreCreeps: true), as well as use custom CostMatrix callback so I can mark some specific creeps as unwalkable at some specific situations.
Then after all the creep logic has run its course I run another loop of collision resolver, that checks if there's a creep in the creep's intended move direction, whether it is moving or not, and tries to move the blocker creep out of the way, with some role-specific overrides provided, too.
Took me a few hours to code, a couple of days to iron all the edge cases, but now it works pretty well for 99.8% of cases. The remaining 0.02% result in some weird creep dancing, but tend to resolve themselves in a few ticks on their own.