{"id":20571823,"url":"https://github.com/usrme/wishlistlite","last_synced_at":"2026-02-07T17:04:54.199Z","repository":{"id":41468467,"uuid":"490790346","full_name":"usrme/wishlistlite","owner":"usrme","description":"The lesser SSH directory ✨","archived":false,"fork":false,"pushed_at":"2024-09-06T05:40:46.000Z","size":3231,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-17T15:14:53.654Z","etag":null,"topics":["go","golang","linux","macos","ssh","tui","unix"],"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/usrme.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-10T17:07:03.000Z","updated_at":"2024-09-06T05:40:49.000Z","dependencies_parsed_at":"2024-02-02T10:25:57.775Z","dependency_job_id":"8ec0137e-9780-4335-99d9-587189ecaa40","html_url":"https://github.com/usrme/wishlistlite","commit_stats":null,"previous_names":["usrme/wishlist-lite"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/usrme/wishlistlite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usrme%2Fwishlistlite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usrme%2Fwishlistlite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usrme%2Fwishlistlite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usrme%2Fwishlistlite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/usrme","download_url":"https://codeload.github.com/usrme/wishlistlite/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/usrme%2Fwishlistlite/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29200843,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T16:28:23.579Z","status":"ssl_error","status_checked_at":"2026-02-07T16:28:22.566Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["go","golang","linux","macos","ssh","tui","unix"],"created_at":"2024-11-16T05:17:24.034Z","updated_at":"2026-02-07T17:04:54.184Z","avatar_url":"https://github.com/usrme.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wishlist Lite\n\n![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/usrme/wishlistlite)\n[![test](https://github.com/usrme/wishlistlite/actions/workflows/test.yml/badge.svg)](https://github.com/usrme/wishlistlite/actions/workflows/test.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/usrme/wishlistlite)](https://goreportcard.com/report/github.com/usrme/wishlistlite)\n\nThe lesser SSH directory (though maybe not so much anymore) ✨\n\nI made this a little while after discovering the canonical [Wishlist](https://github.com/charmbracelet/wishlist), but after not getting it to work properly (it wasn't able to connect to any of my defined hosts) I still felt the need for a tool of this sort. This luckily coincided with the time I started learning about Go and after a bit of faffing about I got something to work!\n\n![Wishlist Lite - animated GIF demo](examples/demo.gif)\n\n## Features\n\n- Ping individual hosts on demand\n- Measure time it takes to connect to a host\n- Store when and what was connected to with a local file\n- Connect to a host interactively\n\n## Installation\n\n- using `go install`:\n\n```bash\ngo install github.com/usrme/wishlistlite@latest\n```\n\n- download a binary from the [releases](https://github.com/usrme/wishlistlite/releases) page\n\n- build it yourself (requires Go 1.18+):\n\n```bash\ngit clone https://github.com/usrme/wishlistlite.git\ncd wishlistlite\ngo build\n```\n\n## Removal\n\n```bash\nrm -f \"${GOPATH}/bin/wishlistlite\"\nrm -rf \"${GOPATH}/pkg/mod/github.com/usrme/wishlistlite*\"\n```\n\n## Usage\n\nExecute `wishlistlite`, which opens up an alternate screen where you can (hopefully) see all of your hosts from your `~/.ssh/config` listed, which can then be SSH-ed into by selecting the appropriate one using arrow keys, or filtering for it, and pressing Enter. It then just grabs whatever is next to the `Host` declaration, precedes it with `ssh`, runs that executable, and exits `wishlistlite` leaving you with an SSH session.\n\nIt's also possible to press the letter `i`, which will allow you to supply a host to connect to on an ad-hoc basis. For example inputting `user@example.com` and pressing Enter will go through the exact process as above. Any of the entries from your SSH configuration are still valid as inputs.\n\nTo sort by recently connected to hosts press the letter `r`, which will read the file `~/.ssh/recent.json`, which gets created with the same entries as presented in the default view. After connecting to various hosts that file will be sorted according to which host was connected to recently. Press `r` again to return to the default view.\n\nTo delete entries from the recently connected view press the letter `d`, which will remove the selected host from the view and immediately save the changes to the `~/.ssh/recent.json` file.\n\nTo copy a highlighted entry's 'HostName' value to the clipboard press the letter `c`. This works when viewing configuration entries and the recently connected to hosts.\n\n### Caveats\n\nHosts starting with an asterisk are excluded as those (in my use case) usually mean either a `ProxyJump` or a `User` declaration right after. The entire parsing is done with regular expressions, so there may be other edge cases with parsing, but I've tried to cover the most common cases with the included tests.\n\nBefore starting the execution there is a verification that is made that the `ssh` executable exists and that any necessary SSH keys are already loaded into an SSH agent.\n\nThe ability to show a stopwatch counting up to the moment a connection is made is achieved through the use of the ['ControlMaster'](https://www.mankier.com/5/ssh_config#ControlMaster), ['ControlPersist'](https://www.mankier.com/5/ssh_config#ControlPersist), and ['ControlPath'](https://www.mankier.com/5/ssh_config#ControlPath) SSH options. Here is some [more information on those options](https://usrme.xyz/tils/that-ssh-allows-for-connection-sharing/) and the [GitHub issue](https://github.com/usrme/wishlistlite/issues/8) behind implementing it. The caveat is in that a socket is being set up in `/dev/shm` that is privileged only to your own user.\n\nHere is how the connection flow works by way of showing the system processes:\n\n* Just Wishlist Lite being open:\n\n```text\nsystemd(1)───...───wishlistlite(85716)─┬─{wishlistlite}(85717)\n                                       ├─{wishlistlite}(85718)\n                                       ├─{wishlistlite}(85719)\n                                       ├─{wishlistlite}(85720)\n                                       ├─{wishlistlite}(85721)\n                                       ├─{wishlistlite}(85722)\n                                       ├─{wishlistlite}(85723)\n                                       ├─{wishlistlite}(85724)\n                                       └─{wishlistlite}(85725)\n```\n\n* Having initiated a connection, which brought up a parent SSH connection with [specific SSH options](https://github.com/usrme/wishlistlite/blob/146a247cb3fea212b900a8b296e978974a9fb454/main.go#L20):\n\n```text\nsystemd(1)───...───wishlistlite(85716)─┬─ssh(85853)───ssh(85854)\n                                       ├─{wishlistlite}(85717)\n                                       ├─{wishlistlite}(85718)\n                                       ├─{wishlistlite}(85719)\n                                       ├─{wishlistlite}(85720)\n                                       ├─{wishlistlite}(85721)\n                                       ├─{wishlistlite}(85722)\n                                       ├─{wishlistlite}(85723)\n                                       ├─{wishlistlite}(85724)\n                                       ├─{wishlistlite}(85725)\n                                       ├─{wishlistlite}(85855)\n                                       ├─{wishlistlite}(85856)\n                                       ├─{wishlistlite}(85857)\n                                       └─{wishlistlite}(85858)\n```\n\n* Being finally connected to a host:\n\n```text\nsystemd(1)───...───ssh(85716)───ssh(85853)\n```\n\nNote how the original process ID of Wishlist Lite (85716) is now that of the SSH process'. This is happening because of the call to `syscall.Exec` [here](https://github.com/usrme/wishlistlite/blob/146a247cb3fea212b900a8b296e978974a9fb454/main.go#L69), which in turn invokes the ['execve(2) system call'](https://www.mankier.com/2/execve), which:\n\n\u003e causes the program that is currently being run by the calling process to be replaced with a new program, with newly initialized stack, heap, and (initialized and uninitialized) data segments.\n\n## Acknowledgments\n\nCouldn't have been possible without the work of people in [Charm](https://github.com/charmbracelet).\n\n## License\n\n[MIT](/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusrme%2Fwishlistlite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fusrme%2Fwishlistlite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fusrme%2Fwishlistlite/lists"}