Trunk currently runs all of the transcripts by shelling out to the unison cli, this causes two problems:
* It's slow to boot up a fresh ucm for every transcript
* On Windows, we're likely to encounter [this bug](https://github.com/commercialhaskell/stack/issues/5038) which comes up when using `readProcess`, I'm noticing when I run transcripts on windows it inserts a ton of `++stty: 'standard input': Inappropriate ioctl for device` into output files.
As far as speedup goes, a quick benchmark on non-optimized builds shaves off ~90 seconds!
```
New version
/usr/bin/time stack exec transcripts
103.79 real 153.25 user 89.79 sys
/usr/bin/time stack exec transcripts
193.79 real 183.08 user 6.97 sys
```
Implementation notes
* Define `withTranscriptRunner`, which does a single initialization and then provides a transcript runner to the provided action. The caller can run any number of transcripts without re-initializing the runtime.
* Rather than crash the with an `exit 1` on failure and then detect that exit code, we return an Either which can be handled as a test failure.
I think it's only needed in these two spots, as the other
executables just shell out to `stack exec unison`.
I'm not actually clear on how this interacts with (or could be replaced by `hSetEncoding`, which we do have sprinkled around already, but not sufficiently to let Windows builds work.
If there's a cleaner solution, I'd like to use it. i.e. am I papering over a more correct multi-platform fix by using the Windows-only System.IO.Codepage?
the haskell language server was giving me some errors about not being able to find a local cli package, renaming it to unison-cli fixed that and seems to be consistent with other naming conventions.