Make SSH apps, just like that! 💫

Wish

A nice rendering of a star, anthropomorphized somewhat by means of a smile, with the words ‘Charm Wish’ next to it
Latest Release GoDoc Build Status

Make SSH apps, just like that! 💫

SSH is an excellent platform to build remotely accessible applications on. It offers secure communication without the hassle of HTTPS certificates, it has user identification with SSH keys and it's accessible from anywhere with a terminal. Powerful protocols like Git work over SSH and you can even render TUIs directly over an SSH connection.

Wish is an SSH server with sensible defaults and a collection of middleware that makes building SSH apps easy. Wish is built on gliderlabs/ssh and should be easy to integrate into any existing projects.

Middleware

Bubble Tea

The bubbletea middleware makes it easy to serve any Bubble Tea application over SSH. Each SSH session will get their own tea.Program with the SSH pty input and output connected. Client window dimension and resize messages are also natively handled by the tea.Program.

You can see a demo of the Wish middleware in action at: ssh git.charm.sh

Git

The git middleware adds git server functionality to any ssh server. It supports repo creation on initial push and custom public key based auth.

This middleware requires that git is installed on the server.

Logging

The logging middleware provides basic connection logging. Connects are logged with the remote address, invoked command, TERM setting, window dimensions and if the auth was public key based. Disconnect will log the remote address and connection duration.

Access Control

Not all applications will support general SSH connections. To restrict access to supported methods, you can use the activeterm middleware to only allow connections with active terminals connected and the accesscontrol middleware that lets you specify allowed commands.

Default Server

Wish includes the ability to easily create an always authenticating default SSH server with automatic server key generation.

Examples

There are examples for a standalone Bubble Tea application and Git server in the examples folder. To see a more real-world application that combines Bubble Tea and Git, you can take a look at Soft Serve which uses Git as a CMS and provides a TUI over SSH for interacting with pushed repos.

Pro Tip

When building various Wish applications locally you can add the following to your ~/.ssh/config to avoid having to clear out localhost entries in your ~/.ssh/known_hosts file:

Host localhost
    UserKnownHostsFile /dev/null

License

MIT


Part of Charm.

The Charm logo

Charm热爱开源 • Charm loves open source

