Factor out all of the output into a separate module

No new functionality -- just a refactoring.  Easier to read and beef up the notification logic in the future.  Manual testing looks ok on `{unix,linux}`