Shameless plug: if you find yourself wanting more advamced custom painting, you can try http://trunk.io, which provides you with three different ways to write your own linters (pass/fail based on your script's exit code, spit out a patch that should be applied to your code, or LSP diagnostics) that can get propagated to VSCode and CI (as well as just as a CLI tool, if that's your preference).
Disclaimer: I work on trunk :)