Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add truecolor info #273

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,11 @@ Host localhost
## How it works?

Wish uses [gliderlabs/ssh][gliderlabs/ssh] to implement its SSH server, and
OpenSSH is never used nor needed — you can even uninstall it if you want to.
OpenSSH's server process, `sshd`, is never used nor needed — you can even
uninstall it if you want to.

Incidentally, there's no risk of accidentally sharing a shell because there's no
default behavior that does that on Wish.
default behavior that does that with Wish.

## Running with SystemD

Expand Down
33 changes: 33 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Wish Docs

Welcome to the Wish official documentation. If you're new to the project, make
sure you check out the [README][README] for a high-level overview of the project
and how to get started. From there, take a look at the [examples][examples].
They're ordered by complexity and will show you how to use Wish. If you're
looking for additional functionality not shown in the examples, I'd highly
recommend checking out the [godoc][pkg.go.dev]. The godoc showcases all of the
functionality available to you with Wish alongside descriptions on what those
functions do.

If you want *more* examples from projects of various sizes,
[sourcegraph][sourcegraph] is a great code search tool that can help you find
other projects that use Wish. A great way to leverage this tool is when looking
at our API (in the godoc), do a global search for that specific function. e.g.
`wish.NewServer`. If you have questions about the limitations of Wish, we're
happy to help, though given we're a small team of maintainers, it may take some
time. In the meantime, you may find that [phorm.ai][phorm] is helpful in
answering your questions about Charm projects. We've found it to be quite
helpful so far.

This directory includes additional information about how Wish works. The topics
chosen for this section are based on frequently asked questions in the
community. If there's a topic you'd like to see covered in this section, please
submit an [issue][issue] with links to or quotes of questions on that topic.
That will allow us to ensure we're answering the question effectively.

[README]: https://github.com/charmbracelet/wish?tab=readme-ov-file#wish
[examples]: https://github.com/charmbracelet/wish/tree/main/examples#wish-examples
[pkg.go.dev]:https://pkg.go.dev/github.com/charmbracelet/wish
[issue]: https://github.com/charmbracelet/wish/issues/new/choose
[phorm]: https://www.phorm.ai
[sourcegraph]: https://sourcegraph.com/search?q=context:global+wish.NewServer&patternType=keyword&sm=0
123 changes: 123 additions & 0 deletions docs/truecolor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Truecolor Over SSH With Wish

If you're having issues with colors displaying properly in your Wish apps, you
may have to force `truecolor` support with
`bm.MiddlewareWithColorProfile(handler, termenv.TrueColor)` when defining the
middleware for your `Wish` server. This will force `truecolor` support. For
example:

```go
import (
// ...
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/log"
"github.com/charmbracelet/ssh"
"github.com/charmbracelet/wish"
"github.com/charmbracelet/wish/activeterm"
"github.com/charmbracelet/wish/bubbletea"
"github.com/charmbracelet/wish/logging"
)

// ...

func main() {
s, err := wish.NewServer(
wish.WithAddress(net.JoinHostPort(host, port)),
wish.WithHostKeyPath(".ssh/id_ed25519"),
wish.WithMiddleware(
bubbletea.MiddlewareWithColorProfile(teaHandler, termenv.TrueColor) // Force truecolor.
activeterm.Middleware(), // Bubble Tea apps usually require a PTY.
logging.Middleware(),
),
)),
)
// ...
```

[see more][examples-bubbletea]

This *may* cause issues for users accessing your Wish app through a terminal
emulator that is not `truecolor` compatible (e.g. Apple's Terminal app).

## Color profiles? What, like it's hard?

We'll dive into the root of the problem for those who want to learn more. In an
SSH session, the client only sends the `TERM` environment variable, which can
only detect `256 color` support. If you run `echo $COLORTERM` in your shell
you'll likely see `truecolor` as the result, which is what you want for ultra
colorful terminal outputs. If you don't see that as a result, it might be time
to try a new [terminal emulator][supported-emulators].

Unfortunately, there is no standard way for terminals to detect `truecolor`
support in an SSH session, hence why it defaults to `256 color`. Most terminals
express their `truecolor` support with the `COLORTERM` environment variable,
but this doesn't get sent when connecting over SSH. One workaround is to make
SSH send this environment variable using `SendEnv COLORTERM` in the [`ssh
config`][truecolor-ssh]. By default, the OpenSSH client (what you're using when
you run `ssh`) will only send the `TERM` to the remote, so other variables must
be configured. In the future, we hope to solve this problem by querying the
terminal for support if `COLORTERM` is not detected.

You can learn more about [checking for `COLORTERM`][colorterm-issue].

Because of this, the color options are limited and your experience running the
app locally will differ to how it presents over SSH. You're probably wondering
*how much* of a difference this makes. Well, `256 color` support uses a palette
with 256 colors available. By contrast, `truecolor` supports a whopping 16
**million** different colors.

[Learn more about color standards for terminal emulators][termstandard]

## What is Wish

Wish is an SSH server that allows you to make your apps accessible over SSH. It
uses SSH middleware to handle connections, so you can serve specific actions to
the user, then call the next middleware.

Wish uses the SSH protocol to authenticate users, then allows the developer to
specify how to handle these connections. We've used Wish to serve both TUIs
(textual UIs) *and* CLIs. If you've hosted your own [Soft Serve][soft] git
server, then you'll have seen this first hand. Soft Serve uses a middleware to
serve the TUI and another middleware for its CLI, allowing users to interact
with the server through either interface. In this case, the CLI is useful for
any server administration tasks, while the TUI provides a great interface to
view your repositories. Note that both of these options are accessible through
the same port (pretty neat).

Similar to a website, this process runs on the server, freeing up your computer's
resources for other things. What's great about this is it also gives you a
consistent state no matter where you connect from (as long as you've got your
authorized SSH keys with you).

## Noteworthy environment variables (for debugging)

These environment variables may help you should you encounter unexpected
behavior when working with terminal styling.

`TERM` - provides information about your terminal emulator's capabilities. This
is the only environment variable out of this list that is sent in an SSH
session. The rest are included for debugging purposes only.

`COLORTERM` - provides information about your terminal emulator's color
capabilities. Used primarily to specify if your emulator has `truecolor`
support.

`NO_COLOR` - turns colors on and off. `NO_COLOR=1` for non-colored text
outputs, `NO_COLOR=0` for colored text outputs.

`CLICOLOR` - turns colors on and off. `CLICOLOR=1` for colored text outputs,
`CLICOLOR=0` for non-colored text outputs.

`CLICOLOR_FORCE` - overrides `CLICOLOR`.

`NO_COLOR` vs `CLICOLOR`: if `NO_COLOR` is set or `CLICOLOR=0` then the output should
not be colored. Otherwise, the output can include ansi sequences.

[termstandard]: https://github.com/termstandard/colors
[supported-emulators]: https://github.com/termstandard/colors?tab=readme-ov-file#terminal-emulators
[truecolor-ssh]: https://fixnum.org/2023-03-22-helix-truecolor-ssh-screen/
[colorterm-issue]: https://github.com/termstandard/colors?tab=readme-ov-file#truecolor-detection
[examples-bubbletea]: https://github.com/charmbracelet/wish/blob/main/examples/bubbletea/main.go#L35
[soft]: https://github.com/charmbracelet/soft-serve
[termenv]: https://github.com/muesli/termenv/blob/345783024a348cbb893bf6f08f1d7ab79d2e22ff/termenv_unix.go#L53
Loading