Owner
Charm
We build tools to make the command line glamorous
Charm
Comments
  • undefined: wish.Session

    undefined: wish.Session

    I was trying to run a couple of the examples in this repo, but seems they are broken after a recent refactor (ssh.Session => wish.Session)

    ./main.go:71:28: undefined: wish.Session
    
  • String together multiple tea.Programs inside one Wish application?

    String together multiple tea.Programs inside one Wish application?

    Maybe my thinking is wrong, if so, please correct me.

    I would like to have two, and perhaps more tea.Programs inside of a Wish app.

    For example, if public key authentication fails, I would like to fall back to an email access code base authentication, that would have a UI substantially different from the rest of my app.

    I think right now my only choice is to add a case inside my func (m model) View() string and either render the access code authenticator UI or render the rest of the app.

    I look into func myCustomBubbleteaMiddleware() wish.Middleware: https://github.com/charmbracelet/wish/blob/ce617216a32dd6411babed018981c25abfdc89ec/examples/bubbleteaprogram/main.go#L61

    However, inside myCustomBubbleteaMiddleware when building the teaHandler (to use the variable name from examples/bubbleteaprogram) I don't have access to the ssh.Session to check if I should instantiate the tea.Program for the emailed authentication code, or if the SSH key could be validated and thus the tea.Program for the rest of the app should be instantiated.

    Also, even if I did succeed in initially correctly instantiate one of two teaHandlers, once that tea.Program successfully completed, I don't see any way the running teaHandler could be replaced by another teaHandler.

    Ultimately I think the question is really your recommendation on organizing multi-screen tea applications, especially cases where the header/footer may be different on some screens (initial screens, graphs, final screens).

    If a more complicated application could be built by combining smaller tea applications, seems like it could really simplify development, testing and maintenance.

  • access to the `tea.Program` object

    access to the `tea.Program` object

    I'm using wish/bubbletea to serve an application. I would like to use the method Program.Send so another part of the application can trigger a behaviour in the UI part, but I don't see how I can access the tea.Program object from the middleware.

  • chat application

    chat application

    Hey there!

    Last year I wrote a game with Wish and Bubbletea. I had some game state shared between players, but I failed to find a way to have events sent from one client to another. Any tips on where to start? Would a minimal chat application make a good example for the wish repository?

  • feat(deps): bump github.com/hashicorp/golang-lru from 0.5.4 to 1.0.0

    feat(deps): bump github.com/hashicorp/golang-lru from 0.5.4 to 1.0.0

    Bumps github.com/hashicorp/golang-lru from 0.5.4 to 1.0.0.

    Release notes

    Sourced from github.com/hashicorp/golang-lru's releases.

    Tagging prior to v2

    This is likely the last tag prior to the switch to generics and the v2 package.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • fix: goroutine leak

    fix: goroutine leak

    we never really break out of that for loop, so, the goroutine would keep running there even long after the program that launched it finished.

    this fixes it.

  • Suggestions on how to host an app written with wish

    Suggestions on how to host an app written with wish

    The problem

    I want to deploy the app to my domain so that it's accessible from the terminal via ssh antoni.ai, but I have some difficulties figuring out how to do it properly.

    First, my go-to easy hosting provider (Railway) doesn't let ssh protocol through, so I can't deploy there. I've considered just getting a compute service like a droplet on digital ocean, but I also need to ssh into it to control it, so I can't expose port 22 there.

    My best guess here is to just have a service running and listening on a different port, and then use a reverse proxy to point port 22 to the previously mentioned service, but I once again hit the issue of having the 22nd port occupied for controlling the service.

    I also don't want to use my raspberry pi for this, because I don't want people ssh'ing into my home network, even if it looks pretty safe behind the TUI.

    Any suggestions would be greatly appreciated! ❤️

  • feat: rate limit middleware

    feat: rate limit middleware

    this middleware allows to rate limit clients using x/time/rate

    closes #43

    PS: not sure about the api yet, that's why no tests either. Looking for feedback.

  • Directory Traversal

    Directory Traversal

    Repo paths are not properly sanitized so users can access repos outside the designated repo dir.

    Users with read access will be able to access repos outside the directory, and users with write permissions have the ability to write outside that directory as well.

    A quick example that sort of demonstrates whats happening is just to run

    git clone 'ssh://git.charm.sh/soft-serve/../glow'
    

    That example doesnt demonstrate reading outside the repo directory (because I dont know where there may be repos on that server) but it does show that it walks the directory path just fine including the ... An attacker could implement some scanning logic to find other repos they arent supposed to have access to.

  • feat(deps): bump github.com/go-git/go-git/v5 from 5.4.2 to 5.5.0

    feat(deps): bump github.com/go-git/go-git/v5 from 5.4.2 to 5.5.0

    Bumps github.com/go-git/go-git/v5 from 5.4.2 to 5.5.0.

    Release notes

    Sourced from github.com/go-git/go-git/v5's releases.

    v5.5.0

    What's Changed

    Full Changelog: https://github.com/go-git/go-git/compare/v5.4.2...v5.5.0

    Commits
    • 3e07c50 Merge pull request #620 from fluxcd/update-deps
    • f2d68c4 build: bump git workflow to Go 1.19
    • 6629ba6 Update dependencies
    • b80af01 Update test.yml
    • 5132549 Merge pull request #622 from go-git/test-1.19
    • 67fb0c0 .github: update go version
    • 0966a00 Merge pull request #618 from fluxcd/collision_detection
    • 7c37589 sha1: Add collision resistent implementation
    • c798d4a Merge pull request #503 from jfontan/fix/similarity-matrix-too-big
    • acd6c65 Merge pull request #354 from dowy/issue/#309-clone-branch-with-hash-in-name
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • feat(deps): bump github.com/charmbracelet/bubbletea from 0.23.0 to 0.23.1

    feat(deps): bump github.com/charmbracelet/bubbletea from 0.23.0 to 0.23.1

    Bumps github.com/charmbracelet/bubbletea from 0.23.0 to 0.23.1.

    Release notes

    Sourced from github.com/charmbracelet/bubbletea's releases.

    v0.23.1

    This bugfix release addresses an issue that was introduced by v0.23.0 and prevented programs from re-using stdin after a tea.Program had finished execution.


    Changelog

    Fixed!


    Thoughts? Questions? We love hearing from you. Feel free to reach out on Twitter, The Fediverse, or Discord.

    Commits
    • 94d6f50 docs: update readme
    • 9c20a80 fix: don't close stdin
    • e079831 Remove references to io/ioutil package
    • 7ba62d4 chore(deps): bump github.com/charmbracelet/glamour in /examples
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • feat(deps): bump golang.org/x/crypto from 0.3.0 to 0.4.0

    feat(deps): bump golang.org/x/crypto from 0.3.0 to 0.4.0

    Bumps golang.org/x/crypto from 0.3.0 to 0.4.0.

    Commits
    • eb2c406 go.mod: update golang.org/x dependencies
    • 2c47667 cryptobyte: add support for ReadASN1Integer into []byte
    • See full diff in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
  • docs: running within systemd

    docs: running within systemd

    not sure if this is the best place for it, or if we should put it in another file... for now at least I think the readme is not "too big" yet...

  • feat: update termenv

    feat: update termenv

    WIP

    will need to update lipgloss (once https://github.com/charmbracelet/lipgloss/pull/91 gets released), bubbletea (once it gets a new release) as well

  • Color issues when running the program under a systemd service

    Color issues when running the program under a systemd service

    Hi!

    First, thanks for the great framework to make pretty terminal applications :)

    I am currently working on a SSH application, using Wish and BubbleTea. In particular, I am using somewhere a colored progress bar. This is working well.

    To manage and start properly my application, I am using a simple systemd service:

    [Unit]
    Description=My SSH application
    After=network.target
    
    [Service]
    ExecStart=/path/to/binary
    WorkingDirectory=/path/to/
    Restart=on-failure
    RestartSec=15s
    
    [Install]
    WantedBy=multi-user.target
    

    And when I start this service, the SSH server is working well, but my terminal has no color, all is black and white. This happens only when I run the application through the systemd service. When I manually launch the binary, the colors are well displayed.

    Do you know the origin of the issue, and how to fix it? I don't really want to keep my application opened in a tmux :D

  • Scp example requires -O flag with openssh 9.0

    Scp example requires -O flag with openssh 9.0

    Greetings!

    Love the library and everything you all are working towards!

    openssh v9 just released which changes the default protocol for scp https://www.openssh.com/txt/release-9.0

    The current scp example does not work unless specifying the -O flag.

    It seems like anyone that wishes to implement an scp server now needs to support both: legacy scp and sftp.

    I wanted to surface that potential issue here as well as ask a general question about implementation.

    I'm probably going to start working on adding sftp support to scp but wondered if you all had any advice on how to best implement it? Happy to send whatever I come up with upstream.

    Thanks!

