Stacks usually run more than one service, so the last service read used
to wipe the status of the stack. Merge the labels into the existing map
instead.
Servers are now queried through an injectable fetcher with a concurrency
limit, so a large fleet no longer opens one SSH connection per server at
once, and the fetch is testable.
Also:
- only read the recipe catalogue when a deployed version exists, and
render statuses anyway if it cannot be fetched
- truncate the error banner instead of joining every server error
- clamp the page size to at least one row, as bubble-table otherwise
renders nothing at all
- stop treating keypresses as commands while the filter has focus, so q
types a q rather than quitting
- parse flags on a dedicated flag set with long forms, so a bad flag
reports against cctuip help instead of exiting
- drop golang.org/x/exp in favour of the built-in maps
- query each server independently for app status so ssh login issues no
longer abort the whole poll (partial results still render)
- show ssh/server errors as a dismissible banner instead of a dead-end
error screen; any key dismisses and s can be retried
- guard against concurrent status polls
- stop tracking the compiled cctuip binary, add .gitignore
- add -v/--version flag, remove dead code, harden type assertions,
cache recipe catalogue lookups
- align README install + controls with the code