{"id":13413836,"url":"https://github.com/charmbracelet/wish","last_synced_at":"2025-03-14T20:30:39.740Z","repository":{"id":37481861,"uuid":"228942508","full_name":"charmbracelet/wish","owner":"charmbracelet","description":"Make SSH apps, just like that! 💫","archived":false,"fork":false,"pushed_at":"2024-10-29T18:25:33.000Z","size":635,"stargazers_count":3575,"open_issues_count":8,"forks_count":71,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-10-29T20:27:47.475Z","etag":null,"topics":["hacktoberfest","ssh"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charmbracelet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-12-19T00:11:55.000Z","updated_at":"2024-10-29T18:25:35.000Z","dependencies_parsed_at":"2023-11-28T20:24:52.365Z","dependency_job_id":"daa565f4-4b64-4ee6-850f-bf8013f3ad56","html_url":"https://github.com/charmbracelet/wish","commit_stats":{"total_commits":316,"total_committers":14,"mean_commits":"22.571428571428573","dds":0.6265822784810127,"last_synced_commit":"ef5bbbc6eb2e884eddbcbc3587c7735097704934"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fwish","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fwish/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fwish/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charmbracelet%2Fwish/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charmbracelet","download_url":"https://codeload.github.com/charmbracelet/wish/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243641954,"owners_count":20323940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest","ssh"],"created_at":"2024-07-30T20:01:50.789Z","updated_at":"2025-03-14T20:30:39.416Z","avatar_url":"https://github.com/charmbracelet.png","language":"Go","readme":"# Wish\n\n\u003cp\u003e\n    \u003cimg style=\"width: 247px\" src=\"https://stuff.charm.sh/wish/wish-header.png\" alt=\"A nice rendering of a star, anthropomorphized somewhat by means of a smile, with the words ‘Charm Wish’ next to it\"\u003e\n    \u003cbr\u003e\n    \u003ca href=\"https://github.com/charmbracelet/wish/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/release/charmbracelet/wish.svg\" alt=\"Latest Release\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pkg.go.dev/github.com/charmbracelet/wish?tab=doc\"\u003e\u003cimg src=\"https://godoc.org/github.com/golang/gddo?status.svg\" alt=\"GoDoc\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/charmbracelet/wish/actions\"\u003e\u003cimg src=\"https://github.com/charmbracelet/wish/workflows/Build/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/charmbracelet/wish\"\u003e\u003cimg alt=\"Codecov branch\" src=\"https://img.shields.io/codecov/c/github/charmbracelet/wish/main.svg\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://goreportcard.com/report/github.com/charmbracelet/wish\"\u003e\u003cimg alt=\"Go Report Card\" src=\"https://goreportcard.com/badge/github.com/charmbracelet/wish\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\nMake SSH apps, just like that! 💫\n\nSSH is an excellent platform for building remotely accessible applications. It\noffers:\n* secure communication without the hassle of HTTPS certificates\n* user identification with SSH keys\n* access from any terminal\n\nPowerful protocols like Git work over SSH and you can even render TUIs directly over an SSH connection.\n\nWish is an SSH server with sensible defaults and a collection of middlewares that\nmakes building SSH apps really easy. Wish is built on [gliderlabs/ssh][gliderlabs/ssh]\nand should be easy to integrate into any existing projects.\n\n## What are SSH Apps?\n\nUsually, when we think about SSH, we think about remote shell access into servers,\nmost commonly through `openssh-server`.\n\nThat's a perfectly valid (and probably the most common) use of SSH, but it can do so much more than that.\nJust like HTTP, SMTP, FTP and others, SSH is a protocol!\nIt is a cryptographic network protocol for operating network services securely over an unsecured network. [^1]\n\n[^1]: https://en.wikipedia.org/wiki/Secure_Shell\n\nThat means, among other things, that we can write custom SSH servers without touching `openssh-server`,\nso we can securely do more things than just providing a shell.\n\nWish is a library that helps writing these kind of apps using Go.\n\n## Middleware\n\nWish middlewares are analogous to those in several HTTP frameworks.\nThey are essentially SSH handlers that you can use to do specific tasks,\nand then call the next middleware.\n\nNotice that middlewares are composed from first to last,\nwhich means the last one is executed first.\n\n### Bubble Tea\n\nThe [`bubbletea`](bubbletea) middleware makes it easy to serve any\n[Bubble Tea][bubbletea] application over SSH. Each SSH session will get their own\n`tea.Program` with the SSH pty input and output connected. Client window\ndimension and resize messages are also natively handled by the `tea.Program`.\n\nYou can see a demo of the Wish middleware in action at: `ssh git.charm.sh`\n\n### Git\n\nThe [`git`](git) middleware adds `git` server functionality to any ssh server.\nIt supports repo creation on initial push and custom public key based auth.\n\nThis middleware requires that `git` is installed on the server.\n\n### Logging\n\nThe [`logging`](logging)  middleware provides basic connection logging. Connects\nare logged with the remote address, invoked command, TERM setting, window\ndimensions and if the auth was public key based. Disconnect will log the remote\naddress and connection duration.\n\n### Access Control\n\nNot all applications will support general SSH connections. To restrict access\nto supported methods, you can use the [`activeterm`](activeterm) middleware to\nonly allow connections with active terminals connected and the\n[`accesscontrol`](accesscontrol) middleware that lets you specify allowed\ncommands.\n\n## Default Server\n\nWish includes the ability to easily create an always authenticating default SSH\nserver with automatic server key generation.\n\n## Examples\n\nThere are examples for a standalone [Bubble Tea application](examples/bubbletea)\nand [Git server](examples/git) in the [examples](examples) folder.\n\n## Apps Built With Wish\n\n* [Soft Serve](https://github.com/charmbracelet/soft-serve)\n* [Wishlist](https://github.com/charmbracelet/wishlist)\n* [SSHWordle](https://github.com/davidcroda/sshwordle)\n* [clidle](https://github.com/ajeetdsouza/clidle)\n* [ssh-warm-welcome](https://git.coopcloud.tech/decentral1se/ssh-warm-welcome)\n\n[bubbletea]: https://github.com/charmbracelet/bubbletea\n[gliderlabs/ssh]: https://github.com/gliderlabs/ssh\n\n## Pro tip\n\nWhen building various Wish applications locally you can add the following to\nyour `~/.ssh/config` to avoid having to clear out `localhost` entries in your\n`~/.ssh/known_hosts` file:\n\n```\nHost localhost\n    UserKnownHostsFile /dev/null\n```\n\n## How it works?\n\nWish uses [gliderlabs/ssh][gliderlabs/ssh] to implement its SSH server, and\nOpenSSH is never used nor needed — you can even uninstall it if you want to.\n\nIncidentally, there's no risk of accidentally sharing a shell because there's no\ndefault behavior that does that on Wish.\n\n## Running with SystemD\n\nIf you want to run a Wish app with `systemd`, you can create an unit like so:\n\n`/etc/systemd/system/myapp.service`:\n```service\n[Unit]\nDescription=My App\nAfter=network.target\n\n[Service]\nType=simple\nUser=myapp\nGroup=myapp\nWorkingDirectory=/home/myapp/\nExecStart=/usr/bin/myapp\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\n```\n\nYou can tune the values below, and once you're happy with them, you can run:\n\n```bash\n# need to run this every time you change the unit file\nsudo systemctl daemon-reload\n\n# start/restart/stop/etc:\nsudo systemctl start myapp\n```\n\nIf you use a new user for each app (which is good), you'll need to create them\nfirst:\n\n```bash\nuseradd --system --user-group --create-home myapp\n```\n\nThat should do it.\n\n###\n\n## Feedback\n\nWe’d love to hear your thoughts on this project. Feel free to drop us a note!\n\n* [Twitter](https://twitter.com/charmcli)\n* [The Fediverse](https://mastodon.social/@charmcli)\n* [Discord](https://charm.sh/chat)\n\n## License\n\n[MIT](https://github.com/charmbracelet/wish/raw/main/LICENSE)\n\n***\n\nPart of [Charm](https://charm.sh).\n\n\u003ca href=\"https://charm.sh/\"\u003e\u003cimg alt=\"The Charm logo\" src=\"https://stuff.charm.sh/charm-badge.jpg\" width=\"400\"\u003e\u003c/a\u003e\n\nCharm热爱开源 • Charm loves open source\n","funding_links":[],"categories":["Go","Server Applications","hacktoberfest","服务器应用程序"],"sub_categories":["HTTP Clients","HTTP客户端"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharmbracelet%2Fwish","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharmbracelet%2Fwish","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharmbracelet%2Fwish/lists"}