mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-26 08:02:37 +00:00
* 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>
1 line
12 KiB
JSON
1 line
12 KiB
JSON
{"description":"OpenSSH secure file transfer","options":[{"names":["--help","-h"],"description":"Show help for sftp","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-4"],"description":"Forces scp to use IPv4 addresses only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-6"],"description":"Forces scp to use IPv6 addresses only","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-A"],"description":"Allows forwarding of ssh-agent(1) to the remote system. The default is not to forward an authentication agent","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-a"],"description":"Attempt to continue interrupted transfers rather than overwriting\nexisting partial or complete copies of files. If the partial\ncontents differ from those being transferred, then the resultant\nfile is likely to be corrupt","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-B"],"description":"Specify the size of the buffer that sftp uses when transferring\nfiles. Larger buffers require fewer round trips at the cost of\nhigher memory consumption. The default is 32768 bytes","args":[{"name":"buffer_size","description":"The buffer size","optional":false,"variadic":false,"template":[],"suggestions":[{"names":["32768"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-b"],"description":"Batch mode reads a series of commands from an input batchfile\ninstead of stdin. Since it lacks user interaction it should be\nused in conjunction with non-interactive authentication to obviate\nthe need to enter a password at connection time (see sshd(8) and\nssh-keygen(1) for details)","args":[{"name":"batchfile","description":"The batch file","optional":false,"variadic":false,"template":["filepaths"],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-C"],"description":"Compression enable. Passes the -C flag to ssh(1) to enable compression","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-c"],"description":"Selects the cipher to use for encrypting the data transfer. This option is directly passed to ssh(1)","args":[{"name":"cipher","description":"The selected cipher specification","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-D"],"description":"Connect directly to a local sftp server (rather than via ssh(1)).\nThis option may be useful in debugging the client and server","args":[{"name":"sftp_server_path","description":"Path to the SFTP server","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-F"],"description":"Specifies an alternative per-user configuration file for ssh. This option is directly passed to ssh(1)","args":[{"name":"ssh_config","description":"The selected ssh config","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-f"],"description":"Requests that files be flushed to disk immediately after transfer","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-i"],"description":"Selects the file from which the identity (private key) for public key authentication is read. This option is directly passed to ssh(1)","args":[{"name":"identity_file","description":"Specified identity file","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-J"],"description":"Connect to the target host by first making an scp connection to the\njump host described by destination and then establishing a TCP\nforwarding to the ultimate destination from there. Multiple jump\nhops may be specified separated by comma characters. This is a\nshortcut to specify a ProxyJump configuration directive. This\noption is directly passed to ssh(1)","args":[{"name":"destination","description":"Scp destination","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-l"],"description":"Limits the used bandwidth, specified in Kbit/s","args":[{"name":"limit","description":"Limit bandwidth in Kbit/s","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-N"],"description":"Disables quiet mode, e.g. to override the implicit quiet mode set by the -b flag","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-o"],"description":"Can be used to pass options to ssh in the format used in\nssh_config(5). This is useful for specifying options for which\nthere is no separate scp command-line flag. For full details of\nthe options listed below, and their possible values, see\nssh_config(5)","args":[{"name":"option","description":null,"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":false,"hidden":false},{"names":["-P"],"description":"Specifies the port to connect to on the remote host. Note that\nthis option is written with a capital ‘P’, because -p is already\nreserved for preserving the times and modes of the file","args":[{"name":"port","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-p"],"description":"Preserves modification times, access times, and modes from the original file","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-q"],"description":"Quiet mode: disables the progress meter as well as warning and diagnostic messages from ssh(1)","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-R"],"description":"Specify how many requests may be outstanding at any one time.\nIncreasing this may slightly improve file transfer speed but will\nincrease memory usage. The default is 64 outstanding requests","args":[{"name":"num_requests","description":"The number of requests","optional":false,"variadic":false,"template":[],"suggestions":[{"names":["64"],"description":null}],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-r"],"description":"Recursively copy entire directories. Note that scp follows symbolic links encountered in the tree traversal","args":[],"required":false,"repeatable":false,"hidden":false},{"names":["-S"],"description":"Name of program to use for the encrypted connection. The program must understand ssh(1) options","args":[{"name":"program","description":null,"optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-s"],"description":"Specifies the SSH2 subsystem or the path for an sftp server on the\nremote host. A path is useful when the remote sshd(8) does not\nhave an sftp subsystem configured","args":[{"name":"subsystem | sftp_server","description":"Path to the SFTP server","optional":false,"variadic":false,"template":[],"suggestions":[],"generators":[]}],"required":false,"repeatable":false,"hidden":false},{"names":["-v"],"description":"Verbose mode. Causes scp and ssh(1) to print debugging messages about their progress. This is helpful in debugging connection, authentication, and configuration problems","args":[],"required":false,"repeatable":false,"hidden":false}],"args":[{"name":"sources","description":"File or directory, local or remote ([user@]host:[path])","optional":false,"variadic":true,"template":["filepaths"],"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"]}]},{"name":"target","description":"File or directory, local or remote ([user@]host:[path])","optional":false,"variadic":false,"template":["filepaths"],"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":"sftp"} |