Skip to content

sugarcraft/sugar-wishlist

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

89 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

sugar-wishlist

SugarWishlist

CI codecov Packagist Version License PHP

demo

PHP port of charmbracelet/wishlist β€” a TUI directory of SSH endpoints. Launch wishlist, pick a host, hit Enter, and the current process is replaced with ssh connecting to it.

── wishlist ──
filter:
β–Έ production  ─  deploy@prod.example.com:2222
  staging     ─  stage.example.com
  dev         ─  dev.example.com

  ↑/↓ select Β· Enter connect Β· Esc quit Β· type to filter

Install

The wishlist binary lives at bin/wishlist. Composer adds it to your global vendor/bin/ when installed as a project dependency, or you can add the repo's bin/ to your $PATH.

composer require sugarcraft/sugar-wishlist
~/.composer/vendor/bin/wishlist

Configure

wishlist looks for, in order:

  1. --config <path> (CLI flag)
  2. ~/.config/wishlist.yml
  3. ~/.config/wishlist.yaml
  4. ~/.config/wishlist.json
  5. wishlist.{yml,yaml,json} in the current directory

YAML

- name: production
  host: prod.example.com
  port: 2222
  user: deploy
  identity_file: ~/.ssh/prod-deploy

- name: staging
  host: stage.example.com
  user: deploy

- name: jumpbox
  host: bastion.example.com
  options:
    - ServerAliveInterval=30
    - ProxyJump=gw.example.com

JSON

[
  { "name": "production", "host": "prod.example.com", "port": 2222, "user": "deploy" },
  { "name": "staging",    "host": "stage.example.com" }
]

Keybindings

Key Action
↑ / k Move up
↓ / j Move down
Enter Connect to highlighted endpoint
Esc / ^C Quit without connecting
(typing) Type-to-filter; Backspace clears

Implementation

The picker is a tiny standalone widget β€” not a full SugarBits List. The lifecycle is

read config β†’ render picker β†’ read keys β†’ choose β†’ pcntl_exec(ssh, argv)

That last pcntl_exec is the critical line: it replaces the PHP process with ssh. File descriptors, environment, and the controlling tty all flow through unchanged, so the user sees a normal ssh session β€” host-key prompts, agent forwarding, MOTD, exit status, all native. We never proxy bytes; we get out of the way.

Programmatic use

use SugarCraft\Wishlist\Config;
use SugarCraft\Wishlist\Picker;
use SugarCraft\Wishlist\Launcher;

$endpoints = Config::load('/etc/wishlist.yml');
$picked    = (new Picker())->pick($endpoints);
if ($picked !== null) {
    (new Launcher())->dispatch($picked);
}

Import from SSH Config

wishlist can import endpoints directly from your OpenSSH config file (~/.ssh/config):

use SugarCraft\Wishlist\Config;

$endpoints = Config::importFromSshConfig('/home/user/.ssh/config');

The parser handles:

SSH Config Key Endpoint Field
Host <pattern> name
HostName <value> host
User <value> user
Port <value> port
IdentityFile <path> identityFiles[]
ProxyJump <host> proxyJump

Host * global defaults are inherited by all subsequent host blocks. Host patterns are used as the endpoint name (when no HostName is specified, the pattern itself becomes the host).

Programmatic Use

use SugarCraft\Wishlist\Config;
use SugarCraft\Wishlist\Picker;
use SugarCraft\Wishlist\Launcher;

$endpoints = Config::load('/etc/wishlist.yml');
$picked    = (new Picker())->pick($endpoints);
if ($picked !== null) {
    (new Launcher())->dispatch($picked);
}

// Or import from SSH config:
$sshEndpoints = Config::importFromSshConfig('/home/user/.ssh/config');

Shared foundations

sugar-wishlist uses candy-fuzzy β€” SmithWatermanMatcher::matchAll() replaces ad-hoc str_contains-style filtering. The picker now surfaces scored ranking and match-highlight indices (ANSI bold+cyan on matched grapheme clusters) for ranked, highlighted filter results.

Status

Phase 10.28 β€” SSH config import. 69 tests / 176 assertions. Endpoint, Config (JSON + flat-YAML + SSH config), Picker, Launcher, SshConfigParser are all covered.

About

πŸš€ PHP port of 🧭 wishlist β€” SSH endpoint launcher: YAML/JSON shortcut directory, interactive TUI picker, full host-key & agent-forwarding fidelity.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages