Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use pty aware charmbracelet/ssh #219

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 4 additions & 40 deletions bubbletea/tea.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@ package bubbletea

import (
"context"
"io"

"github.com/aymanbagabas/go-pty"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/log"
"github.com/charmbracelet/ssh"
"github.com/charmbracelet/wish"
"github.com/muesli/termenv"
)

// BubbleTeaHandler is the function Bubble Tea apps implement to hook into the
Expand All @@ -24,7 +20,7 @@ type BubbleTeaHandler = Handler // nolint: revive
// Handler is the function Bubble Tea apps implement to hook into the
// SSH Middleware. This will create a new tea.Program for every connection and
// start it with the tea.ProgramOptions returned.
type Handler func(ssh.Session, *lipgloss.Renderer) (tea.Model, []tea.ProgramOption)
type Handler func(ssh.Session) (tea.Model, []tea.ProgramOption)

// Middleware takes a Handler and hooks the input and output for the
// ssh.Session into the tea.Program.
Expand All @@ -34,21 +30,19 @@ type Handler func(ssh.Session, *lipgloss.Renderer) (tea.Model, []tea.ProgramOpti
func Middleware(bth Handler) wish.Middleware {
return func(sh ssh.Handler) ssh.Handler {
return func(s ssh.Session) {
tty, windowChanges, ok := s.Pty()
_, windowChanges, ok := s.Pty()
if !ok {
wish.Fatalln(s, "no active terminal, skipping")
return
}

renderer := lipgloss.NewRenderer(tty, termenv.WithColorCache(true))

m, hopts := bth(s, renderer)
m, hopts := bth(s)
if m == nil {
log.Error("no model returned by the handler")
return
}

opts := append(hopts, makeIOOpts(tty)...)
opts := append(hopts, makeIOOpts(s)...)
p := tea.NewProgram(m, opts...)
if p != nil {
ctx, cancel := context.WithCancel(s.Context())
Expand All @@ -75,38 +69,8 @@ func Middleware(bth Handler) wish.Middleware {
// tui crash
p.Kill()
cancel()
if err := tty.Close(); err != nil {
log.Error("could not close pty", "error", err)
return
}

}
sh(s)
}
}
}

// Command makes a *pty.Cmd executable with tea.Exec.
func Command(c *pty.Cmd) tea.ExecCommand { return &ptyCommand{c} }

type ptyCommand struct{ *pty.Cmd }

func (*ptyCommand) SetStderr(io.Writer) {} // noop
func (*ptyCommand) SetStdin(io.Reader) {} // noop
func (*ptyCommand) SetStdout(io.Writer) {} // noop

func makeIOOpts(tty ssh.Pty) []tea.ProgramOption {
upty, ok := tty.Pty.(pty.UnixPty)
if !ok {
return []tea.ProgramOption{
tea.WithInput(tty),
tea.WithOutput(tty),
}
}

f := upty.Slave()
return []tea.ProgramOption{
tea.WithInput(f),
tea.WithOutput(f),
}
}
25 changes: 25 additions & 0 deletions bubbletea/tea_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//go:build !linux && !darwin && !freebsd && !dragonfly && !netbsd && !openbsd && !solaris
// +build !linux,!darwin,!freebsd,!dragonfly,!netbsd,!openbsd,!solaris

package bubbletea

import (
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/ssh"
"github.com/muesli/termenv"
)

// MakeRenderer returns a new lipgloss.Renderer for the given ssh.Session.
// It will use the pty if one is available, otherwise it will use the session
// writer.
func MakeRenderer(s ssh.Session) *lipgloss.Renderer {
return lipgloss.NewRenderer(s, termenv.WithUnsafe(), termenv.WithColorCache(true))
}

func makeIOOpts(s ssh.Session) []tea.ProgramOption {
return []tea.ProgramOption{
tea.WithInput(s),
tea.WithOutput(s),
}
}
40 changes: 40 additions & 0 deletions bubbletea/tea_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris

package bubbletea

import (
"io"

tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/ssh"
"github.com/muesli/termenv"
)

// MakeRenderer returns a new lipgloss.Renderer for the given ssh.Session.
// It will use the pty if one is available, otherwise it will use the session
// writer.
func MakeRenderer(s ssh.Session) *lipgloss.Renderer {
var f io.Writer = s
pty, _, ok := s.Pty()
if ok {
f = pty.Slave
}
return lipgloss.NewRenderer(f, termenv.WithColorCache(true))
}

func makeIOOpts(s ssh.Session) []tea.ProgramOption {
pty, _, ok := s.Pty()
if !ok || s.EmulatedPty() {
return []tea.ProgramOption{
tea.WithInput(s),
tea.WithOutput(s),
}
}

return []tea.ProgramOption{
tea.WithInput(pty.Slave),
tea.WithOutput(pty.Slave),
}
}
7 changes: 3 additions & 4 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/lipgloss v0.9.1
github.com/charmbracelet/log v0.3.1
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b
github.com/charmbracelet/wish v0.5.0
github.com/muesli/termenv v0.15.2
github.com/spf13/cobra v1.7.0
Expand All @@ -20,11 +20,10 @@ require (
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/aymanbagabas/go-pty v0.2.1 // indirect
github.com/charmbracelet/keygen v0.5.0 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/creack/pty v1.1.15 // indirect
github.com/creack/pty v1.1.21 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
Expand Down Expand Up @@ -54,7 +53,7 @@ require (
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.14.0 // indirect
Expand Down
24 changes: 16 additions & 8 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-pty v0.2.1 h1:bqnC0bCkr4OAQ1fZdqqriRzGnZTHC71wogGNOPjSNHQ=
github.com/aymanbagabas/go-pty v0.2.1/go.mod h1:1EXZe9k53iaw8QnevpvYenkDazponD+qtcp1s1E7CsQ=
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
Expand All @@ -25,15 +23,25 @@ github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159 h1:JgPRzCH5Uyi2y/Zgb+XmVTnowqRb8tN8TcBCVJdfPYI=
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159/go.mod h1:2B8b7QeevR8cn/lLB3j/Q1qo9FO/7eC1NH9RG+lfii0=
github.com/charmbracelet/ssh v0.0.0-20240108173924-d928369dd254 h1:LQEx1n2MuC2Kzgetq8TW7v2JDXN/+o3BsqloJmKgoiY=
github.com/charmbracelet/ssh v0.0.0-20240108173924-d928369dd254/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108184918-e75da4447a78 h1:OPhgZLveCrbwJqVyPj0+bFMi7ncEdXtvhiq+m8y9kVs=
github.com/charmbracelet/ssh v0.0.0-20240108184918-e75da4447a78/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108190445-72503be29e9d h1:ykEOWspdc2kLCGF10gTJ015n5Q1VZZ5Q59oU+/RBm2s=
github.com/charmbracelet/ssh v0.0.0-20240108190445-72503be29e9d/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108191434-0c40f63bb0ce h1:JnzZdHKxn6p4m2o/VGV/GifrxHWmzN7pQwlPJEMDYAg=
github.com/charmbracelet/ssh v0.0.0-20240108191434-0c40f63bb0ce/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108193150-97a8c4d0f968 h1:J64ERdPQ3kaV2p8y+Lm28SGWOO6o5fEriUJQt3FLTY4=
github.com/charmbracelet/ssh v0.0.0-20240108193150-97a8c4d0f968/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b h1:VPRNMDlAOQeptDNA7u3ci897ApTY7ay/aaImni+4f8U=
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -156,8 +164,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
Expand Down
9 changes: 5 additions & 4 deletions examples/wish-exec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"os/signal"
"syscall"
"time"
Expand Down Expand Up @@ -58,7 +59,8 @@ func main() {
}
}

func teaHandler(s ssh.Session, renderer *lipgloss.Renderer) (tea.Model, []tea.ProgramOption) {
func teaHandler(s ssh.Session) (tea.Model, []tea.ProgramOption) {
renderer := bm.MakeRenderer(s)
m := model{
sess: s,
style: renderer.NewStyle().Foreground(lipgloss.Color("8")),
Expand All @@ -85,9 +87,8 @@ func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
case tea.KeyMsg:
switch msg.String() {
case "e":
pty, _, _ := m.sess.Pty()
c := pty.Command("vim", "file.txt")
cmd := tea.Exec(bm.Command(c), func(err error) tea.Msg {
c := exec.Command("vim", "file.txt")
cmd := tea.ExecProcess(c, func(err error) tea.Msg {
if err != nil {
log.Error("vim finished", "error", err)
}
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/charmbracelet/keygen v0.5.0
github.com/charmbracelet/lipgloss v0.9.1
github.com/charmbracelet/log v0.3.1
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b
github.com/go-git/go-git/v5 v5.11.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/golang-lru/v2 v2.0.7
Expand All @@ -27,7 +27,7 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/creack/pty v1.1.15 // indirect
github.com/creack/pty v1.1.21 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
Expand All @@ -52,7 +52,7 @@ require (
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.14.0 // indirect
Expand Down
22 changes: 16 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,24 @@ github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159 h1:JgPRzCH5Uyi2y/Zgb+XmVTnowqRb8tN8TcBCVJdfPYI=
github.com/charmbracelet/ssh v0.0.0-20240105010023-df1b8bf5b159/go.mod h1:2B8b7QeevR8cn/lLB3j/Q1qo9FO/7eC1NH9RG+lfii0=
github.com/charmbracelet/ssh v0.0.0-20240108173924-d928369dd254 h1:LQEx1n2MuC2Kzgetq8TW7v2JDXN/+o3BsqloJmKgoiY=
github.com/charmbracelet/ssh v0.0.0-20240108173924-d928369dd254/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108184918-e75da4447a78 h1:OPhgZLveCrbwJqVyPj0+bFMi7ncEdXtvhiq+m8y9kVs=
github.com/charmbracelet/ssh v0.0.0-20240108184918-e75da4447a78/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108190445-72503be29e9d h1:ykEOWspdc2kLCGF10gTJ015n5Q1VZZ5Q59oU+/RBm2s=
github.com/charmbracelet/ssh v0.0.0-20240108190445-72503be29e9d/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108191434-0c40f63bb0ce h1:JnzZdHKxn6p4m2o/VGV/GifrxHWmzN7pQwlPJEMDYAg=
github.com/charmbracelet/ssh v0.0.0-20240108191434-0c40f63bb0ce/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108193150-97a8c4d0f968 h1:J64ERdPQ3kaV2p8y+Lm28SGWOO6o5fEriUJQt3FLTY4=
github.com/charmbracelet/ssh v0.0.0-20240108193150-97a8c4d0f968/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b h1:VPRNMDlAOQeptDNA7u3ci897ApTY7ay/aaImni+4f8U=
github.com/charmbracelet/ssh v0.0.0-20240108200552-7ffdd484aa1b/go.mod h1:H/cBXf4vsbGUlCLiR8cNGP7lpv8wuHbgD3GnWJ8quHA=
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/creack/pty v1.1.15 h1:cKRCLMj3Ddm54bKSpemfQ8AtYFBhAI2MPmdys22fBdc=
github.com/creack/pty v1.1.15/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand Down Expand Up @@ -148,8 +158,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
Expand Down
Loading