Related tags
Get Brew Packages to update, just like you've experienced from Ubuntu
Get Brew Packages to update, just like you've experienced from Ubuntu

Get the number of Brew Packages to update, just like you've experienced from Ubuntu BrewUpdate is a simple utility written in Go, notify you how many

Nov 6, 2021
It‘s a cmd-line tool like `make` and `task`, supporting nested args and alias using `cobra`

It‘s a cmd-line tool like `make` and `task`, supporting nested args and alias using `cobra`. It's a makefile alternative and a shell wrapper.

Oct 18, 2022
I like reading news but I also like the terminal. I am leaning and practicing my go.
I like reading news but I also like the terminal. I am leaning and practicing my go.

I made an api and didn't know how to use it. Screenshots The initial screen when you first run the app. The screen after you specify an id. This app u

Jan 14, 2022
Argparse for golang. Just because `flag` sucks

Golang argparse Let's be honest -- Go's standard command line arguments parser flag terribly sucks. It cannot come anywhere close to the Python's argp

Dec 28, 2022
An implementation of sed in Go. Just because!

Sed-Go An implementation of sed in Go. Just because! Status Command-Line processing: Done. It accepts '-e', '-f', '-n' and long versions of the same.

Aug 23, 2022
Just a simple CLI tool to group dependabot PRs by dependency and merge them.
Just a simple CLI tool to group dependabot PRs by dependency and merge them.

