Files
tty7/assets/completions/ssh.json
l0ng-aiandl0ng-ai 21b7f82392 feat(completion): execute dynamic generators for live candidates (#52)
* feat(completion): execute dynamic generators for live candidates

The completion engine consumed Fig specs' static shape but never ran
their dynamic generators, so positions whose candidates come from the
live system — ssh hosts, git branches — fell through to filesystem
path completion (#51: ssh <Tab> listed the cwd).

Local-only by design: the pure engine returns each pending script, the
view runs it on the background executor (/bin/sh -c in the session
cwd, 800ms timeout, kill-on-drop, 256KiB stdout cap, 5s TTL cache) and
merges the parsed lines into the open menu, generation-tagged so a
result can't outlive its session. A per-script parser registry ports
the specs' dropped postProcess transforms (git markers, docker
{{json .}}, package.json scripts, …); unmatched scripts default to
one-candidate-per-line, and hopeless outputs are suppressed rather
than inserted as garbage.

ssh/scp/sftp/rsync specs gain host generators reading ~/.ssh/config
(Include-aware, wildcard patterns skipped) and known_hosts (hashed
entries skipped, [host]:port unwrapped).

Fixes #51

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>

* docs(comments): describe borrowed conventions directly

Prior-art name-drops in comments aged poorly as the implementations
diverged; keep the behavioral rationale, drop the product citations.

* fix(completion): make generator execution CI-portable

Linux: sh -c may fork the command instead of exec'ing it, so killing
only the shell on timeout left a grandchild holding the stdout pipe —
the reader (and the caller) then blocked until the grandchild exited
on its own. Spawn the child as its own process-group leader and kill
the group; the timeout test now forces the fork case (trailing true)
so the group-kill is what's actually proven.

Windows: generator scripts are POSIX sh + awk, so the execution path
now compiles to no-suggestions there instead of failing at runtime on
a missing /bin/sh; the process-spawning tests are Unix-only to match.

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-07-11 19:12:10 +08:00

1 line
13 KiB
JSON

{"description":"Log into a remote machine","options":[{"names":["-1"],"description":"Forces ssh to try protocol version 1 only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-2"],"description":"Forces ssh to try protocol version 2 only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-4"],"description":"Forces ssh to use IPv4 addresses only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-6"],"description":"Forces ssh to use IPv6 addresses only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-A"],"description":"Enables forwarding of the authentication agent connection","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-a"],"description":"Disables forwarding of the authentication agent connection","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-b"],"description":"Use bind_address on the local machine as the source address of the connection","args":[{"name":"bind address","description":"Source address of the connection","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-C"],"description":"Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11 and TCP connections)","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-c"],"description":"Selects the cipher specification for encrypting the session","args":[{"name":"cipher spec","description":"The selected cipher specification","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-D"],"description":"Specifies a local 'dynamic' application-level port forwarding","args":[{"name":"port","description":"Port of the bind address","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-e"],"description":"Sets the escape character for sessions with a pty (default: '~')","args":[{"name":"escape char","description":"Specified escape character","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-F"],"description":"Specifies an alternative per-user configuration file","args":[{"name":"configfile","description":"Path to alternative config file","optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-f"],"description":"Requests ssh to go to background just before command execution","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-g"],"description":"Allows remote hosts to connect to local forwarded ports","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-I"],"description":"Specify the PKCS#11 shared library ssh should use to communicate with a PKCS#11 token providing the user's private RSA key","args":[{"name":"pkcs11","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-i"],"description":"Selects a file from which the identity (private key) for public key authentication is read","args":[{"name":"identity file","description":"Path to identity (private key)","optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":true,"hidden":false},{"names":["-K"],"description":"Enables GSSAPI-based authentication and forwarding (delegation) of GSSAPI credentials to the server","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-k"],"description":"Disables forwarding (delegation) of GSSAPI credentials to the server","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-L"],"description":"Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side","args":[{"name":"port:host:hostport","description":"Local port, followed by host and host port to forward to","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-l"],"description":"Specifies the user to log in as on the remote machine","args":[{"name":"login name","description":"Name of user logging into remote machine","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-M"],"description":"Places the ssh client into ``master'' mode for connection sharing","args":[],"required":false,"repeatable":true,"hidden":false},{"names":["-m"],"description":"Additionally, for protocol version 2 a comma-separated list of MAC (message authentication code) algorithms can be specified in order of preference","args":[{"name":"mac spec","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-N"],"description":"Do not execute a remote command","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-n"],"description":"Redirects stdin from /dev/null (actually, prevents reading from stdin)","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-O"],"description":"Control an active connection multiplexing master process","args":[{"name":"ctl cmd","description":"Command that's passed to the master process","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-o"],"description":"Can be used to give options in the format used in the configuration file","args":[{"name":"option","description":"Options that can be specified in the format of the config file","optional":false,"variadic":false,"template":[],"suggestions":[{"names":["AddressFamily"],"description":null},{"names":["BatchMode"],"description":null},{"names":["BindAddress"],"description":null},{"names":["ChallengeResponseAuthentication"],"description":null},{"names":["CheckHostIP"],"description":null},{"names":["Cipher"],"description":null},{"names":["Ciphers"],"description":null},{"names":["ClearAllForwardings"],"description":null},{"names":["Compression"],"description":null},{"names":["CompressionLevel"],"description":null},{"names":["ConnectionAttempts"],"description":null},{"names":["ConnectTimeout"],"description":null},{"names":["ControlMaster"],"description":null},{"names":["ControlPath"],"description":null},{"names":["ControlPersist"],"description":null},{"names":["DynamicForward"],"description":null},{"names":["EscapeChar"],"description":null},{"names":["ExitOnForwardFailure"],"description":null},{"names":["ForwardAgent"],"description":null},{"names":["ForwardX11"],"description":null},{"names":["ForwardX11Timeout"],"description":null},{"names":["ForwardX11Trusted"],"description":null},{"names":["GatewayPorts"],"description":null},{"names":["GlobalKnownHostsFile"],"description":null},{"names":["GSSAPIAuthentication"],"description":null},{"names":["GSSAPIDelegateCredentials"],"description":null},{"names":["HashKnownHosts"],"description":null},{"names":["Host"],"description":null},{"names":["HostbasedAuthentication"],"description":null},{"names":["HostKeyAlgorithms"],"description":null},{"names":["HostKeyAlias"],"description":null},{"names":["HostName"],"description":null},{"names":["IdentityFile"],"description":null},{"names":["IdentitiesOnly"],"description":null},{"names":["IPQoS"],"description":null},{"names":["KbdInteractiveAuthentication"],"description":null},{"names":["KbdInteractiveDevices"],"description":null},{"names":["KexAlgorithms"],"description":null},{"names":["LocalCommand"],"description":null},{"names":["LocalForward"],"description":null},{"names":["LogLevel"],"description":null},{"names":["MACs"],"description":null},{"names":["NoHostAuthenticationForLocalhost"],"description":null},{"names":["NumberOfPasswordPrompts"],"description":null},{"names":["PasswordAuthentication"],"description":null},{"names":["PermitLocalCommand"],"description":null},{"names":["PKCS11Provider"],"description":null},{"names":["Port"],"description":null},{"names":["PreferredAuthentications"],"description":null},{"names":["Protocol"],"description":null},{"names":["ProxyCommand"],"description":null},{"names":["PubkeyAuthentication"],"description":null},{"names":["RekeyLimit"],"description":null},{"names":["RequestTTY"],"description":null},{"names":["RhostsRSAAuthentication"],"description":null},{"names":["RSAAuthentication"],"description":null},{"names":["SendEnv"],"description":null},{"names":["ServerAliveInterval"],"description":null},{"names":["ServerAliveCountMax"],"description":null},{"names":["StrictHostKeyChecking"],"description":null},{"names":["TCPKeepAlive"],"description":null},{"names":["Tunnel"],"description":null},{"names":["TunnelDevice"],"description":null},{"names":["UsePrivilegedPort"],"description":null},{"names":["User"],"description":null},{"names":["UserKnownHostsFile"],"description":null},{"names":["VerifyHostKeyDNS"],"description":null},{"names":["VisualHostKey"],"description":null},{"names":["XAuthLocation"],"description":null}],"generators":[]}],"required":false,"repeatable":true,"hidden":false},{"names":["-p"],"description":"Port to connect to on the remote host","args":[{"name":"port","description":"Port to connect to","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-q"],"description":"Quiet mode. Causes most warning and diagnostic messages to be suppressed","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-R"],"description":"Specifies that the given port on the remote (server) host is to be forwarded to the given host and port on the local side","args":[{"name":"port:host:hostport","description":"Local port, followed by host and host port to forward to","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-S"],"description":"Specifies the location of a control socket for connection sharing, or the string 'none' to disable connection sharing","args":[{"name":"ctl_path","description":"Location of the control socket","optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-s"],"description":"May be used to request invocation of a subsystem on the remote system","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-T"],"description":"Disable pseudo-tty allocation","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-t"],"description":"Force pseudo-tty allocation","args":[],"required":false,"repeatable":true,"hidden":false},{"names":["-V"],"description":"Display the version number and exit","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-v"],"description":"Verbose mode. Causes ssh to print debugging messages about its progress","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-W"],"description":"Requests that standard input and output on the client be forwarded to host on port over the secure channel","args":[{"name":"host:port","description":"Host and port to forward to","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-w"],"description":"Requests tunnel device forwarding with the specified tun(4) devices between the client (local_tun) and the server (remote_tun)","args":[{"name":"local tun","description":"Local device to forward to","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-X"],"description":"Enables X11 forwarding","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-x"],"description":"Disables X11 forwarding","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-Y"],"description":"Enables trusted X11 forwarding","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-y"],"description":"Send log information using the syslog(3) system module","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"user@hostname","description":"Address of remote machine to log into","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[{"script":["cat ~/.ssh/config $(awk 'tolower($1)==\"include\"{for(i=2;i<=NF;i++){p=$i;if(p ~ /^~\\//){sub(/^~/,ENVIRON[\"HOME\"],p)}else if(p !~ /^\\//){p=ENVIRON[\"HOME\"]\"/.ssh/\"p}print p}}' ~/.ssh/config 2>/dev/null) 2>/dev/null | awk 'tolower($1)==\"host\"{for(i=2;i<=NF;i++){if($i !~ /[*?!]/)print $i}}' | sort -u"]},{"script":["awk '/^[|#@]/{next}{n=split($1,a,\",\");for(i=1;i<=n;i++){h=a[i];sub(/^\\[/,\"\",h);sub(/\\]:[0-9]+$/,\"\",h);sub(/\\]$/,\"\",h);print h}}' ~/.ssh/known_hosts 2>/dev/null | sort -u"]}]}],"subcommands":[],"name":"ssh"}