Dependabotbot Have you been the victim of a lodash update? Has your notification page in Github been assaulted by needing to update a patch version of

Jun 30, 2022
It is an easy and fast tool to install your packages with just one command.

Trouxa It is an easy and fast tool to install your packages with just one command. What means "Trouxa"? In portuguese, Trouxa means something like a "

Sep 29, 2022
react, fiber, api just for saying hello

say-hello Introduction Sometimes we need to have a frontend besides the backend. This repository uses React to show how we can server a React build an

Nov 9, 2022
Golisp-wtf - A lisp interpreter (still just a parser) implementation in golang. You may yell "What the fuck!?.." when you see the shitty code.

R6RS Scheme Lisp dialect interpreter This is an implementation of a subset of R6RS Scheme Lisp dialect in golang. The work is still in progress. At th

Jan 7, 2022
Count once - Just once? no, when appear many it run once, but it can run many times

countOnce just once? no, when appear many it run once, but it can run many times

Jan 29, 2022
Turn .mp3 files in current directory to a podcast feed just one command.

dir2cast Turn .mp3 files in current directory to a podcast feed just one command. Then you can subscribe to it with your favorite podcast client, down

Jun 27, 2022
A simple, fast, and fun package for building command line apps in Go

cli cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable comm

Dec 31, 2022
A collection of terminal-based widgets for richer Golang CLI apps.
A collection of terminal-based widgets for richer Golang CLI apps.

Flinch A collection of terminal-based widgets for richer Golang CLI apps. Ships with a library to build your own widgets/TUIs too. Warning: This modul

Jan 7, 2023
A tiny markup language for terminal output. Makes formatting output in CLI apps easier!
A tiny markup language for terminal output. Makes formatting output in CLI apps easier!

tml - Terminal Markup Language A Go module (and standalone binary) to make the output of coloured/formatted text in the terminal easier and more reada

Dec 14, 2022
Viper: a complete configuration solution for Go applications including 12-Factor apps
Viper: a complete configuration solution for Go applications including 12-Factor apps

Viper v2 feedback Viper is heading towards v2 and we would love to hear what you would like to see in it. Share your thoughts here: https://forms.gle/

Dec 6, 2021
Start Go command line apps with ease
Start Go command line apps with ease

Start Start Go command line apps with ease Executive Summary The start package for Go provides two basic features for command line applications: Read

Oct 29, 2021
This repository contains example apps created using GoCondor framework

Examples This repository contains example apps created using GoCondor framework what are the examples? 1- Todo API A todo api with the below routes:

May 7, 2021
cli is a simple, fast, and fun package for building command line apps in Go.

cli cli is a simple, fast, and fun package for building command line apps in Go. The goal is to enable developers to write fast and distributable comm

Jul 10, 2022
This project is used to get familiar with GoLang cli apps, along with cobra generator.

SecretCTL SecretCTL About the project Status Getting started Layout Notes About the project This project is used to get familiar with GoLang cli apps,

Jan 11, 2022