Repository: nats-io/nsc
Pull request #242 (2019-12-03 15:39:15)

moved to cliprompts/v2
note that for some reason one of the tests triggered a failure as the jwt library was returning an error on a metric rate of `0` which is valid (to disable the metric). This is currently referencing the jwt branch with the fix.

aricart: This fixes #178

Patch:
diff --git a/cmd/addaccount.go b/cmd/addaccount.go
index 5b01aa7..dfcdd28 100644
--- a/cmd/addaccount.go
+++ b/cmd/addaccount.go
@@ -22,7 +22,7 @@ import (
 	"fmt"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -100,17 +100,17 @@ func (p *AddAccountParams) validateAccountNKey(s string) error {
 
 func (p *AddAccountParams) PreInteractive(ctx ActionCtx) error {
 	var err error
-	p.name, err = cli.Prompt("account name", p.name, true, cli.LengthValidator(1))
+	p.name, err = cli.Prompt("account name", p.name, cli.NewLengthValidator(1))
 	if err != nil {
 		return err
 	}
 
-	p.generate, err = cli.PromptYN("generate an account nkey")
+	p.generate, err = cli.Confirm("generate an account nkey", true)
 	if err != nil {
 		return err
 	}
 	if !p.generate {
-		p.keyPath, err = cli.Prompt("path to an account nkey or nkey", p.keyPath, true, p.validateAccountNKey)
+		p.keyPath, err = cli.Prompt("path to an account nkey or nkey", p.keyPath, cli.Val(p.validateAccountNKey))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/addexport.go b/cmd/addexport.go
index 4605dc6..6ff76f7 100644
--- a/cmd/addexport.go
+++ b/cmd/addexport.go
@@ -21,11 +21,10 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/nats-io/nsc/cmd/store"
-
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
+	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
 )
 
@@ -46,7 +45,7 @@ func createAddExportCmd() *cobra.Command {
 	cmd.Flags().BoolVarP(&params.service, "service", "r", false, "export type service")
 	cmd.Flags().BoolVarP(&params.private, "private", "p", false, "private export - requires an activation to access")
 	cmd.Flags().StringVarP(&params.latSubject, "latency", "", "", "latency metrics subject (services only)")
-	cmd.Flags().IntVarP(&params.latSampling, "sampling", "", 0, "latency sampling percentage [0-100] - 0 disables it (services only)")
+	cmd.Flags().IntVarP(&params.latSampling, "sampling", "", 0, "latency sampling percentage [1-100]  (services only)")
 	hm := fmt.Sprintf("response type for the service [%s | %s | %s] (services only)", jwt.ResponseTypeSingleton, jwt.ResponseTypeStream, jwt.ResponseTypeChunked)
 	cmd.Flags().StringVarP(&params.responseType, "response-type", "", jwt.ResponseTypeSingleton, hm)
 	params.AccountContextParams.BindFlags(cmd)
@@ -107,7 +106,7 @@ func (p *AddExportParams) PreInteractive(ctx ActionCtx) error {
 	}
 
 	choices := []string{jwt.Stream.String(), jwt.Service.String()}
-	i, err := cli.PromptChoices("export type", p.export.Type.String(), choices)
+	i, err := cli.Select("export type", p.export.Type.String(), choices)
 	if err != nil {
 		return err
 	}
@@ -127,7 +126,7 @@ func (p *AddExportParams) PreInteractive(ctx ActionCtx) error {
 		return nil
 	}
 
-	p.subject, err = cli.Prompt("subject", p.subject, true, svFn)
+	p.subject, err = cli.Prompt("subject", p.subject, cli.Val(svFn))
 	if err != nil {
 		return err
 	}
@@ -137,51 +136,37 @@ func (p *AddExportParams) PreInteractive(ctx ActionCtx) error {
 		p.export.Name = p.subject
 	}
 
-	p.export.Name, err = cli.Prompt("name", p.export.Name, true, cli.LengthValidator(1))
+	p.export.Name, err = cli.Prompt("name", p.export.Name, cli.NewLengthValidator(1))
 	if err != nil {
 		return err
 	}
 
-	p.export.TokenReq, err = cli.PromptBoolean(fmt.Sprintf("private %s", p.export.Type.String()), p.export.TokenReq)
+	p.export.TokenReq, err = cli.Confirm(fmt.Sprintf("private %s", p.export.Type.String()), p.export.TokenReq)
 	if err != nil {
 		return err
 	}
 
 	if p.export.IsService() {
-		ok, err := cli.PromptBoolean("track service latency", false)
+		ok, err := cli.Confirm("track service latency", false)
 		if err != nil {
 			return err
 		}
 		if ok {
-			_, err = cli.Prompt("sampling percentage [0-100] (0 disables)", "", false, func(s string) error {
-				v, err := strconv.Atoi(s)
-				if err != nil {
-					return err
-				}
-				if v < 0 || v > 100 {
-					return errors.New("sampling must be between 0 and 100 inclusive")
-				}
-				p.latSampling = v
-				return nil
-			})
-			p.latSubject, err = cli.Prompt("latency metrics subject", "", true, func(s string) error {
-				var lat jwt.ServiceLatency
-				lat.Results = jwt.Subject(s)
-				lat.Sampling = p.latSampling
-				var vr jwt.ValidationResults
-				lat.Validate(&vr)
-				if len(vr.Issues) > 0 {
-					return errors.New(vr.Issues[0].Description)
-				}
-				return nil
-			})
+			samp, err := cli.Prompt("sampling percentage [1-100]", "", cli.Val(SamplingValidator))
+			if err != nil {
+				return err
+			}
+			// cannot fail
+			p.latSampling, _ = strconv.Atoi(samp)
+
+			p.latSubject, err = cli.Prompt("latency metrics subject", "", cli.Val(LatencyMetricsSubjectValidator))
 			if err != nil {
 				return err
 			}
 		}
 
 		choices := []string{jwt.ResponseTypeSingleton, jwt.ResponseTypeStream, jwt.ResponseTypeChunked}
-		s, err := cli.PromptChoices("service response type", string(p.export.ResponseType), choices)
+		s, err := cli.Select("service response type", string(p.export.ResponseType), choices)
 		if err != nil {
 			return err
 		}
@@ -195,6 +180,30 @@ func (p *AddExportParams) PreInteractive(ctx ActionCtx) error {
 	return nil
 }
 
+func SamplingValidator(s string) error {
+	v, err := strconv.Atoi(s)
+	if err != nil {
+		return err
+	}
+	if v < 1 || v > 100 {
+		return errors.New("sampling must be between 1 and 100 inclusive")
+	}
+	return nil
+}
+
+func LatencyMetricsSubjectValidator(s string) error {
+	var lat jwt.ServiceLatency
+	// bogus freq just to get a value into the validation
+	lat.Sampling = 100
+	lat.Results = jwt.Subject(s)
+	var vr jwt.ValidationResults
+	lat.Validate(&vr)
+	if len(vr.Issues) > 0 {
+		return errors.New(vr.Issues[0].Description)
+	}
+	return nil
+}
+
 func (p *AddExportParams) Load(ctx ActionCtx) error {
 	var err error
 
@@ -210,7 +219,7 @@ func (p *AddExportParams) Load(ctx ActionCtx) error {
 	return nil
 }
 
-func (p *AddExportParams) PostInteractive(ctx ActionCtx) error {
+func (p *AddExportParams) PostInteractive(_ ActionCtx) error {
 	return nil
 }
 
diff --git a/cmd/addimport.go b/cmd/addimport.go
index 955d946..09f9680 100644
--- a/cmd/addimport.go
+++ b/cmd/addimport.go
@@ -21,11 +21,10 @@ import (
 	"net/url"
 	"strings"
 
-	"github.com/nats-io/nsc/cmd/store"
-
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
+	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
 )
 
@@ -145,7 +144,7 @@ func (p *AddImportParams) addLocalExport(ctx ActionCtx) (bool, error) {
 
 	if len(available) > 0 {
 		// we have some exports that they may want
-		ok, err := cli.PromptYN("pick from locally available exports")
+		ok, err := cli.Confirm("pick from locally available exports", true)
 		if err != nil {
 			return false, err
 		}
@@ -159,7 +158,7 @@ func (p *AddImportParams) addLocalExport(ctx ActionCtx) (bool, error) {
 
 			var c *AccountExportChoice
 			for {
-				idx, err := cli.PromptChoices("select the export", "", labels)
+				idx, err := cli.Select("select the export", "", labels)
 				if err != nil {
 					return false, err
 				}
@@ -191,7 +190,7 @@ func (p *AddImportParams) addLocalExport(ctx ActionCtx) (bool, error) {
 					}
 				}
 				subject = strings.Join(a, ".")
-				subject, err = cli.Prompt("export subject", subject, true, func(s string) error {
+				subject, err = cli.Prompt("export subject", subject, cli.Val(func(s string) error {
 					sub := jwt.Subject(s)
 					if sub.HasWildCards() {
 						return errors.New("services cannot have wildcard subjects")
@@ -202,7 +201,7 @@ func (p *AddImportParams) addLocalExport(ctx ActionCtx) (bool, error) {
 						return errors.New(vr.Issues[0].Description)
 					}
 					return nil
-				})
+				}))
 			}
 			p.remote = subject
 			p.service = c.Selection.IsService()
@@ -254,7 +253,7 @@ func (p *AddImportParams) generateToken(ctx ActionCtx, c *AccountExportChoice) e
 
 func (p *AddImportParams) addManualExport(ctx ActionCtx) error {
 	var err error
-	p.public, err = cli.PromptYN("is the export public?")
+	p.public, err = cli.Confirm("is the export public?", true)
 	if err != nil {
 		return err
 	}
@@ -262,7 +261,7 @@ func (p *AddImportParams) addManualExport(ctx ActionCtx) error {
 		if err := p.srcAccount.Edit(); err != nil {
 			return err
 		}
-		p.remote, err = cli.Prompt("remote subject", p.remote, true, func(v string) error {
+		p.remote, err = cli.Prompt("remote subject", p.remote, cli.Val(func(v string) error {
 			t := jwt.Subject(v)
 			var vr jwt.ValidationResults
 			t.Validate(&vr)
@@ -270,20 +269,20 @@ func (p *AddImportParams) addManualExport(ctx ActionCtx) error {
 				return errors.New(vr.Issues[0].Description)
 			}
 			return nil
-		})
-		p.service, err = cli.PromptYN("is import a service")
+		}))
+		p.service, err = cli.Confirm("is import a service", true)
 		if err != nil {
 			return err
 		}
 	} else {
-		p.tokenSrc, err = cli.Prompt("token path or url", p.tokenSrc, true, func(s string) error {
+		p.tokenSrc, err = cli.Prompt("token path or url", p.tokenSrc, cli.Val(func(s string) error {
 			p.tokenSrc = s
 			p.token, err = p.loadImport()
 			if err != nil {
 				return err
 			}
 			return nil
-		})
+		}))
 		if err != nil {
 			return err
 		}
@@ -407,7 +406,7 @@ func (p *AddImportParams) PostInteractive(ctx ActionCtx) error {
 		p.name = p.remote
 	}
 
-	p.name, err = cli.Prompt("name", p.name, true, cli.LengthValidator(1))
+	p.name, err = cli.Prompt("name", p.name, cli.NewLengthValidator(1))
 	if err != nil {
 		return err
 	}
@@ -422,8 +421,7 @@ func (p *AddImportParams) PostInteractive(ctx ActionCtx) error {
 		m = "local subject"
 		prefix = p.local
 	}
-
-	p.local, err = cli.Prompt(m, prefix, true, func(s string) error {
+	p.local, err = cli.Prompt(m, prefix, cli.Val(func(s string) error {
 		if !p.service && s == "" {
 			return nil
 		}
@@ -443,7 +441,7 @@ func (p *AddImportParams) PostInteractive(ctx ActionCtx) error {
 		}
 
 		return nil
-	})
+	}))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/addoperator.go b/cmd/addoperator.go
index 8e28ae3..9531cf7 100644
--- a/cmd/addoperator.go
+++ b/cmd/addoperator.go
@@ -21,7 +21,7 @@ import (
 	"net/url"
 	"os"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -79,12 +79,12 @@ func (p *AddOperatorParams) SetDefaults(ctx ActionCtx) error {
 func (p *AddOperatorParams) PreInteractive(ctx ActionCtx) error {
 	var err error
 
-	ok, err := cli.PromptYN("import operator from a JWT")
+	ok, err := cli.Confirm("import operator from a JWT", true)
 	if err != nil {
 		return err
 	}
 	if ok {
-		p.jwtPath, err = cli.Prompt("path or url for operator jwt", p.jwtPath, true, func(v string) error {
+		p.jwtPath, err = cli.Prompt("path or url for operator jwt", p.jwtPath, cli.Val(func(v string) error {
 			// is it is an URL or path
 			pv := cli.PathOrURLValidator()
 			if perr := pv(v); perr != nil {
@@ -98,12 +98,12 @@ func (p *AddOperatorParams) PreInteractive(ctx ActionCtx) error {
 				return perr
 			}
 			return nil
-		})
+		}))
 		if err != nil {
 			return err
 		}
 	} else {
-		p.name, err = cli.Prompt("operator name", p.name, true, cli.LengthValidator(1))
+		p.name, err = cli.Prompt("operator name", p.name, cli.NewLengthValidator(1))
 		if err != nil {
 			return err
 		}
@@ -193,12 +193,12 @@ func (p *AddOperatorParams) PostInteractive(ctx ActionCtx) error {
 	}
 
 	if p.signerKP == nil {
-		p.generate, err = cli.PromptYN("generate an operator nkey")
+		p.generate, err = cli.Confirm("generate an operator nkey", true)
 		if err != nil {
 			return err
 		}
 		if !p.generate {
-			p.keyPath, err = cli.Prompt("path to an operator nkey or nkey", p.keyPath, true, p.validateOperatorNKey)
+			p.keyPath, err = cli.Prompt("path to an operator nkey or nkey", p.keyPath, cli.Val(p.validateOperatorNKey))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/adduser.go b/cmd/adduser.go
index 069a6c0..36ef743 100644
--- a/cmd/adduser.go
+++ b/cmd/adduser.go
@@ -23,7 +23,7 @@ import (
 	"strings"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -297,20 +297,20 @@ func (p *ResponsePermsParams) Edit(hasPerm bool) error {
 	if hasPerm {
 		verb = "Edit"
 	}
-	ok, err := cli.PromptBoolean(fmt.Sprintf("%s response permissions?", verb), false)
+	ok, err := cli.Confirm(fmt.Sprintf("%s response permissions?", verb), false)
 	if err != nil {
 		return err
 	}
 	if ok {
 		if hasPerm {
-			p.rmResp, err = cli.PromptBoolean("delete response permissions", p.rmResp)
+			p.rmResp, err = cli.Confirm("delete response permissions", p.rmResp)
 			if err != nil {
 				return err
 			}
 		}
 		if !p.rmResp {
-			p.respMax, err = cli.Prompt("Number of max responses", p.respMax, true, p.maxResponseValidator)
-			p.respTTL, err = cli.Prompt("Response Permission TTL", p.respTTL, true, p.ttlValidator)
+			p.respMax, err = cli.Prompt("Number of max responses", p.respMax, cli.Val(p.maxResponseValidator))
+			p.respTTL, err = cli.Prompt("Response Permission TTL", p.respTTL, cli.Val(p.ttlValidator))
 		}
 	}
 	return nil
diff --git a/cmd/common.go b/cmd/common.go
index 85ca773..2d09756 100644
--- a/cmd/common.go
+++ b/cmd/common.go
@@ -33,7 +33,7 @@ import (
 
 	"github.com/dustin/go-humanize"
 	"github.com/mitchellh/go-homedir"
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
diff --git a/cmd/dataparams.go b/cmd/dataparams.go
index b27c4dd..1f177aa 100644
--- a/cmd/dataparams.go
+++ b/cmd/dataparams.go
@@ -16,7 +16,7 @@
 package cmd
 
 import (
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 )
 
 type DataParams struct {
@@ -32,10 +32,10 @@ func (e *DataParams) Valid() error {
 func (e *DataParams) Edit(prompt string) error {
 	var err error
 	var nv int64
-	sv, err := cli.Prompt(prompt, e.Value, true, func(s string) error {
+	sv, err := cli.Prompt(prompt, e.Value, cli.Val(func(s string) error {
 		nv, err = ParseNumber(s)
 		return err
-	})
+	}))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/deleteexport.go b/cmd/deleteexport.go
index 205b428..2c481ce 100644
--- a/cmd/deleteexport.go
+++ b/cmd/deleteexport.go
@@ -18,7 +18,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -107,7 +107,7 @@ func (p *DeleteExportParams) PostInteractive(ctx ActionCtx) error {
 	}
 	labels := AccountExportChoices(choices).String()
 
-	p.index, err = cli.PromptChoices("select export to delete", "", labels)
+	p.index, err = cli.Select("select export to delete", "", labels)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/deleteimport.go b/cmd/deleteimport.go
index 47b0950..9bdb5f9 100644
--- a/cmd/deleteimport.go
+++ b/cmd/deleteimport.go
@@ -19,7 +19,7 @@ import (
 	"fmt"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -137,7 +137,7 @@ func (p *DeleteImportParams) PostInteractive(ctx ActionCtx) error {
 		return err
 	}
 	labels := choices.String()
-	p.index, err = cli.PromptChoices("select import to delete", "", labels)
+	p.index, err = cli.Select("select import to delete", "", labels)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/deleteuser.go b/cmd/deleteuser.go
index 28d6142..433f0a8 100644
--- a/cmd/deleteuser.go
+++ b/cmd/deleteuser.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"os"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
@@ -86,7 +86,7 @@ func (p *DeleteUserParams) PreInteractive(ctx ActionCtx) error {
 		return fmt.Errorf("account %q doesn't have any users - add one first", p.AccountContextParams.Name)
 	}
 	if len(users) > 0 {
-		sel, err := cli.PromptMultipleChoices("select users", users)
+		sel, err := cli.MultiSelect("select users", users)
 		if err != nil {
 			return err
 		}
@@ -100,7 +100,7 @@ func (p *DeleteUserParams) PreInteractive(ctx ActionCtx) error {
 	if len(p.names) > 1 {
 		m = "revoke users before deleting"
 	}
-	p.revoke, err = cli.PromptBoolean(m, false)
+	p.revoke, err = cli.Confirm(m, false)
 	if err != nil {
 		return err
 	}
@@ -109,7 +109,7 @@ func (p *DeleteUserParams) PreInteractive(ctx ActionCtx) error {
 	if len(p.names) > 1 {
 		m = "delete associated nkeys"
 	}
-	p.rmNKey, err = cli.PromptBoolean(m, false)
+	p.rmNKey, err = cli.Confirm(m, false)
 	if err != nil {
 		return err
 	}
@@ -118,7 +118,7 @@ func (p *DeleteUserParams) PreInteractive(ctx ActionCtx) error {
 	if len(p.names) > 1 {
 		m = "delete associated creds files"
 	}
-	p.rmCreds, err = cli.PromptBoolean(m, false)
+	p.rmCreds, err = cli.Confirm(m, false)
 	if err != nil {
 		return err
 	}
@@ -137,7 +137,7 @@ func (p *DeleteUserParams) PostInteractive(ctx ActionCtx) error {
 	if len(p.names) > 1 {
 		m = "deleting users, nkeys or creds files cannot be undone - continue"
 	}
-	ok, err := cli.PromptBoolean(m, false)
+	ok, err := cli.Confirm(m, false)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/describejwt.go b/cmd/describejwt.go
index efd7ec8..88fe8d3 100644
--- a/cmd/describejwt.go
+++ b/cmd/describejwt.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/nats-io/nsc/cmd/store"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/spf13/cobra"
 )
@@ -65,9 +65,7 @@ func (p *DescribeFile) SetDefaults(ctx ActionCtx) error {
 
 func (p *DescribeFile) PreInteractive(ctx ActionCtx) error {
 	var err error
-	p.file, err = cli.Prompt("token file or url", p.file, true, func(s string) error {
-		return nil
-	})
+	p.file, err = cli.Prompt("token file or url", p.file)
 	return err
 }
 
diff --git a/cmd/editexport.go b/cmd/editexport.go
index 3a86e81..59d3db0 100644
--- a/cmd/editexport.go
+++ b/cmd/editexport.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"strconv"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -45,9 +45,10 @@ func createEditExportCmd() *cobra.Command {
 	cmd.Flags().BoolVarP(&params.private, "private", "p", false, "private export - requires an activation to access")
 	cmd.Flags().StringVarP(&params.latSubject, "latency", "", "", "latency metrics subject (services only)")
 	cmd.Flags().IntVarP(&params.latSampling, "sampling", "", 0, "latency sampling percentage [0-100] - 0 disables it (services only)")
+	cmd.Flags().BoolVarP(&params.rmLatencySampling, "rm-latency-sampling", "", false, "remove latency sampling")
 
 	hm := fmt.Sprintf("response type for the service [%s | %s | %s] (services only)", jwt.ResponseTypeSingleton, jwt.ResponseTypeStream, jwt.ResponseTypeChunked)
-	cmd.Flags().StringVarP(&params.responseType, "response-type", "", string(jwt.ResponseTypeSingleton), hm)
+	cmd.Flags().StringVarP(&params.responseType, "response-type", "", jwt.ResponseTypeSingleton, hm)
 	params.AccountContextParams.BindFlags(cmd)
 
 	return cmd
@@ -64,12 +65,13 @@ type EditExportParams struct {
 	index   int
 	subject string
 
-	name         string
-	latSampling  int
-	latSubject   string
-	service      bool
-	private      bool
-	responseType string
+	name              string
+	latSampling       int
+	latSubject        string
+	service           bool
+	private           bool
+	responseType      string
+	rmLatencySampling bool
 }
 
 func (p *EditExportParams) SetDefaults(ctx ActionCtx) error {
@@ -142,7 +144,7 @@ func (p *EditExportParams) PostInteractive(ctx ActionCtx) error {
 	if index == -1 {
 		index = 0
 	}
-	p.index, err = cli.PromptChoices("select export to edit", labels[index], labels)
+	p.index, err = cli.Select("select export to edit", labels[index], labels)
 	if err != nil {
 		return err
 	}
@@ -154,7 +156,7 @@ func (p *EditExportParams) PostInteractive(ctx ActionCtx) error {
 	if sel.Type == jwt.Service {
 		k = kinds[1]
 	}
-	i, err := cli.PromptChoices("export type", k, kinds)
+	i, err := cli.Select("export type", k, kinds)
 	if err != nil {
 		return err
 	}
@@ -175,7 +177,7 @@ func (p *EditExportParams) PostInteractive(ctx ActionCtx) error {
 		return nil
 	}
 
-	p.subject, err = cli.Prompt("subject", string(sel.Subject), true, svFn)
+	p.subject, err = cli.Prompt("subject", string(sel.Subject), cli.Val(svFn))
 	if err != nil {
 		return err
 	}
@@ -183,18 +185,18 @@ func (p *EditExportParams) PostInteractive(ctx ActionCtx) error {
 	if p.name == "" {
 		p.name = sel.Name
 	}
-	p.name, err = cli.Prompt("name", p.name, true, cli.LengthValidator(1))
+	p.name, err = cli.Prompt("name", p.name, cli.NewLengthValidator(1))
 	if err != nil {
 		return err
 	}
 
-	p.private, err = cli.PromptBoolean(fmt.Sprintf("private %s", k), sel.TokenReq)
+	p.private, err = cli.Confirm(fmt.Sprintf("private %s", k), sel.TokenReq)
 	if err != nil {
 		return err
 	}
 
 	if p.service {
-		ok, err := cli.PromptBoolean("track service latency", false)
+		ok, err := cli.Confirm("track service latency", false)
 		if err != nil {
 			return err
 		}
@@ -205,35 +207,23 @@ func (p *EditExportParams) PostInteractive(ctx ActionCtx) error {
 				cls = sel.Latency.Sampling
 				results = sel.Latency.Results
 			}
-			_, err = cli.Prompt("sampling percentage [0-100] (0 disables)", strconv.Itoa(cls), false, func(s string) error {
-				v, err := strconv.Atoi(s)
-				if err != nil {
-					return err
-				}
-				if v < 0 || v > 100 {
-					return errors.New("sampling must be between 0 and 100 inclusive")
-				}
-				p.latSampling = v
-				return nil
-			})
-			p.latSubject, err = cli.Prompt("latency metrics subject", string(results), true, func(s string) error {
-				var lat jwt.ServiceLatency
-				lat.Results = jwt.Subject(s)
-				lat.Sampling = p.latSampling
-				var vr jwt.ValidationResults
-				lat.Validate(&vr)
-				if len(vr.Issues) > 0 {
-					return errors.New(vr.Issues[0].Description)
-				}
-				return nil
-			})
+			samp, err := cli.Prompt("sampling percentage [1-100]", fmt.Sprintf("%d", cls), cli.Val(SamplingValidator))
 			if err != nil {
 				return err
 			}
+			// cannot fail
+			p.latSampling, _ = strconv.Atoi(samp)
+
+			p.latSubject, err = cli.Prompt("latency metrics subject", string(results), cli.Val(LatencyMetricsSubjectValidator))
+			if err != nil {
+				return err
+			}
+		} else {
+			p.rmLatencySampling = true
 		}
 
 		choices := []string{jwt.ResponseTypeSingleton, jwt.ResponseTypeStream, jwt.ResponseTypeChunked}
-		s, err := cli.PromptChoices("service response type", string(p.responseType), choices)
+		s, err := cli.Select("service response type", p.responseType, choices)
 		if err != nil {
 			return err
 		}
@@ -307,6 +297,11 @@ func (p *EditExportParams) syncOptions(ctx ActionCtx) {
 	if !(cmd.Flag("sampling").Changed) {
 		p.latSampling = sampling
 	}
+
+	if !(cmd.Flag("response-type").Changed) {
+		p.responseType = string(old.ResponseType)
+	}
+
 }
 
 func (p *EditExportParams) Run(ctx ActionCtx) (store.Status, error) {
@@ -341,25 +336,39 @@ func (p *EditExportParams) Run(ctx ActionCtx) (store.Status, error) {
 	}
 
 	if export.Type == jwt.Service {
-		oldSampling := 0
-		oldReport := jwt.Subject("")
-		if old.Latency != nil {
-			oldSampling = old.Latency.Sampling
-			oldReport = old.Latency.Results
+		// old response type may be blank
+		if old.ResponseType == "" {
+			old.ResponseType = jwt.ResponseTypeSingleton
 		}
-		if p.latSubject != "" {
-			export.Latency = &jwt.ServiceLatency{Results: jwt.Subject(p.latSubject), Sampling: p.latSampling}
-			if oldSampling != export.Latency.Sampling {
-				r.AddOK("changed service latency to %d%%", export.Latency.Sampling)
+
+		if p.rmLatencySampling {
+			export.Latency = nil
+			if old.Latency != nil {
+				r.AddOK("removed latency tracking")
+			} else {
+				r.AddOK("no need to remove latency tracking as it was not set")
+			}
+		} else {
+			oldSampling := 0
+			oldReport := jwt.Subject("")
+			if old.Latency != nil {
+				oldSampling = old.Latency.Sampling
+				oldReport = old.Latency.Results
 			}
-			if oldReport != export.Latency.Results {
-				r.AddOK("changed service latency subject to %s", export.Latency.Results)
-				r.AddWarning("changed latency subject will break consumers of the report")
+			if p.latSubject != "" {
+				export.Latency = &jwt.ServiceLatency{Results: jwt.Subject(p.latSubject), Sampling: p.latSampling}
+				if oldSampling != export.Latency.Sampling {
+					r.AddOK("changed service latency to %d%%", export.Latency.Sampling)
+				}
+				if oldReport != "" && oldReport != export.Latency.Results {
+					r.AddOK("changed service latency subject to %s", export.Latency.Results)
+					r.AddWarning("changed latency subject will break consumers of the report")
+				}
 			}
 		}
 
 		rt := jwt.ResponseType(p.responseType)
-		if export.ResponseType != rt {
+		if old.ResponseType != rt {
 			export.ResponseType = rt
 			r.AddOK("changed response type to %s", p.responseType)
 		}
diff --git a/cmd/editoperator.go b/cmd/editoperator.go
index 76a7afc..c217db8 100644
--- a/cmd/editoperator.go
+++ b/cmd/editoperator.go
@@ -19,7 +19,7 @@ import (
 	"fmt"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -116,25 +116,25 @@ func (p *EditOperatorParams) PostInteractive(ctx ActionCtx) error {
 	if err = p.GenericClaimsParams.Edit(p.claim.Tags); err != nil {
 		return err
 	}
-	p.asu, err = cli.Prompt("account jwt server url", p.asu, true, nil)
+	p.asu, err = cli.Prompt("account jwt server url", p.asu)
 	if err != nil {
 		return err
 	}
 	p.asu = strings.TrimSpace(p.asu)
 
-	ok, err := cli.PromptYN("add a service url")
+	ok, err := cli.Confirm("add a service url", true)
 	if err != nil {
 		return err
 	}
 	if ok {
 		for {
-			v, err := cli.Prompt("operator service url", "", true, jwt.ValidateOperatorServiceURL)
+			v, err := cli.Prompt("operator service url", "", cli.Val(jwt.ValidateOperatorServiceURL))
 			if err != nil {
 				return err
 			}
 			// the list will prune empty urls
 			p.serviceURLs = append(p.serviceURLs, v)
-			ok, err := cli.PromptYN("add another service url")
+			ok, err := cli.Confirm("add another service url", true)
 			if err != nil {
 				return err
 			}
@@ -144,12 +144,12 @@ func (p *EditOperatorParams) PostInteractive(ctx ActionCtx) error {
 		}
 	}
 	if len(p.claim.OperatorServiceURLs) > 0 {
-		ok, err = cli.PromptYN("remove any service urls")
+		ok, err = cli.Confirm("remove any service urls", true)
 		if err != nil {
 			return err
 		}
 		if ok {
-			idx, err := cli.PromptMultipleChoices("select service urls to remove", p.claim.OperatorServiceURLs)
+			idx, err := cli.MultiSelect("select service urls to remove", p.claim.OperatorServiceURLs)
 			if err != nil {
 				return err
 			}
diff --git a/cmd/entity.go b/cmd/entity.go
index ff74681..05ee70e 100644
--- a/cmd/entity.go
+++ b/cmd/entity.go
@@ -20,7 +20,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -116,17 +116,17 @@ func (c *Entity) Edit() error {
 	var err error
 	label := c.kind.String()
 
-	c.name, err = cli.Prompt(fmt.Sprintf("%s name", label), c.name, true, cli.LengthValidator(1))
+	c.name, err = cli.Prompt(fmt.Sprintf("%s name", label), c.name, cli.NewLengthValidator(1))
 	if err != nil {
 		return err
 	}
 
-	ok, err := cli.PromptYN(fmt.Sprintf("generate an %s nkey", label))
+	ok, err := cli.Confirm(fmt.Sprintf("generate an %s nkey", label), true)
 	if err != nil {
 		return err
 	}
 	if !ok {
-		c.keyPath, err = cli.Prompt(fmt.Sprintf("path to an %s nkey or nkey", label), c.keyPath, true, c.ValidateNKey())
+		c.keyPath, err = cli.Prompt(fmt.Sprintf("path to an %s nkey or nkey", label), c.keyPath, cli.Val(c.ValidateNKey()))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/generateactivation.go b/cmd/generateactivation.go
index c61f75a..01def46 100644
--- a/cmd/generateactivation.go
+++ b/cmd/generateactivation.go
@@ -23,7 +23,7 @@ import (
 	"net/url"
 	"path"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -127,7 +127,7 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
 	if len(labels) == 1 {
 		choice = labels[0]
 	}
-	i, err := cli.PromptChoices("select the export", choice, labels)
+	i, err := cli.Select("select the export", choice, labels)
 	if err != nil {
 		return err
 	}
@@ -138,7 +138,7 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
 	}
 	kind := p.export.Type
 
-	p.subject, err = cli.Prompt("subject", p.subject, true, func(v string) error {
+	p.subject, err = cli.Prompt("subject", p.subject, cli.Val(func(v string) error {
 		t := jwt.Subject(v)
 		var vr jwt.ValidationResults
 		t.Validate(&vr)
@@ -152,7 +152,7 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
 			return fmt.Errorf("%q doesn't contain %q", string(p.export.Subject), string(t))
 		}
 		return nil
-	})
+	}))
 	if err != nil {
 		return err
 	}
@@ -173,7 +173,7 @@ func (p *GenerateActivationParams) PostInteractive(ctx ActionCtx) error {
 	}
 	if oc.AccountServerURL != "" {
 		m := fmt.Sprintf("push the activation to %q", oc.AccountServerURL)
-		p.push, err = cli.PromptBoolean(m, false)
+		p.push, err = cli.Confirm(m, false)
 	}
 
 	return nil
diff --git a/cmd/genericclaimparams.go b/cmd/genericclaimparams.go
index b36d02c..c4e9f05 100644
--- a/cmd/genericclaimparams.go
+++ b/cmd/genericclaimparams.go
@@ -22,7 +22,7 @@ import (
 	"sort"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nsc/cmd/store"
 )
@@ -56,14 +56,14 @@ func (sp *GenericClaimsParams) add(label string, current []string) ([]string, er
 			m = fmt.Sprintf("add another %s", label)
 		}
 		first = false
-		ok, err := cli.PromptBoolean(m, false)
+		ok, err := cli.Confirm(m, false)
 		if err != nil {
 			return nil, err
 		}
 		if !ok {
 			break
 		}
-		v, err := cli.Prompt(fmt.Sprintf("enter a %s", label), "", true, nil)
+		v, err := cli.Prompt(fmt.Sprintf("enter a %s", label), "")
 		if err != nil {
 			return nil, err
 		}
@@ -77,12 +77,12 @@ func (sp *GenericClaimsParams) remove(label string, values []string) ([]string,
 	if len(values) == 0 {
 		return nil, nil
 	}
-	ok, err := cli.PromptBoolean("remove tags", false)
+	ok, err := cli.Confirm("remove tags", false)
 	if err != nil {
 		return nil, err
 	}
 	if ok {
-		idx, err := cli.PromptMultipleChoices(fmt.Sprintf("select %s to remove", label), values)
+		idx, err := cli.MultiSelect(fmt.Sprintf("select %s to remove", label), values)
 		if err != nil {
 			return nil, err
 		}
diff --git a/cmd/init.go b/cmd/init.go
index b214df9..65a0c17 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -104,10 +104,10 @@ func (p *InitCmdParams) init(cmd *cobra.Command) error {
 
 	tc := GetConfig()
 	if p.Prompt {
-		p.Dir, err = cli.Prompt("enter a configuration directory", tc.StoreRoot, true, func(v string) error {
+		p.Dir, err = cli.Prompt("enter a configuration directory", tc.StoreRoot, cli.Val(func(v string) error {
 			_, err := Expand(v)
 			return err
-		})
+		}))
 	}
 	p.Dir, err = Expand(p.Dir)
 	if err != nil {
@@ -141,7 +141,7 @@ func (p *InitCmdParams) resolveOperator() error {
 		if defsel == "" {
 			defsel = "Create Operator"
 		}
-		sel, err := cli.PromptChoices("Select an operator", defsel, choices)
+		sel, err := cli.Select("Select an operator", defsel, choices)
 		if err != nil {
 			return err
 		}
@@ -151,7 +151,7 @@ func (p *InitCmdParams) resolveOperator() error {
 		case local:
 			p.CreateOperator = true
 		case custom:
-			p.OperatorJwtURL, err = cli.Prompt("Operator URL", "", true, cli.URLValidator("http", "https"))
+			p.OperatorJwtURL, err = cli.Prompt("Operator URL", "", cli.NewURLValidator("http", "https"))
 			if err != nil {
 				return err
 			}
@@ -163,7 +163,7 @@ func (p *InitCmdParams) resolveOperator() error {
 		if p.CreateOperator {
 			q = "name your operator, account and user"
 		}
-		p.Name, err = cli.Prompt(q, p.Name, true, OperatorNameValidator)
+		p.Name, err = cli.Prompt(q, p.Name, cli.Val(OperatorNameValidator))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/list.go b/cmd/list.go
index ff78404..4aabfdf 100644
--- a/cmd/list.go
+++ b/cmd/list.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"sort"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
diff --git a/cmd/listeditor.go b/cmd/listeditor.go
index 8d950d1..fadb4cc 100644
--- a/cmd/listeditor.go
+++ b/cmd/listeditor.go
@@ -18,7 +18,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 )
 
 type ListEditorParam struct {
@@ -53,21 +53,21 @@ func (e *ListEditorParam) Edit() error {
 		e.AddMessage = fmt.Sprintf("add %s", e.FlagName)
 	}
 	for i, v := range e.Values {
-		sv, err := cli.Prompt(e.PromptMessage, v, true, e.ValidatorFn)
+		sv, err := cli.Prompt(e.PromptMessage, v, cli.Val(e.ValidatorFn))
 		if err != nil {
 			return err
 		}
 		e.Values[i] = sv
 	}
 	for {
-		ok, err := cli.PromptYN(e.AddMessage)
+		ok, err := cli.Confirm(e.AddMessage, true)
 		if err != nil {
 			return err
 		}
 		if !ok {
 			break
 		}
-		sv, err := cli.Prompt(e.PromptMessage, "", true, e.ValidatorFn)
+		sv, err := cli.Prompt(e.PromptMessage, "", cli.Val(e.ValidatorFn))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/migrate.go b/cmd/migrate.go
index 73738b2..9d2e081 100644
--- a/cmd/migrate.go
+++ b/cmd/migrate.go
@@ -23,7 +23,7 @@ import (
 	"path/filepath"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -71,20 +71,20 @@ func (p *MigrateCmdParams) SetDefaults(ctx ActionCtx) error {
 }
 
 func (p *MigrateCmdParams) PreInteractive(ctx ActionCtx) error {
-	ok, err := cli.PromptYN("migrate all accounts under a particular operator")
+	ok, err := cli.Confirm("migrate all accounts under a particular operator", true)
 	if err != nil {
 		return err
 	}
 	if ok {
-		p.storeDir, err = cli.Prompt("specify the directory for the operator", "", true, func(v string) error {
+		p.storeDir, err = cli.Prompt("specify the directory for the operator", "", cli.Val(func(v string) error {
 			_, err := store.LoadStore(v)
 			return err
-		})
+		}))
 		if err != nil {
 			return err
 		}
 	} else {
-		p.url, err = cli.Prompt("account jwt url/or path ", p.url, true, func(v string) error {
+		p.url, err = cli.Prompt("account jwt url/or path ", p.url, cli.Val(func(v string) error {
 			// we expect either a file or url
 			if u, err := url.Parse(v); err == nil && u.Scheme != "" {
 				return nil
@@ -95,7 +95,7 @@ func (p *MigrateCmdParams) PreInteractive(ctx ActionCtx) error {
 			}
 			_, err = os.Stat(v)
 			return err
-		})
+		}))
 	}
 	return nil
 }
@@ -226,7 +226,7 @@ func (j *MigrateJob) PostInteractive(ctx ActionCtx) {
 		}
 		j.overwrite = aac.Subject == j.claim.Subject
 		if !j.overwrite {
-			j.overwrite, err = cli.PromptBoolean("account %q already exists under the current operator, replace it", false)
+			j.overwrite, err = cli.Confirm("account %q already exists under the current operator, replace it", false)
 			if err != nil {
 				j.status = store.ErrorStatus(fmt.Sprintf("%v", err))
 				return
diff --git a/cmd/numberparams.go b/cmd/numberparams.go
index a9205c0..ff1f39b 100644
--- a/cmd/numberparams.go
+++ b/cmd/numberparams.go
@@ -18,7 +18,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 )
 
 type NumberParams struct {
@@ -34,10 +34,10 @@ func (e *NumberParams) Edit(prompt string) error {
 	var err error
 	var nv int64
 	sv := fmt.Sprintf("%d", e.NumberValue)
-	_, err = cli.Prompt(prompt, sv, true, func(s string) error {
+	_, err = cli.Prompt(prompt, sv, cli.Val(func(s string) error {
 		nv, err = ParseNumber(s)
 		return err
-	})
+	}))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/pubkeyparams.go b/cmd/pubkeyparams.go
index 87c3a97..4efe8dd 100644
--- a/cmd/pubkeyparams.go
+++ b/cmd/pubkeyparams.go
@@ -18,7 +18,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
@@ -53,7 +53,7 @@ func (e *PubKeyParams) Valid() error {
 }
 
 func (e *PubKeyParams) Edit() error {
-	sv, err := cli.Prompt(fmt.Sprintf("%s public key", e.flagName), e.publicKey, true, e.valid)
+	sv, err := cli.Prompt(fmt.Sprintf("%s public key", e.flagName), e.publicKey, cli.Val(e.valid))
 	if err != nil {
 		return err
 	}
diff --git a/cmd/pull.go b/cmd/pull.go
index 10a73d7..f7bd6e3 100644
--- a/cmd/pull.go
+++ b/cmd/pull.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/nats-io/nsc/cmd/store"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/spf13/cobra"
 )
@@ -119,7 +119,7 @@ func (p *PullParams) SetDefaults(ctx ActionCtx) error {
 func (p *PullParams) PreInteractive(ctx ActionCtx) error {
 	var err error
 	tc := GetConfig()
-	p.All, err = cli.PromptYN(fmt.Sprintf("pull operator %q and all accounts", tc.Operator))
+	p.All, err = cli.Confirm(fmt.Sprintf("pull operator %q and all accounts", tc.Operator), true)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/push.go b/cmd/push.go
index d9799f5..014abdd 100644
--- a/cmd/push.go
+++ b/cmd/push.go
@@ -21,7 +21,7 @@ import (
 	"net/url"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
@@ -129,7 +129,7 @@ func (p *PushCmdParams) PreInteractive(ctx ActionCtx) error {
 			return err
 		}
 	}
-	p.ASU, err = cli.Prompt("Account Server URL", p.ASU, true, p.validURL)
+	p.ASU, err = cli.Prompt("Account Server URL", p.ASU, cli.Val(p.validURL))
 	return err
 }
 
diff --git a/cmd/revoke_clearactivation.go b/cmd/revoke_clearactivation.go
index 3f32eec..12fcee1 100644
--- a/cmd/revoke_clearactivation.go
+++ b/cmd/revoke_clearactivation.go
@@ -19,7 +19,7 @@ import (
 	"fmt"
 	"strconv"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -91,7 +91,7 @@ func (p *RevokeClearActivationParams) PreInteractive(ctx ActionCtx) error {
 		return err
 	}
 
-	p.service, err = cli.PromptBoolean("is service", p.service)
+	p.service, err = cli.Confirm("is service", p.service)
 	if err != nil {
 		return err
 	}
@@ -147,7 +147,7 @@ func (p *RevokeClearActivationParams) PostInteractive(ctx ActionCtx) error {
 		kind = jwt.Service
 	}
 
-	i, err := cli.PromptChoices(fmt.Sprintf("select %s export", kind.String()), "", choices)
+	i, err := cli.Select(fmt.Sprintf("select %s export", kind.String()), "", choices)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/revoke_listactivation.go b/cmd/revoke_listactivation.go
index 8a909e7..03c70ed 100644
--- a/cmd/revoke_listactivation.go
+++ b/cmd/revoke_listactivation.go
@@ -20,7 +20,7 @@ import (
 	"strconv"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -88,7 +88,7 @@ func (p *RevokeListActivationParams) PreInteractive(ctx ActionCtx) error {
 		return err
 	}
 
-	p.service, err = cli.PromptBoolean("is service", p.service)
+	p.service, err = cli.Confirm("is service", p.service)
 	if err != nil {
 		return err
 	}
@@ -170,7 +170,7 @@ func (p *RevokeListActivationParams) PostInteractive(ctx ActionCtx) error {
 		kind = jwt.Service
 	}
 
-	i, err := cli.PromptChoices(fmt.Sprintf("select %s export", kind.String()), "", choices)
+	i, err := cli.Select(fmt.Sprintf("select %s export", kind.String()), "", choices)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/revokeactivation.go b/cmd/revokeactivation.go
index 9aafc5c..cd424c4 100644
--- a/cmd/revokeactivation.go
+++ b/cmd/revokeactivation.go
@@ -20,7 +20,7 @@ import (
 	"strconv"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -94,7 +94,7 @@ func (p *RevokeActivationParams) PreInteractive(ctx ActionCtx) error {
 		return err
 	}
 
-	p.service, err = cli.PromptBoolean("is service", p.service)
+	p.service, err = cli.Confirm("is service", p.service)
 	if err != nil {
 		return err
 	}
@@ -180,7 +180,7 @@ func (p *RevokeActivationParams) PostInteractive(ctx ActionCtx) error {
 		kind = jwt.Service
 	}
 
-	i, err := cli.PromptChoices(fmt.Sprintf("select %s export", kind.String()), "", choices)
+	i, err := cli.Select(fmt.Sprintf("select %s export", kind.String()), "", choices)
 	if err != nil {
 		return err
 	}
@@ -195,7 +195,7 @@ func (p *RevokeActivationParams) PostInteractive(ctx ActionCtx) error {
 
 	if p.at == 0 {
 		at := fmt.Sprintf("%d", p.at)
-		at, err = cli.Prompt("revoke all credentials created before (0 is now)", at, true, p.canParse)
+		at, err = cli.Prompt("revoke all credentials created before (0 is now)", at, cli.Val(p.canParse))
 		p.at, err = strconv.Atoi(at)
 	}
 
diff --git a/cmd/revokeuser.go b/cmd/revokeuser.go
index 7ad94f9..2a2f7b7 100644
--- a/cmd/revokeuser.go
+++ b/cmd/revokeuser.go
@@ -20,7 +20,7 @@ import (
 	"strconv"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
@@ -88,7 +88,7 @@ func (p *RevokeUserParams) PreInteractive(ctx ActionCtx) error {
 	}
 	if p.at == 0 {
 		at := fmt.Sprintf("%d", p.at)
-		at, err = cli.Prompt("revoke all credentials created before (0 is now)", at, true, p.canParse)
+		at, err = cli.Prompt("revoke all credentials created before (0 is now)", at, cli.Val(p.canParse))
 		p.at, err = strconv.Atoi(at)
 	}
 	if err := p.SignerParams.Edit(ctx); err != nil {
diff --git a/cmd/root.go b/cmd/root.go
index 4203b98..7ad66d0 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -23,7 +23,7 @@ import (
 	"strconv"
 
 	"github.com/mitchellh/go-homedir"
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
diff --git a/cmd/signerparams.go b/cmd/signerparams.go
index 9a5ed58..195d002 100644
--- a/cmd/signerparams.go
+++ b/cmd/signerparams.go
@@ -20,7 +20,7 @@ import (
 	"os"
 	"strings"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/nkeys"
 )
 
@@ -78,7 +78,7 @@ func (p *SignerParams) SelectFromSigners(ctx ActionCtx, signers []string) error
 		if p.prompt == "" {
 			p.prompt = "select the key to use for signing"
 		}
-		choice, err := cli.PromptChoices(p.prompt, choices[0], choices)
+		choice, err := cli.Select(p.prompt, choices[0], choices)
 		if err != nil {
 			return err
 		}
@@ -86,7 +86,7 @@ func (p *SignerParams) SelectFromSigners(ctx ActionCtx, signers []string) error
 		if idx != -1 && choice == idx {
 			label := fmt.Sprintf("path to signer %s nkey or nkey", p.kind.String())
 			// key must be one from signing keys
-			KeyPathFlag, err = cli.Prompt(label, "", true, SeedNKeyValidatorMatching(p.kind, signers))
+			KeyPathFlag, err = cli.Prompt(label, "", cli.Val(SeedNKeyValidatorMatching(p.kind, signers)))
 			if err != nil {
 				return err
 			}
diff --git a/cmd/signingkeyseditor.go b/cmd/signingkeyseditor.go
index c0baadc..99ccdf6 100644
--- a/cmd/signingkeyseditor.go
+++ b/cmd/signingkeyseditor.go
@@ -20,7 +20,7 @@ package cmd
 import (
 	"fmt"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/nkeys"
 	"github.com/nats-io/nsc/cmd/store"
 	"github.com/spf13/cobra"
@@ -89,7 +89,7 @@ func (e *SigningKeysParams) PublicKeys() ([]string, error) {
 func (e *SigningKeysParams) Edit() error {
 	// verify any keys that were added via flags
 	for i, v := range e.paths {
-		sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), v, true, e.valid)
+		sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), v, cli.Val(e.valid))
 		if err != nil {
 			return err
 		}
@@ -103,14 +103,14 @@ func (e *SigningKeysParams) Edit() error {
 		}
 		first = false
 
-		ok, err := cli.PromptBoolean(m, false)
+		ok, err := cli.Confirm(m, false)
 		if err != nil {
 			return err
 		}
 		if !ok {
 			break
 		}
-		sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), "", true, e.valid)
+		sv, err := cli.Prompt(fmt.Sprintf("path to %s nkey or nkey", e.flagName), "", cli.Val(e.valid))
 		if err != nil {
 			return err
 		}
diff --git a/cmd/store/store.go b/cmd/store/store.go
index b0a0d0b..1edcb41 100644
--- a/cmd/store/store.go
+++ b/cmd/store/store.go
@@ -30,7 +30,7 @@ import (
 	"sync"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nkeys"
 )
@@ -799,7 +799,7 @@ func (ctx *Context) PickAccount(name string) (string, error) {
 		name = accounts[0]
 	}
 	if len(accounts) > 1 {
-		i, err := cli.PromptChoices("select account", name, accounts)
+		i, err := cli.Select("select account", name, accounts)
 		if err != nil {
 			return "", err
 		}
@@ -850,7 +850,7 @@ func (ctx *Context) PickUser(accountName string) (string, error) {
 		return users[0], nil
 	}
 	if len(users) > 1 {
-		i, err := cli.PromptChoices("select user", "", users)
+		i, err := cli.Select("select user", "", users)
 		if err != nil {
 			return "", err
 		}
diff --git a/cmd/timeparams.go b/cmd/timeparams.go
index 0757804..2917d81 100644
--- a/cmd/timeparams.go
+++ b/cmd/timeparams.go
@@ -21,7 +21,7 @@ import (
 	"strconv"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/spf13/cobra"
 )
 
@@ -43,7 +43,7 @@ func (p *TimeParams) valid(value string, label string, oldOK bool) error {
 	}
 	if InteractiveFlag && !oldOK && when != 0 && now > when {
 		m := fmt.Sprintf("%s %q is in the past (%s) - are you sure?", label, value, HumanizedDate(when))
-		ok, err := cli.PromptBoolean(m, false)
+		ok, err := cli.Confirm(m, false)
 		if err != nil {
 			return err
 		}
@@ -97,12 +97,12 @@ func (p *TimeParams) canParse(s string) error {
 func (p *TimeParams) Edit() error {
 	var err error
 	format := "valid from ('0' is always) - yyyy-mm-dd, #m(inutes), #h(ours), #d(ays), #w(eeks), #M(onths), #y(ears)"
-	p.Start, err = cli.PromptWithHelp("valid", p.Start, true, p.canParse, format)
+	p.Start, err = cli.Prompt("valid", p.Start, cli.Val(p.canParse), cli.Help(format))
 	if err != nil {
 		return err
 	}
 
-	p.Expiry, err = cli.PromptWithHelp("valid until (0 is always)", p.Expiry, true, p.canParse, format)
+	p.Expiry, err = cli.Prompt("valid until (0 is always)", p.Expiry, cli.Val(p.canParse), cli.Help(format))
 	return err
 }
 
diff --git a/cmd/update.go b/cmd/update.go
index f0629c2..eab6721 100644
--- a/cmd/update.go
+++ b/cmd/update.go
@@ -22,7 +22,7 @@ import (
 
 	"github.com/blang/semver"
 	"github.com/briandowns/spinner"
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/rhysd/go-github-selfupdate/selfupdate"
 	"github.com/spf13/cobra"
 )
diff --git a/go.mod b/go.mod
index 6972bc6..7725f14 100644
--- a/go.mod
+++ b/go.mod
@@ -10,11 +10,9 @@ require (
 	github.com/fatih/color v1.7.0 // indirect
 	github.com/hinshun/vt10x v0.0.0-20180809195222-d55458df857c // indirect
 	github.com/inconshreveable/mousetrap v1.0.0 // indirect
-	github.com/kr/pty v1.1.3 // indirect
-	github.com/mattn/go-isatty v0.0.4 // indirect
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/mitchellh/mapstructure v1.1.2 // indirect
-	github.com/nats-io/cliprompts v0.3.16
+	github.com/nats-io/cliprompts/v2 v2.0.0-20191203200115-ae8d3743105d
 	github.com/nats-io/jwt v0.3.2
 	github.com/nats-io/nats-server/v2 v2.0.1-0.20190625001713-2db76bde3329
 	github.com/nats-io/nats.go v1.8.1
diff --git a/go.sum b/go.sum
index c4dc836..6ce81bb 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,5 @@
-github.com/AlecAivazis/survey v1.7.0 h1:Hri7k8HCumnCO2ks0BjjYZdnLVL3b/nvfUjUUVJtHGs=
-github.com/AlecAivazis/survey v1.7.0/go.mod h1:MVECab6WqEH1aXhj8nKIwF7HEAJAj2bhhGiSjNy3wII=
+github.com/AlecAivazis/survey/v2 v2.0.4 h1:qzXnJSzXEvmUllWqMBWpZndvT2YfoAUzAMvZUax3L2M=
+github.com/AlecAivazis/survey/v2 v2.0.4/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
@@ -11,7 +11,6 @@ github.com/briandowns/spinner v0.0.0-20181029155426-195c31b675a7 h1:IvbBe4mOtBLz
 github.com/briandowns/spinner v0.0.0-20181029155426-195c31b675a7/go.mod h1:hw/JEQBIE+c/BLI4aKM8UU8v+ZqrD3h7HC27kKt8JQU=
 github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
@@ -45,17 +44,16 @@ github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.3 h1:/Um6a/ZmD5tF7peoOJ5oN5KMQ0DrGVQSXLNwyckutPk=
-github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
+github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
-github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -66,8 +64,8 @@ github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KH
 github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/nats-io/cliprompts v0.3.16 h1:P0V9+ygF5pGWTxOoyaW30Hx1Hg5GdGvYmAeim1WUQ9M=
-github.com/nats-io/cliprompts v0.3.16/go.mod h1:z7VXOACCA8oEJByXsW/AsHsrqvZlAoQHhVmh9Ash9Jo=
+github.com/nats-io/cliprompts/v2 v2.0.0-20191203200115-ae8d3743105d h1:2+6rW0YuYCNV3BOB5iHI+85pLB29CBWrS1RPsQsfyCE=
+github.com/nats-io/cliprompts/v2 v2.0.0-20191203200115-ae8d3743105d/go.mod h1:oweZn7AeaVJYKlNHfCIhznJVsdySLSng55vfuINE/d0=
 github.com/nats-io/jwt v0.2.6 h1:eAyoYvGgGLXR2EpnsBUvi/FcFrBqN6YKFVbOoEfPN4k=
 github.com/nats-io/jwt v0.2.6/go.mod h1:mQxQ0uHQ9FhEVPIcTSKwx2lqZEpXWWcCgA7R6NrWvvY=
 github.com/nats-io/jwt v0.3.2 h1:+RB5hMpXUUA2dfxuhBTEkMOrYmM+gKIZYS1KjSostMI=
@@ -125,7 +123,6 @@ github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5 h1:gmD7q6cCJfBbcu
 github.com/xlab/tablewriter v0.0.0-20160610135559-80b567a11ad5/go.mod h1:fVwOndYN3s5IaGlMucfgxwMhqwcaJtlGejBU6zX6Yxw=
 golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
 golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
 golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -145,14 +142,15 @@ golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAG
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg=
 golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8 h1:YoY1wS6JYVRpIfFngRf2HHo9R9dAne3xbkGOQ5rJXjU=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qqCB4teTffacDWr7CI+0=
 golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@@ -162,8 +160,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
 google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-gopkg.in/AlecAivazis/survey.v1 v1.8.7 h1:oBJqtgsyBLg9K5FK9twNUbcPnbCPoh+R9a+7nag3qJM=
-gopkg.in/AlecAivazis/survey.v1 v1.8.7/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/vendor/github.com/AlecAivazis/survey/.travis.yml b/vendor/github.com/AlecAivazis/survey/.travis.yml
deleted file mode 100644
index 70932cd..0000000
--- a/vendor/github.com/AlecAivazis/survey/.travis.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-language: go
-
-go_import_path: gopkg.in/AlecAivazis/survey.v1
-
-before_install:
-  - go get github.com/AlecAivazis/run
-
-install:
-  - run install-deps
-
-script:
-  - run tests
-  # - run autoplay-tests
diff --git a/vendor/github.com/AlecAivazis/survey/_tasks.yml b/vendor/github.com/AlecAivazis/survey/_tasks.yml
deleted file mode 100644
index ab84a17..0000000
--- a/vendor/github.com/AlecAivazis/survey/_tasks.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-autoplay-tests:
-  summary: Replaying interactive tests
-  command: |-
-    cd tests
-    set -e
-    for test in autoplay/*.go; do
-      echo "==> Running $test"
-      go run $test
-    done
-
-install-deps:
-  summary: Install all of package dependencies
-  command: |-
-    go get -t {{.files}}
-    # for autoplay tests
-    go get github.com/kr/pty
-
-tests:
-  summary: Run the test suite
-  command: go test {{.files}}
-
-variables:
-  files: '$(go list -v ./... | grep -iEv "tests|examples")'
diff --git a/vendor/github.com/AlecAivazis/survey/v2/.travis.yml b/vendor/github.com/AlecAivazis/survey/v2/.travis.yml
new file mode 100644
index 0000000..a9e09e8
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/.travis.yml
@@ -0,0 +1,21 @@
+language: go
+
+go:
+  - 1.12
+
+os:
+  - linux
+  - linux-ppc64le
+  - osx
+  - windows
+
+go_import_path: github.com/AlecAivazis/survey/v2
+
+before_install:
+  - go get github.com/alecaivazis/run
+
+install: []
+
+script:
+  - run tests
+  # - run autoplay-tests
diff --git a/vendor/github.com/AlecAivazis/survey/CONTRIBUTING.md b/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md
similarity index 68%
rename from vendor/github.com/AlecAivazis/survey/CONTRIBUTING.md
rename to vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md
index 24dcca1..a84e060 100644
--- a/vendor/github.com/AlecAivazis/survey/CONTRIBUTING.md
+++ b/vendor/github.com/AlecAivazis/survey/v2/CONTRIBUTING.md
@@ -19,11 +19,12 @@ This project and its contibutors are expected to uphold the [Go Community Code o
 
 ## Getting help
 
-Feel free to [open up an issue](https://github.com/AlecAivazis/survey/issues/new) on GitHub when asking a question so others will be able to find it. Please remember to tag the issue with the `Question` label so the maintainers can get to your question as soon as possible. If the question is urgent, feel free to reach out to `@AlecAivazis` directly in the gophers slack channel.
+Feel free to [open up an issue](https://github.com/AlecAivazis/survey/v2/issues/new) on GitHub when asking a question so others will be able to find it. Please remember to tag the issue with the `Question` label so the maintainers can get to your question as soon as possible. If the question is urgent, feel free to reach out to `@AlecAivazis` directly in the gophers slack channel.
 
 ## How to file a bug report
 
 Bugs are tracked using the Github Issue tracker. When filing a bug, please remember to label the issue as a `Bug` and answer/provide the following:
+
 1. What operating system and terminal are you using?
 1. An example that showcases the bug.
 1. What did you expect to see?
@@ -31,20 +32,20 @@ Bugs are tracked using the Github Issue tracker. When filing a bug, please remem
 
 ## Suggesting an API change
 
-If you have an idea, I'm more than happy to discuss it. Please open an issue labeled `Discussion` and we can work through it. In order to maintain some sense of stability, additions to the top-level API are taken just as seriously as changes that break it. Adding stuff is much easier than removing it.
+If you have an idea, I'm more than happy to discuss it. Please open an issue and we can work through it. In order to maintain some sense of stability, additions to the top-level API are taken just as seriously as changes that break it. Adding stuff is much easier than removing it.
 
 ## Submitting a contribution
 
-In order to maintain stability, most features get fully integrated in more than one PR. This allows for more opportunity to think through each API change without amassing large amounts of tech debt and API changes  at once. If your feature can be broken into separate chunks, it will be able to be reviewed much quicker. For example, if the PR that implemented the `Validate` field was submitted in a PR separately from one that included `survey.Required`, it would be able to get merge without having to decide how many different `Validators` we want to provide as part of `survey`'s API.
+In order to maintain stability, most features get fully integrated in more than one PR. This allows for more opportunity to think through each API change without amassing large amounts of tech debt and API changes at once. If your feature can be broken into separate chunks, it will be able to be reviewed much quicker. For example, if the PR that implemented the `Validate` field was submitted in a PR separately from one that included `survey.Required`, it would be able to get merge without having to decide how many different `Validators` we want to provide as part of `survey`'s API.
 
 When submitting a contribution,
-  *  Provide a description of the feature or change
-  *  Reference the ticket addressed by the PR if there is one
-  *  Following community standards, add comments for all exported members so that all necessary information is available on godocs
-  *  Remember to update the project README.md with changes to the high-level API
-  *  Include both positive and negative unit tests (when applicable)
-  *  Contributions with visual ramifications or interaction changes should be accompanied with the appropriate `go-expect` tests. For more information on writing these tests, see [Writing and Running Tests](#writing-and-running-tests)
 
+- Provide a description of the feature or change
+- Reference the ticket addressed by the PR if there is one
+- Following community standards, add comments for all exported members so that all necessary information is available on godocs
+- Remember to update the project README.md with changes to the high-level API
+- Include both positive and negative unit tests (when applicable)
+- Contributions with visual ramifications or interaction changes should be accompanied with the appropriate `go-expect` tests. For more information on writing these tests, see [Writing and Running Tests](#writing-and-running-tests)
 
 ## Writing and running tests
 
@@ -74,5 +75,3 @@ For example, you can extend the tests for Input by specifying the following test
 If you want to write your own `go-expect` test from scratch, you'll need to instantiate a virtual terminal,
 multiplex it into an `*expect.Console`, and hook up its tty with survey's optional stdio. Please see `go-expect`
 [documentation](https://godoc.org/github.com/Netflix/go-expect) for more detail.
-
-
diff --git a/vendor/github.com/AlecAivazis/survey/Gopkg.lock b/vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock
similarity index 100%
rename from vendor/github.com/AlecAivazis/survey/Gopkg.lock
rename to vendor/github.com/AlecAivazis/survey/v2/Gopkg.lock
diff --git a/vendor/github.com/AlecAivazis/survey/Gopkg.toml b/vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml
similarity index 100%
rename from vendor/github.com/AlecAivazis/survey/Gopkg.toml
rename to vendor/github.com/AlecAivazis/survey/v2/Gopkg.toml
diff --git a/vendor/github.com/AlecAivazis/survey/LICENSE b/vendor/github.com/AlecAivazis/survey/v2/LICENSE
similarity index 100%
rename from vendor/github.com/AlecAivazis/survey/LICENSE
rename to vendor/github.com/AlecAivazis/survey/v2/LICENSE
diff --git a/vendor/github.com/AlecAivazis/survey/README.md b/vendor/github.com/AlecAivazis/survey/v2/README.md
similarity index 52%
rename from vendor/github.com/AlecAivazis/survey/README.md
rename to vendor/github.com/AlecAivazis/survey/v2/README.md
index 0811027..420810f 100644
--- a/vendor/github.com/AlecAivazis/survey/README.md
+++ b/vendor/github.com/AlecAivazis/survey/v2/README.md
@@ -1,9 +1,9 @@
 # Survey
 
 [![Build Status](https://travis-ci.org/AlecAivazis/survey.svg?branch=feature%2Fpretty)](https://travis-ci.org/AlecAivazis/survey)
-[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/gopkg.in/AlecAivazis/survey.v1)
+[![GoDoc](http://img.shields.io/badge/godoc-reference-5272B4.svg)](https://godoc.org/github.com/AlecAivazis/survey)
 
-A library for building interactive prompts. 
+A library for building interactive prompts.
 
 <img width="550" src="https://thumbs.gfycat.com/VillainousGraciousKouprey-size_restricted.gif"/>
 
@@ -12,7 +12,7 @@ package main
 
 import (
     "fmt"
-    "gopkg.in/AlecAivazis/survey.v1"
+    "github.com/AlecAivazis/survey/v2"
 )
 
 // the questions to ask
@@ -42,7 +42,7 @@ func main() {
     answers := struct {
         Name          string                  // survey will match the question and field names
         FavoriteColor string `survey:"color"` // or you can tag fields to match a specific name
-        Age           int                     // if the types don't match exactly, survey will try to convert for you
+        Age           int                     // if the types don't match, survey will convert it
     }{}
 
     // perform the questions
@@ -59,6 +59,7 @@ func main() {
 ## Table of Contents
 
 1. [Examples](#examples)
+1. [Running the Prompts](#running-the-prompts)
 1. [Prompts](#prompts)
    1. [Input](#input)
    1. [Multiline](#multiline)
@@ -67,13 +68,13 @@ func main() {
    1. [Select](#select)
    1. [MultiSelect](#multiselect)
    1. [Editor](#editor)
+1. [Filtering Options](#filtering-options)
 1. [Validation](#validation)
    1. [Built-in Validators](#built-in-validators)
 1. [Help Text](#help-text)
-   1. [Changing the input rune](#changing-the-input-run)
+   1. [Changing the input rune](#changing-the-input-rune)
+1. [Changing the Icons ](#changing-the-icons)
 1. [Custom Types](#custom-types)
-1. [Customizing Output](#customizing-output)
-1. [Versioning](#versioning)
 1. [Testing](#testing)
 
 ## Examples
@@ -82,14 +83,45 @@ Examples can be found in the `examples/` directory. Run them
 to see basic behavior:
 
 ```bash
-go get gopkg.in/AlecAivazis/survey.v1
+go get github.com/AlecAivazis/survey
 
-cd $GOPATH/src/gopkg.in/AlecAivazis/survey.v1
+cd $GOPATH/src/github.com/AlecAivazis/survey
 
 go run examples/simple.go
 go run examples/validation.go
 ```
 
+## Running the Prompts
+
+There are two primary ways to execute prompts and start collecting information from your users: `Ask` and
+`AskOne`. The primary difference is whether you are interested in collecting a single piece of information
+or if you have a list of questions to ask whose answers should be collected in a single struct.
+For most basic usecases, `Ask` should be enough. However, for surveys with complicated branching logic,
+we recommend that you break out your questions into multiple calls to both of these functions to fit your needs.
+
+### Configuring the Prompts
+
+Most prompts take fine-grained configuration through fields on the structs you instantiate. It is also
+possible to change survey's default behaviors by passing `AskOpts` to either `Ask` or `AskOne`. Examples
+in this document will do both interchangeably:
+
+```golang
+prompt := &Select{
+    Message: "Choose a color:",
+    Options: []string{"red", "blue", "green"},
+    // can pass a validator directly
+    Validate: survey.Required,
+}
+
+// or define a default for the single call to `AskOne`
+// the answer will get written to the color variable
+survey.AskOne(prompt, &color, survey.WithValidator(survey.Required))
+
+// or define a default for every entry in a list of questions
+// the answer will get copied into the matching field of the struct as shown above
+survey.Ask(questions, &answers, survey.WithValidator(survey.Required))
+```
+
 ## Prompts
 
 ### Input
@@ -101,7 +133,7 @@ name := ""
 prompt := &survey.Input{
     Message: "ping",
 }
-survey.AskOne(prompt, &name, nil)
+survey.AskOne(prompt, &name)
 ```
 
 ### Multiline
@@ -113,7 +145,7 @@ text := ""
 prompt := &survey.Multiline{
     Message: "ping",
 }
-survey.AskOne(prompt, &text, nil)
+survey.AskOne(prompt, &text)
 ```
 
 ### Password
@@ -125,7 +157,7 @@ password := ""
 prompt := &survey.Password{
     Message: "Please type your password",
 }
-survey.AskOne(prompt, &password, nil)
+survey.AskOne(prompt, &password)
 ```
 
 ### Confirm
@@ -137,7 +169,7 @@ name := false
 prompt := &survey.Confirm{
     Message: "Do you like pie?",
 }
-survey.AskOne(prompt, &name, nil)
+survey.AskOne(prompt, &name)
 ```
 
 ### Select
@@ -150,18 +182,24 @@ prompt := &survey.Select{
     Message: "Choose a color:",
     Options: []string{"red", "blue", "green"},
 }
-survey.AskOne(prompt, &color, nil)
+survey.AskOne(prompt, &color)
 ```
 
-The user can filter for options by typing while the prompt is active. The user can also press `esc` to toggle 
-the ability cycle through the options with the j and k keys to do down and up respectively.
+Fields and values that come from a `Select` prompt can be one of two different things. If you pass an `int`
+the field will have the value of the selected index. If you instead pass a string, the string value selected
+will be written to the field.
+
+The user can also press `esc` to toggle the ability cycle through the options with the j and k keys to do down and up respectively.
 
 By default, the select prompt is limited to showing 7 options at a time
-and will paginate lists of options longer than that. To increase, you can either
-change the global `survey.PageSize`, or set the `PageSize` field on the prompt:
+and will paginate lists of options longer than that. This can be changed a number of ways:
 
 ```golang
-prompt := &survey.Select{..., PageSize: 10}
+// as a field on a single select
+prompt := &survey.MultiSelect{..., PageSize: 10}
+
+// or as an option to Ask or AskOne
+survey.AskOne(prompt, &days, survey.WithPageSize(10))
 ```
 
 ### MultiSelect
@@ -174,32 +212,74 @@ prompt := &survey.MultiSelect{
     Message: "What days do you prefer:",
     Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
 }
-survey.AskOne(prompt, &days, nil)
+survey.AskOne(prompt, &days)
 ```
 
-The user can filter for options by typing while the prompt is active. The user can also press `esc` to toggle 
-the ability cycle through the options with the j and k keys to do down and up respectively.
+Fields and values that come from a `MultiSelect` prompt can be one of two different things. If you pass an `int`
+the field will have a slice of the selected indices. If you instead pass a string, a slice of the string values
+selected will be written to the field.
+
+The user can also press `esc` to toggle the ability cycle through the options with the j and k keys to do down and up respectively.
 
 By default, the MultiSelect prompt is limited to showing 7 options at a time
-and will paginate lists of options longer than that. To increase, you can either
-change the global `survey.PageSize`, or set the `PageSize` field on the prompt:
+and will paginate lists of options longer than that. This can be changed a number of ways:
 
 ```golang
+// as a field on a single select
 prompt := &survey.MultiSelect{..., PageSize: 10}
+
+// or as an option to Ask or AskOne
+survey.AskOne(prompt, &days, survey.WithPageSize(10))
 ```
 
 ### Editor
 
-Launches the user's preferred editor (defined by the $EDITOR environment variable) on a
+Launches the user's preferred editor (defined by the \$VISUAL or \$EDITOR environment variables) on a
 temporary file. Once the user exits their editor, the contents of the temporary file are read in as
 the result. If neither of those are present, notepad (on Windows) or vim (Linux or Mac) is used.
 
+You can also specify a [pattern](https://golang.org/pkg/io/ioutil/#TempFile) for the name of the temporary file. This
+can be useful for ensuring syntax highlighting matches your usecase.
+
+```golang
+prompt := &survey.Editor{
+    Message: "Shell code snippet",
+    FileName: "*.sh",
+}
+
+survey.AskOne(prompt, &content)
+```
+
+## Filtering Options
+
+By default, the user can filter for options in Select and MultiSelects by typing while the prompt
+is active. This will filter out all options that don't contain the typed string anywhere in their name, ignoring case.
+
+A custom filter function can also be provided to change this behavior:
+
+```golang
+func myFilter(filterValue string, optValue string, optIndex int) bool {
+    // only include the option if it includes the filter and has length greater than 5
+    return strings.Contains(optValue, filterValue) && len(optValue) >= 5
+}
+
+// configure it for a specific prompt
+&Select{
+    Message: "Choose a color:",
+    Options: []string{"red", "blue", "green"},
+    Filter: myFilter,
+}
+
+// or define a default for all of the questions
+survey.AskOne(prompt, &color, survey.WithFilter(myFilter))
+```
+
 ## Validation
 
 Validating individual responses for a particular question can be done by defining a
 `Validate` field on the `survey.Question` to be validated. This function takes an
 `interface{}` type and returns an error to show to the user, prompting them for another
-response:
+response. Like usual, validators can be provided directly to the prompt or with `survey.WithValidator`:
 
 ```golang
 q := &survey.Question{
@@ -209,8 +289,15 @@ q := &survey.Question{
         if str, ok := val.(string) ; !ok || len(str) > 10 {
             return errors.New("This response cannot be longer than 10 characters.")
         }
-    }
+	return nil
+    },
 }
+
+color := ""
+prompt := &survey.Input{ Message: "Whats your name?" }
+
+// you can pass multiple validators here and survey will make sure each one passes
+survey.AskOne(prompt, &color, survey.WithValidator(survey.Required))
 ```
 
 ### Built-in Validators
@@ -240,12 +327,11 @@ All of the prompts have a `Help` field which can be defined to provide more info
 ### Changing the input rune
 
 In some situations, `?` is a perfectly valid response. To handle this, you can change the rune that survey
-looks for by setting the `HelpInputRune` variable in `survey/core`:
+looks for with `WithHelpInput`:
 
 ```golang
 import (
-    "gopkg.in/AlecAivazis/survey.v1"
-    surveyCore "gopkg.in/AlecAivazis/survey.v1/core"
+    "github.com/AlecAivazis/survey/v2"
 )
 
 number := ""
@@ -254,17 +340,50 @@ prompt := &survey.Input{
     Help:    "I couldn't come up with one.",
 }
 
-surveyCore.HelpIcon = '^'
+survey.AskOne(prompt, &number, survey.WithHelpInput('^'))
+```
+
+## Changing the Icons
+
+Changing the icons and their color/format can be done by passing the `WithIcons` option. The format
+follows the patterns outlined [here](https://github.com/mgutz/ansi#style-format). For example:
+
+```golang
+import (
+    "github.com/AlecAivazis/survey/v2"
+)
 
-survey.AskOne(prompt, &number, nil)
+number := ""
+prompt := &survey.Input{
+    Message: "If you have this need, please give me a reasonable message.",
+    Help:    "I couldn't come up with one.",
+}
+
+survey.AskOne(prompt, &number, survey.WithIcons(func(icons *survey.IconSet) {
+    // you can set any icons
+    icons.Question.Text = "⁇"
+    // for more information on formatting the icons, see here: https://github.com/mgutz/ansi#style-format
+    icons.Question.Format = "yellow+hb"
+}))
 ```
 
+The icons and their default text and format are summarized below:
+
+| name           | text | format     | description                                                   |
+| -------------- | ---- | ---------- | ------------------------------------------------------------- |
+| Error          | X    | red        | Before an error                                               |
+| Help           | i    | cyan       | Before help text                                              |
+| Question       | ?    | green+hb   | Before the message of a prompt                                |
+| SelectFocus    | >    | green      | Marks the current focus in `Select` and `MultiSelect` prompts |
+| UnmarkedOption | [ ]  | default+hb | Marks an unselected option in a `MultiSelect` prompt          |
+| MarkedOption   | [x]  | cyan+b     | Marks a chosen selection in a `MultiSelect` prompt            |
+
 ## Custom Types
 
 survey will assign prompt answers to your custom types if they implement this interface:
 
 ```golang
-type settable interface {
+type Settable interface {
     WriteAnswer(field string, value interface{}) error
 }
 ```
@@ -284,36 +403,10 @@ survey.AskOne(
     &survey.Input{
         Message: "Enter something:",
     },
-    &myval,
-    nil,
+    &myval
 )
 ```
 
-## Customizing Output
-
-Customizing the icons and various parts of survey can easily be done by setting the following variables
-in `survey/core`:
-
-| name               | default | description                                                   |
-| ------------------ | ------- | ------------------------------------------------------------- |
-| ErrorIcon          | X       | Before an error                                               |
-| HelpIcon           | i       | Before help text                                              |
-| QuestionIcon       | ?       | Before the message of a prompt                                |
-| SelectFocusIcon    | >       | Marks the current focus in `Select` and `MultiSelect` prompts |
-| UnmarkedOptionIcon | [ ]     | Marks an unselected option in a `MultiSelect` prompt          |
-| MarkedOptionIcon   | [x]     | Marks a chosen selection in a `MultiSelect` prompt            |
-
-## Versioning
-
-This project tries to maintain semantic GitHub releases as closely as possible and relies on [gopkg.in](http://labix.org/gopkg.in)
-to maintain those releases. Importing version 1 of survey would look like:
-
-```golang
-package main
-
-import "gopkg.in/AlecAivazis/survey.v1"
-```
-
 ## Testing
 
 You can test your program's interactive prompts using [go-expect](https://github.com/Netflix/go-expect). The library
@@ -322,74 +415,4 @@ if you are manipulating the cursor or using `survey`, you will need a way to int
 for things like `CursorLocation`. `vt10x.NewVT10XConsole` will create a `go-expect` console that also multiplexes
 stdio to an in-memory [virtual terminal](https://github.com/hinshun/vt10x).
 
-For example, you can test a binary utilizing `survey` by connecting the Console's tty to a subprocess's stdio. 
-
-```go
-func TestCLI(t *testing.T) {
- 	// Multiplex stdin/stdout to a virtual terminal to respond to ANSI escape
- 	// sequences (i.e. cursor position report).
- 	c, state, err := vt10x.NewVT10XConsole()
-	require.Nil(t, err)
-	defer c.Close()
-
-	donec := make(chan struct{})
-	go func() {
-		defer close(donec)
-    		c.ExpectString("What is your name?")
-    		c.SendLine("Johnny Appleseed")
-    		c.ExpectEOF()
-  	}()
-
-	cmd := exec.Command("your-cli")
-  	cmd.Stdin = c.Tty()
-  	cmd.Stdout = c.Tty()
-  	cmd.Stderr = c.Tty()
-
-  	err = cmd.Run()
-  	require.Nil(t, err)
-
-  	// Close the slave end of the pty, and read the remaining bytes from the master end.
-  	c.Tty().Close()
-  	<-donec
-
-  	// Dump the terminal's screen.
-  	t.Log(expect.StripTrailingEmptyLines(state.String()))
-}
-```
-
-If your application is decoupled from `os.Stdout` and `os.Stdin`, you can even test through the tty alone.
-`survey` itself is tested in this manner.
-
-```go
-func TestCLI(t *testing.T) {
-  	// Multiplex stdin/stdout to a virtual terminal to respond to ANSI escape
-  	// sequences (i.e. cursor position report).
-	c, state, err := vt10x.NewVT10XConsole()
-	require.Nil(t, err)
-  	defer c.Close()
-
-  	donec := make(chan struct{})
-	go func() {
-    		defer close(donec)
-    		c.ExpectString("What is your name?")
-    		c.SendLine("Johnny Appleseed")
-    		c.ExpectEOF()
-	}()
-
-  	prompt := &Input{
-    		Message: "What is your name?",
-  	}
-  	prompt.WithStdio(Stdio(c))
-
-  	answer, err := prompt.Prompt()
-  	require.Nil(t, err)
-  	require.Equal(t, "Johnny Appleseed", answer)
-
-  	// Close the slave end of the pty, and read the remaining bytes from the master end.
-  	c.Tty().Close()
-  	<-donec
-
-  	// Dump the terminal's screen.
-  	t.Log(expect.StripTrailingEmptyLines(state.String()))
-}
-```
+For some examples, you can see any of the tests in this repo.
diff --git a/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl b/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl
new file mode 100644
index 0000000..ae970f3
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/_tasks.hcl
@@ -0,0 +1,19 @@
+task "install-deps" {
+    description = "Install all of package dependencies"
+    pipeline = [
+        "go get {{.files}}",
+    ]
+}
+
+task "tests" {
+    description = "Run the test suite"
+    command = "go test {{.files}}"
+    environment {
+        GOFLAGS = "-mod=vendor"
+    }
+}
+
+variables {
+    files = "$(go list -v ./... | grep -iEv \"tests|examples\")"
+}
+
diff --git a/vendor/github.com/AlecAivazis/survey/confirm.go b/vendor/github.com/AlecAivazis/survey/v2/confirm.go
similarity index 68%
rename from vendor/github.com/AlecAivazis/survey/confirm.go
rename to vendor/github.com/AlecAivazis/survey/v2/confirm.go
index 5672c52..8e5d7ef 100644
--- a/vendor/github.com/AlecAivazis/survey/confirm.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/confirm.go
@@ -3,13 +3,11 @@ package survey
 import (
 	"fmt"
 	"regexp"
-
-	"gopkg.in/AlecAivazis/survey.v1/core"
 )
 
 // Confirm is a regular text input that accept yes/no answers. Response type is a bool.
 type Confirm struct {
-	core.Renderer
+	Renderer
 	Message string
 	Default bool
 	Help    string
@@ -20,17 +18,18 @@ type ConfirmTemplateData struct {
 	Confirm
 	Answer   string
 	ShowHelp bool
+	Config   *PromptConfig
 }
 
 // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
 var ConfirmQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
 {{- if .Answer}}
   {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
 {{- else }}
-  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ HelpInputRune }} for help]{{color "reset"}} {{end}}
+  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}}
   {{- color "white"}}{{if .Default}}(Y/n) {{else}}(y/N) {{end}}{{color "reset"}}
 {{- end}}`
 
@@ -47,7 +46,7 @@ func yesNo(t bool) string {
 	return "No"
 }
 
-func (c *Confirm) getBool(showHelp bool) (bool, error) {
+func (c *Confirm) getBool(showHelp bool, config *PromptConfig) (bool, error) {
 	cursor := c.NewCursor()
 	rr := c.NewRuneReader()
 	rr.SetTermMode()
@@ -72,10 +71,14 @@ func (c *Confirm) getBool(showHelp bool) (bool, error) {
 			answer = false
 		case val == "":
 			answer = c.Default
-		case val == string(core.HelpInputRune) && c.Help != "":
+		case val == config.HelpInput && c.Help != "":
 			err := c.Render(
 				ConfirmQuestionTemplate,
-				ConfirmTemplateData{Confirm: *c, ShowHelp: true},
+				ConfirmTemplateData{
+					Confirm:  *c,
+					ShowHelp: true,
+					Config:   config,
+				},
 			)
 			if err != nil {
 				// use the default value and bubble up
@@ -85,12 +88,16 @@ func (c *Confirm) getBool(showHelp bool) (bool, error) {
 			continue
 		default:
 			// we didnt get a valid answer, so print error and prompt again
-			if err := c.Error(fmt.Errorf("%q is not a valid answer, please try again.", val)); err != nil {
+			if err := c.Error(config, fmt.Errorf("%q is not a valid answer, please try again.", val)); err != nil {
 				return c.Default, err
 			}
 			err := c.Render(
 				ConfirmQuestionTemplate,
-				ConfirmTemplateData{Confirm: *c, ShowHelp: showHelp},
+				ConfirmTemplateData{
+					Confirm:  *c,
+					ShowHelp: showHelp,
+					Config:   config,
+				},
 			)
 			if err != nil {
 				// use the default value and bubble up
@@ -110,29 +117,37 @@ by a carriage return.
 
 	likesPie := false
 	prompt := &survey.Confirm{ Message: "What is your name?" }
-	survey.AskOne(prompt, &likesPie, nil)
+	survey.AskOne(prompt, &likesPie)
 */
-func (c *Confirm) Prompt() (interface{}, error) {
+func (c *Confirm) Prompt(config *PromptConfig) (interface{}, error) {
 	// render the question template
 	err := c.Render(
 		ConfirmQuestionTemplate,
-		ConfirmTemplateData{Confirm: *c},
+		ConfirmTemplateData{
+			Confirm: *c,
+			Config:  config,
+		},
 	)
 	if err != nil {
 		return "", err
 	}
 
 	// get input and return
-	return c.getBool(false)
+	return c.getBool(false, config)
 }
 
 // Cleanup overwrite the line with the finalized formatted version
-func (c *Confirm) Cleanup(val interface{}) error {
+func (c *Confirm) Cleanup(config *PromptConfig, val interface{}) error {
 	// if the value was previously true
 	ans := yesNo(val.(bool))
+
 	// render the template
 	return c.Render(
 		ConfirmQuestionTemplate,
-		ConfirmTemplateData{Confirm: *c, Answer: ans},
+		ConfirmTemplateData{
+			Confirm: *c,
+			Answer:  ans,
+			Config:  config,
+		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/v2/core/template.go b/vendor/github.com/AlecAivazis/survey/v2/core/template.go
new file mode 100644
index 0000000..f2b89b4
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/core/template.go
@@ -0,0 +1,60 @@
+package core
+
+import (
+	"bytes"
+	"sync"
+	"text/template"
+
+	"github.com/mgutz/ansi"
+)
+
+// DisableColor can be used to make testing reliable
+var DisableColor = false
+
+var TemplateFuncs = map[string]interface{}{
+	// Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
+	"color": func(color string) string {
+		if DisableColor {
+			return ""
+		}
+		return ansi.ColorCode(color)
+	},
+}
+
+func RunTemplate(tmpl string, data interface{}) (string, error) {
+	t, err := getTemplate(tmpl)
+	if err != nil {
+		return "", err
+	}
+	buf := bytes.NewBufferString("")
+	err = t.Execute(buf, data)
+	if err != nil {
+		return "", err
+	}
+	return buf.String(), err
+}
+
+var (
+	memoizedGetTemplate = map[string]*template.Template{}
+
+	memoMutex = &sync.RWMutex{}
+)
+
+func getTemplate(tmpl string) (*template.Template, error) {
+	memoMutex.RLock()
+	if t, ok := memoizedGetTemplate[tmpl]; ok {
+		memoMutex.RUnlock()
+		return t, nil
+	}
+	memoMutex.RUnlock()
+
+	t, err := template.New("prompt").Funcs(TemplateFuncs).Parse(tmpl)
+	if err != nil {
+		return nil, err
+	}
+
+	memoMutex.Lock()
+	memoizedGetTemplate[tmpl] = t
+	memoMutex.Unlock()
+	return t, nil
+}
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/core/write.go b/vendor/github.com/AlecAivazis/survey/v2/core/write.go
similarity index 77%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/core/write.go
rename to vendor/github.com/AlecAivazis/survey/v2/core/write.go
index cef7635..8aac529 100644
--- a/vendor/gopkg.in/AlecAivazis/survey.v1/core/write.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/core/write.go
@@ -6,19 +6,35 @@ import (
 	"reflect"
 	"strconv"
 	"strings"
+	"time"
 )
 
 // the tag used to denote the name of the question
 const tagName = "survey"
 
-// add a few interfaces so users can configure how the prompt values are set
-type settable interface {
+// Settables allow for configuration when assigning answers
+type Settable interface {
 	WriteAnswer(field string, value interface{}) error
 }
 
+// OptionAnswer is the return type of Selects/MultiSelects that lets the appropriate information
+// get copied to the user's struct
+type OptionAnswer struct {
+	Value string
+	Index int
+}
+
+func OptionAnswerList(incoming []string) []OptionAnswer {
+	list := []OptionAnswer{}
+	for i, opt := range incoming {
+		list = append(list, OptionAnswer{Value: opt, Index: i})
+	}
+	return list
+}
+
 func WriteAnswer(t interface{}, name string, v interface{}) (err error) {
 	// if the field is a custom type
-	if s, ok := t.(settable); ok {
+	if s, ok := t.(Settable); ok {
 		// use the interface method
 		return s.WriteAnswer(name, v)
 	}
@@ -39,6 +55,13 @@ func WriteAnswer(t interface{}, name string, v interface{}) (err error) {
 	switch elem.Kind() {
 	// if we are writing to a struct
 	case reflect.Struct:
+		// if we are writing to an option answer than we want to treat
+		// it like a single thing and not a place to deposit answers
+		if elem.Type().Name() == "OptionAnswer" {
+			// copy the value over to the normal struct
+			return copy(elem, value)
+		}
+
 		// get the name of the field that matches the string we  were given
 		fieldIndex, err := findFieldIndex(elem, name)
 		// if something went wrong
@@ -47,13 +70,13 @@ func WriteAnswer(t interface{}, name string, v interface{}) (err error) {
 			return err
 		}
 		field := elem.Field(fieldIndex)
-		// handle references to the settable interface aswell
-		if s, ok := field.Interface().(settable); ok {
+		// handle references to the Settable interface aswell
+		if s, ok := field.Interface().(Settable); ok {
 			// use the interface method
 			return s.WriteAnswer(name, v)
 		}
 		if field.CanAddr() {
-			if s, ok := field.Addr().Interface().(settable); ok {
+			if s, ok := field.Addr().Interface().(Settable); ok {
 				// use the interface method
 				return s.WriteAnswer(name, v)
 			}
@@ -165,7 +188,11 @@ func copy(t reflect.Value, v reflect.Value) (err error) {
 				castVal = int32(val64)
 			}
 		case reflect.Int64:
-			castVal, casterr = strconv.ParseInt(vString, 10, 64)
+			if t.Type() == reflect.TypeOf(time.Duration(0)) {
+				castVal, casterr = time.ParseDuration(vString)
+			} else {
+				castVal, casterr = strconv.ParseInt(vString, 10, 64)
+			}
 		case reflect.Uint:
 			var val64 uint64
 			val64, casterr = strconv.ParseUint(vString, 10, 8)
@@ -212,6 +239,32 @@ func copy(t reflect.Value, v reflect.Value) (err error) {
 		return
 	}
 
+	// if we are copying from an OptionAnswer to something
+	if v.Type().Name() == "OptionAnswer" {
+		// copying an option answer to a string
+		if t.Kind() == reflect.String {
+			// copies the Value field of the struct
+			t.Set(reflect.ValueOf(v.FieldByName("Value").Interface()))
+			return
+		}
+
+		// copying an option answer to an int
+		if t.Kind() == reflect.Int {
+			// copies the Index field of the struct
+			t.Set(reflect.ValueOf(v.FieldByName("Index").Interface()))
+			return
+		}
+
+		// copying an OptionAnswer to an OptionAnswer
+		if t.Type().Name() == "OptionAnswer" {
+			t.Set(v)
+			return
+		}
+
+		// we're copying an option answer to an incorrect type
+		return fmt.Errorf("Unable to convert from OptionAnswer to type %s", t.Kind())
+	}
+
 	// if we are copying from one slice or array to another
 	if isList(v) && isList(t) {
 		// loop over every item in the desired value
diff --git a/vendor/github.com/AlecAivazis/survey/editor.go b/vendor/github.com/AlecAivazis/survey/v2/editor.go
similarity index 71%
rename from vendor/github.com/AlecAivazis/survey/editor.go
rename to vendor/github.com/AlecAivazis/survey/v2/editor.go
index d69cd95..ec6a141 100644
--- a/vendor/github.com/AlecAivazis/survey/editor.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/editor.go
@@ -7,9 +7,8 @@ import (
 	"os/exec"
 	"runtime"
 
+	"github.com/AlecAivazis/survey/v2/terminal"
 	shellquote "github.com/kballard/go-shellquote"
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
 )
 
 /*
@@ -23,16 +22,17 @@ Response type is a string.
 
 	message := ""
 	prompt := &survey.Editor{ Message: "What is your commit message?" }
-	survey.AskOne(prompt, &message, nil)
+	survey.AskOne(prompt, &message)
 */
 type Editor struct {
-	core.Renderer
+	Renderer
 	Message       string
 	Default       string
 	Help          string
 	Editor        string
 	HideDefault   bool
 	AppendDefault bool
+	FileName      string
 }
 
 // data available to the templates when processing
@@ -41,17 +41,18 @@ type EditorTemplateData struct {
 	Answer     string
 	ShowAnswer bool
 	ShowHelp   bool
+	Config     *PromptConfig
 }
 
 // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
 var EditorQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
 {{- if .ShowAnswer}}
   {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
 {{- else }}
-  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ HelpInputRune }} for help]{{color "reset"}} {{end}}
+  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}}
   {{- if and .Default (not .HideDefault)}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
   {{- color "cyan"}}[Enter to launch editor] {{color "reset"}}
 {{- end}}`
@@ -72,11 +73,27 @@ func init() {
 	}
 }
 
-func (e *Editor) Prompt() (interface{}, error) {
+func (e *Editor) PromptAgain(config *PromptConfig, invalid interface{}, err error) (interface{}, error) {
+	initialValue := invalid.(string)
+	return e.prompt(initialValue, config)
+}
+
+func (e *Editor) Prompt(config *PromptConfig) (interface{}, error) {
+	initialValue := ""
+	if e.Default != "" && e.AppendDefault {
+		initialValue = e.Default
+	}
+	return e.prompt(initialValue, config)
+}
+
+func (e *Editor) prompt(initialValue string, config *PromptConfig) (interface{}, error) {
 	// render the template
 	err := e.Render(
 		EditorQuestionTemplate,
-		EditorTemplateData{Editor: *e},
+		EditorTemplateData{
+			Editor: *e,
+			Config: config,
+		},
 	)
 	if err != nil {
 		return "", err
@@ -105,10 +122,14 @@ func (e *Editor) Prompt() (interface{}, error) {
 		if r == terminal.KeyEndTransmission {
 			break
 		}
-		if r == core.HelpInputRune && e.Help != "" {
+		if string(r) == config.HelpInput && e.Help != "" {
 			err = e.Render(
 				EditorQuestionTemplate,
-				EditorTemplateData{Editor: *e, ShowHelp: true},
+				EditorTemplateData{
+					Editor:   *e,
+					ShowHelp: true,
+					Config:   config,
+				},
 			)
 			if err != nil {
 				return "", err
@@ -118,7 +139,11 @@ func (e *Editor) Prompt() (interface{}, error) {
 	}
 
 	// prepare the temp file
-	f, err := ioutil.TempFile("", "survey")
+	pattern := e.FileName
+	if pattern == "" {
+		pattern = "survey*.txt"
+	}
+	f, err := ioutil.TempFile("", pattern)
 	if err != nil {
 		return "", err
 	}
@@ -134,11 +159,9 @@ func (e *Editor) Prompt() (interface{}, error) {
 		return "", err
 	}
 
-	// write default value
-	if e.Default != "" && e.AppendDefault {
-		if _, err := f.WriteString(e.Default); err != nil {
-			return "", err
-		}
+	// write initial value
+	if _, err := f.WriteString(initialValue); err != nil {
+		return "", err
 	}
 
 	// close the fd to prevent the editor unable to save file
@@ -186,9 +209,14 @@ func (e *Editor) Prompt() (interface{}, error) {
 	return text, nil
 }
 
-func (e *Editor) Cleanup(val interface{}) error {
+func (e *Editor) Cleanup(config *PromptConfig, val interface{}) error {
 	return e.Render(
 		EditorQuestionTemplate,
-		EditorTemplateData{Editor: *e, Answer: "<Received>", ShowAnswer: true},
+		EditorTemplateData{
+			Editor:     *e,
+			Answer:     "<Received>",
+			ShowAnswer: true,
+			Config:     config,
+		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/v2/filter.go b/vendor/github.com/AlecAivazis/survey/v2/filter.go
new file mode 100644
index 0000000..56f7026
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/filter.go
@@ -0,0 +1,1 @@
+package survey
diff --git a/vendor/github.com/AlecAivazis/survey/v2/go.mod b/vendor/github.com/AlecAivazis/survey/v2/go.mod
new file mode 100644
index 0000000..39e48db
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/go.mod
@@ -0,0 +1,16 @@
+module github.com/AlecAivazis/survey/v2
+
+require (
+	github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8
+	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
+	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
+	github.com/kr/pty v1.1.4 // indirect
+	github.com/mattn/go-colorable v0.1.2 // indirect
+	github.com/mattn/go-isatty v0.0.8
+	github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
+	github.com/pmezard/go-difflib v1.0.0 // indirect
+	github.com/stretchr/testify v1.2.1
+	golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 // indirect
+	golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1 // indirect
+)
diff --git a/vendor/github.com/AlecAivazis/survey/v2/go.sum b/vendor/github.com/AlecAivazis/survey/v2/go.sum
new file mode 100644
index 0000000..69bf673
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/go.sum
@@ -0,0 +1,30 @@
+github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
+github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
+github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
+github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U=
+github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1 h1:R4dVlxdmKenVdMRS/tTspEpSTRWINYrHD8ySIU9yCIU=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/vendor/github.com/AlecAivazis/survey/input.go b/vendor/github.com/AlecAivazis/survey/v2/input.go
similarity index 65%
rename from vendor/github.com/AlecAivazis/survey/input.go
rename to vendor/github.com/AlecAivazis/survey/v2/input.go
index 08724d5..958ce71 100644
--- a/vendor/github.com/AlecAivazis/survey/input.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/input.go
@@ -1,19 +1,15 @@
 package survey
 
-import (
-	"gopkg.in/AlecAivazis/survey.v1/core"
-)
-
 /*
 Input is a regular text input that prints each character the user types on the screen
 and accepts the input with the enter key. Response type is a string.
 
 	name := ""
 	prompt := &survey.Input{ Message: "What is your name?" }
-	survey.AskOne(prompt, &name, nil)
+	survey.AskOne(prompt, &name)
 */
 type Input struct {
-	core.Renderer
+	Renderer
 	Message string
 	Default string
 	Help    string
@@ -25,25 +21,29 @@ type InputTemplateData struct {
 	Answer     string
 	ShowAnswer bool
 	ShowHelp   bool
+	Config     *PromptConfig
 }
 
 // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
 var InputQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
 {{- if .ShowAnswer}}
   {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
 {{- else }}
-  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ HelpInputRune }} for help]{{color "reset"}} {{end}}
+  {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ print .Config.HelpInput }} for help]{{color "reset"}} {{end}}
   {{- if .Default}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
 {{- end}}`
 
-func (i *Input) Prompt() (interface{}, error) {
+func (i *Input) Prompt(config *PromptConfig) (interface{}, error) {
 	// render the template
 	err := i.Render(
 		InputQuestionTemplate,
-		InputTemplateData{Input: *i},
+		InputTemplateData{
+			Input:  *i,
+			Config: config,
+		},
 	)
 	if err != nil {
 		return "", err
@@ -66,10 +66,14 @@ func (i *Input) Prompt() (interface{}, error) {
 		// terminal will echo the \n so we need to jump back up one row
 		cursor.PreviousLine(1)
 
-		if string(line) == string(core.HelpInputRune) && i.Help != "" {
+		if string(line) == config.HelpInput && i.Help != "" {
 			err = i.Render(
 				InputQuestionTemplate,
-				InputTemplateData{Input: *i, ShowHelp: true},
+				InputTemplateData{
+					Input:    *i,
+					ShowHelp: true,
+					Config:   config,
+				},
 			)
 			if err != nil {
 				return "", err
@@ -89,9 +93,14 @@ func (i *Input) Prompt() (interface{}, error) {
 	return string(line), err
 }
 
-func (i *Input) Cleanup(val interface{}) error {
+func (i *Input) Cleanup(config *PromptConfig, val interface{}) error {
 	return i.Render(
 		InputQuestionTemplate,
-		InputTemplateData{Input: *i, Answer: val.(string), ShowAnswer: true},
+		InputTemplateData{
+			Input:      *i,
+			Answer:     val.(string),
+			ShowAnswer: true,
+			Config:     config,
+		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/multiline.go b/vendor/github.com/AlecAivazis/survey/v2/multiline.go
similarity index 70%
rename from vendor/github.com/AlecAivazis/survey/multiline.go
rename to vendor/github.com/AlecAivazis/survey/v2/multiline.go
index 6602444..8368705 100644
--- a/vendor/github.com/AlecAivazis/survey/multiline.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/multiline.go
@@ -1,15 +1,13 @@
 package survey
 
 import (
-	"fmt"
 	"strings"
 
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
 type Multiline struct {
-	core.Renderer
+	Renderer
 	Message string
 	Default string
 	Help    string
@@ -21,30 +19,34 @@ type MultilineTemplateData struct {
 	Answer     string
 	ShowAnswer bool
 	ShowHelp   bool
+	Config     *PromptConfig
 }
 
 // Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
 var MultilineQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
 {{- if .ShowAnswer}}
-  {{- "\n"}}{{color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
+  {{- "\n"}}{{color "cyan"}}{{.Answer}}{{color "reset"}}
+  {{- if .Answer }}{{ "\n" }}{{ end }}
 {{- else }}
   {{- if .Default}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
   {{- color "cyan"}}[Enter 2 empty lines to finish]{{color "reset"}}
 {{- end}}`
 
-func (i *Multiline) Prompt() (interface{}, error) {
+func (i *Multiline) Prompt(config *PromptConfig) (interface{}, error) {
 	// render the template
 	err := i.Render(
 		MultilineQuestionTemplate,
-		MultilineTemplateData{Multiline: *i},
+		MultilineTemplateData{
+			Multiline: *i,
+			Config:    config,
+		},
 	)
 	if err != nil {
 		return "", err
 	}
-	fmt.Println()
 
 	// start reading runes from the standard in
 	rr := i.NewRuneReader()
@@ -95,9 +97,14 @@ func (i *Multiline) Prompt() (interface{}, error) {
 	return val, err
 }
 
-func (i *Multiline) Cleanup(val interface{}) error {
+func (i *Multiline) Cleanup(config *PromptConfig, val interface{}) error {
 	return i.Render(
 		MultilineQuestionTemplate,
-		MultilineTemplateData{Multiline: *i, Answer: val.(string), ShowAnswer: true},
+		MultilineTemplateData{
+			Multiline:  *i,
+			Answer:     val.(string),
+			ShowAnswer: true,
+			Config:     config,
+		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/multiselect.go b/vendor/github.com/AlecAivazis/survey/v2/multiselect.go
similarity index 51%
rename from vendor/github.com/AlecAivazis/survey/multiselect.go
rename to vendor/github.com/AlecAivazis/survey/v2/multiselect.go
index 41fe828..59bfa55 100644
--- a/vendor/github.com/AlecAivazis/survey/multiselect.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/multiselect.go
@@ -2,10 +2,10 @@ package survey
 
 import (
 	"errors"
-	"strings"
+	"fmt"
 
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/core"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
 /*
@@ -17,20 +17,21 @@ for them to select using the arrow keys and enter. Response type is a slice of s
 		Message: "What days do you prefer:",
 		Options: []string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"},
 	}
-	survey.AskOne(prompt, &days, nil)
+	survey.AskOne(prompt, &days)
 */
 type MultiSelect struct {
-	core.Renderer
+	Renderer
 	Message       string
 	Options       []string
-	Default       []string
+	Default       interface{}
 	Help          string
 	PageSize      int
 	VimMode       bool
 	FilterMessage string
+	Filter        func(filter string, value string, index int) bool
 	filter        string
 	selectedIndex int
-	checked       map[string]bool
+	checked       map[int]bool
 	showingHelp   bool
 }
 
@@ -39,31 +40,32 @@ type MultiSelectTemplateData struct {
 	MultiSelect
 	Answer        string
 	ShowAnswer    bool
-	Checked       map[string]bool
+	Checked       map[int]bool
 	SelectedIndex int
 	ShowHelp      bool
-	PageEntries   []string
+	PageEntries   []core.OptionAnswer
+	Config        *PromptConfig
 }
 
 var MultiSelectQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }}{{ .FilterMessage }}{{color "reset"}}
 {{- if .ShowAnswer}}{{color "cyan"}} {{.Answer}}{{color "reset"}}{{"\n"}}
 {{- else }}
-	{{- "  "}}{{- color "cyan"}}[Use arrows to move, type to filter{{- if and .Help (not .ShowHelp)}}, {{ HelpInputRune }} for more help{{end}}]{{color "reset"}}
+	{{- "  "}}{{- color "cyan"}}[Use arrows to move, space to select, type to filter{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
   {{- "\n"}}
   {{- range $ix, $option := .PageEntries}}
-    {{- if eq $ix $.SelectedIndex}}{{color "cyan"}}{{ SelectFocusIcon }}{{color "reset"}}{{else}} {{end}}
-    {{- if index $.Checked $option}}{{color "green"}} {{ MarkedOptionIcon }} {{else}}{{color "default+hb"}} {{ UnmarkedOptionIcon }} {{end}}
+    {{- if eq $ix $.SelectedIndex }}{{color $.Config.Icons.SelectFocus.Format }}{{ $.Config.Icons.SelectFocus.Text }}{{color "reset"}}{{else}} {{end}}
+    {{- if index $.Checked $option.Index }}{{color $.Config.Icons.MarkedOption.Format }} {{ $.Config.Icons.MarkedOption.Text }} {{else}}{{color $.Config.Icons.UnmarkedOption.Format }} {{ $.Config.Icons.UnmarkedOption.Text }} {{end}}
     {{- color "reset"}}
-    {{- " "}}{{$option}}{{"\n"}}
+    {{- " "}}{{$option.Value}}{{"\n"}}
   {{- end}}
 {{- end}}`
 
 // OnChange is called on every keypress.
-func (m *MultiSelect) OnChange(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
-	options := m.filterOptions()
+func (m *MultiSelect) OnChange(key rune, config *PromptConfig) {
+	options := m.filterOptions(config)
 	oldFilter := m.filter
 
 	if key == terminal.KeyArrowUp || (m.VimMode && key == 'k') {
@@ -86,18 +88,22 @@ func (m *MultiSelect) OnChange(line []rune, pos int, key rune) (newLine []rune,
 		}
 		// if the user pressed down and there is room to move
 	} else if key == terminal.KeySpace {
+		// the option they have selected
 		if m.selectedIndex < len(options) {
-			if old, ok := m.checked[options[m.selectedIndex]]; !ok {
-				// otherwise just invert the current value
-				m.checked[options[m.selectedIndex]] = true
+			selectedOpt := options[m.selectedIndex]
+
+			// if we haven't seen this index before
+			if old, ok := m.checked[selectedOpt.Index]; !ok {
+				// set the value to true
+				m.checked[selectedOpt.Index] = true
 			} else {
 				// otherwise just invert the current value
-				m.checked[options[m.selectedIndex]] = !old
+				m.checked[selectedOpt.Index] = !old
 			}
 			m.filter = ""
 		}
 		// only show the help message if we have one to show
-	} else if key == core.HelpInputRune && m.Help != "" {
+	} else if string(key) == config.HelpInput && m.Help != "" {
 		m.showingHelp = true
 	} else if key == terminal.KeyEscape {
 		m.VimMode = !m.VimMode
@@ -118,16 +124,23 @@ func (m *MultiSelect) OnChange(line []rune, pos int, key rune) (newLine []rune,
 	}
 	if oldFilter != m.filter {
 		// filter changed
-		options = m.filterOptions()
+		options = m.filterOptions(config)
 		if len(options) > 0 && len(options) <= m.selectedIndex {
 			m.selectedIndex = len(options) - 1
 		}
 	}
 	// paginate the options
+	// figure out the page size
+	pageSize := m.PageSize
+	// if we dont have a specific one
+	if pageSize == 0 {
+		// grab the global value
+		pageSize = config.PageSize
+	}
 
 	// TODO if we have started filtering and were looking at the end of a list
 	// and we have modified the filter then we should move the page back!
-	opts, idx := paginate(m.PageSize, options, m.selectedIndex)
+	opts, idx := paginate(pageSize, options, m.selectedIndex)
 
 	// render the options
 	m.Render(
@@ -138,42 +151,67 @@ func (m *MultiSelect) OnChange(line []rune, pos int, key rune) (newLine []rune,
 			Checked:       m.checked,
 			ShowHelp:      m.showingHelp,
 			PageEntries:   opts,
+			Config:        config,
 		},
 	)
-
-	// if we are not pressing ent
-	return line, 0, true
 }
 
-func (m *MultiSelect) filterOptions() []string {
-	filter := strings.ToLower(m.filter)
-	if filter == "" {
-		return m.Options
+func (m *MultiSelect) filterOptions(config *PromptConfig) []core.OptionAnswer {
+	// the filtered list
+	answers := []core.OptionAnswer{}
+
+	// if there is no filter applied
+	if m.filter == "" {
+		// return all of the options
+		return core.OptionAnswerList(m.Options)
+	}
+
+	// the filter to apply
+	filter := m.Filter
+	if filter == nil {
+		filter = config.Filter
 	}
-	answer := []string{}
-	for _, o := range m.Options {
-		if strings.Contains(strings.ToLower(o), filter) {
-			answer = append(answer, o)
+
+	// apply the filter to each option
+	for i, opt := range m.Options {
+		// i the filter says to include the option
+		if filter(m.filter, opt, i) {
+			answers = append(answers, core.OptionAnswer{
+				Index: i,
+				Value: opt,
+			})
 		}
 	}
-	return answer
+
+	// we're done here
+	return answers
 }
 
-func (m *MultiSelect) Prompt() (interface{}, error) {
+func (m *MultiSelect) Prompt(config *PromptConfig) (interface{}, error) {
 	// compute the default state
-	m.checked = make(map[string]bool)
+	m.checked = make(map[int]bool)
 	// if there is a default
-	if len(m.Default) > 0 {
-		for _, dflt := range m.Default {
-			for _, opt := range m.Options {
-				// if the option correponds to the default
-				if opt == dflt {
-					// we found our initial value
-					m.checked[opt] = true
-					// stop looking
-					break
+	if m.Default != nil {
+		// if the default is string values
+		if defaultValues, ok := m.Default.([]string); ok {
+			for _, dflt := range defaultValues {
+				for i, opt := range m.Options {
+					// if the option corresponds to the default
+					if opt == dflt {
+						// we found our initial value
+						m.checked[i] = true
+						// stop looking
+						break
+					}
 				}
 			}
+			// if the default value is index values
+		} else if defaultIndices, ok := m.Default.([]int); ok {
+			// go over every index we need to enable by default
+			for _, idx := range defaultIndices {
+				// and enable it
+				m.checked[idx] = true
+			}
 		}
 	}
 
@@ -183,8 +221,16 @@ func (m *MultiSelect) Prompt() (interface{}, error) {
 		return "", errors.New("please provide options to select from")
 	}
 
+	// figure out the page size
+	pageSize := m.PageSize
+	// if we dont have a specific one
+	if pageSize == 0 {
+		// grab the global value
+		pageSize = config.PageSize
+	}
 	// paginate the options
-	opts, idx := paginate(m.PageSize, m.Options, m.selectedIndex)
+	// build up a list of option answers
+	opts, idx := paginate(pageSize, core.OptionAnswerList(m.Options), m.selectedIndex)
 
 	cursor := m.NewCursor()
 	cursor.Hide()       // hide the cursor
@@ -198,6 +244,7 @@ func (m *MultiSelect) Prompt() (interface{}, error) {
 			SelectedIndex: idx,
 			Checked:       m.checked,
 			PageEntries:   opts,
+			Config:        config,
 		},
 	)
 	if err != nil {
@@ -220,15 +267,15 @@ func (m *MultiSelect) Prompt() (interface{}, error) {
 		if r == terminal.KeyEndTransmission {
 			break
 		}
-		m.OnChange(nil, 0, r)
+		m.OnChange(r, config)
 	}
 	m.filter = ""
 	m.FilterMessage = ""
 
-	answers := []string{}
-	for _, option := range m.Options {
-		if val, ok := m.checked[option]; ok && val {
-			answers = append(answers, option)
+	answers := []core.OptionAnswer{}
+	for i, option := range m.Options {
+		if val, ok := m.checked[i]; ok && val {
+			answers = append(answers, core.OptionAnswer{Value: option, Index: i})
 		}
 	}
 
@@ -236,7 +283,19 @@ func (m *MultiSelect) Prompt() (interface{}, error) {
 }
 
 // Cleanup removes the options section, and renders the ask like a normal question.
-func (m *MultiSelect) Cleanup(val interface{}) error {
+func (m *MultiSelect) Cleanup(config *PromptConfig, val interface{}) error {
+	// the answer to show
+	answer := ""
+	for _, ans := range val.([]core.OptionAnswer) {
+		answer = fmt.Sprintf("%s, %s", answer, ans.Value)
+	}
+
+	// if we answered anything
+	if len(answer) > 2 {
+		// remove the precending commas
+		answer = answer[2:]
+	}
+
 	// execute the output summary template with the answer
 	return m.Render(
 		MultiSelectQuestionTemplate,
@@ -244,8 +303,9 @@ func (m *MultiSelect) Cleanup(val interface{}) error {
 			MultiSelect:   *m,
 			SelectedIndex: m.selectedIndex,
 			Checked:       m.checked,
-			Answer:        strings.Join(val.([]string), ", "),
+			Answer:        answer,
 			ShowAnswer:    true,
+			Config:        config,
 		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/password.go b/vendor/github.com/AlecAivazis/survey/v2/password.go
similarity index 57%
rename from vendor/github.com/AlecAivazis/survey/password.go
rename to vendor/github.com/AlecAivazis/survey/v2/password.go
index 86c39a5..d80dc68 100644
--- a/vendor/github.com/AlecAivazis/survey/password.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/password.go
@@ -3,8 +3,8 @@ package survey
 import (
 	"fmt"
 
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/core"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
 /*
@@ -13,10 +13,10 @@ type is a string.
 
 	password := ""
 	prompt := &survey.Password{ Message: "Please type your password" }
-	survey.AskOne(prompt, &password, nil)
+	survey.AskOne(prompt, &password)
 */
 type Password struct {
-	core.Renderer
+	Renderer
 	Message string
 	Help    string
 }
@@ -24,20 +24,24 @@ type Password struct {
 type PasswordTemplateData struct {
 	Password
 	ShowHelp bool
+	Config   *PromptConfig
 }
 
-// Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
+// PasswordQuestionTemplate is a template with color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
 var PasswordQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }} {{color "reset"}}
-{{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ HelpInputRune }} for help]{{color "reset"}} {{end}}`
+{{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}}`
 
-func (p *Password) Prompt() (line interface{}, err error) {
+func (p *Password) Prompt(config *PromptConfig) (line interface{}, err error) {
 	// render the question template
 	out, err := core.RunTemplate(
 		PasswordQuestionTemplate,
-		PasswordTemplateData{Password: *p},
+		PasswordTemplateData{
+			Password: *p,
+			Config:   config,
+		},
 	)
 	fmt.Fprint(terminal.NewAnsiStdout(p.Stdio().Out), out)
 	if err != nil {
@@ -63,13 +67,17 @@ func (p *Password) Prompt() (line interface{}, err error) {
 			return string(line), err
 		}
 
-		if string(line) == string(core.HelpInputRune) {
+		if string(line) == config.HelpInput {
 			// terminal will echo the \n so we need to jump back up one row
 			cursor.PreviousLine(1)
 
 			err = p.Render(
 				PasswordQuestionTemplate,
-				PasswordTemplateData{Password: *p, ShowHelp: true},
+				PasswordTemplateData{
+					Password: *p,
+					ShowHelp: true,
+					Config:   config,
+				},
 			)
 			if err != nil {
 				return "", err
@@ -81,6 +89,6 @@ func (p *Password) Prompt() (line interface{}, err error) {
 }
 
 // Cleanup hides the string with a fixed number of characters.
-func (prompt *Password) Cleanup(val interface{}) error {
+func (prompt *Password) Cleanup(config *PromptConfig, val interface{}) error {
 	return nil
 }
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/core/renderer.go b/vendor/github.com/AlecAivazis/survey/v2/renderer.go
similarity index 76%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/core/renderer.go
rename to vendor/github.com/AlecAivazis/survey/v2/renderer.go
index 49dc955..b367262 100644
--- a/vendor/gopkg.in/AlecAivazis/survey.v1/core/renderer.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/renderer.go
@@ -1,10 +1,11 @@
-package core
+package survey
 
 import (
 	"fmt"
 	"strings"
 
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/core"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
 type Renderer struct {
@@ -13,7 +14,12 @@ type Renderer struct {
 	errorLineCount int
 }
 
-var ErrorTemplate = `{{color "red"}}{{ ErrorIcon }} Sorry, your reply was invalid: {{.Error}}{{color "reset"}}
+type ErrorTemplateData struct {
+	Error error
+	Icon  Icon
+}
+
+var ErrorTemplate = `{{color .Icon.Format }}{{ .Icon.Text }} Sorry, your reply was invalid: {{ .Error.Error }}{{color "reset"}}
 `
 
 func (r *Renderer) WithStdio(stdio terminal.Stdio) {
@@ -35,13 +41,17 @@ func (r *Renderer) NewCursor() *terminal.Cursor {
 	}
 }
 
-func (r *Renderer) Error(invalid error) error {
+func (r *Renderer) Error(config *PromptConfig, invalid error) error {
 	// since errors are printed on top we need to reset the prompt
 	// as well as any previous error print
 	r.resetPrompt(r.lineCount + r.errorLineCount)
+
 	// we just cleared the prompt lines
 	r.lineCount = 0
-	out, err := RunTemplate(ErrorTemplate, invalid)
+	out, err := core.RunTemplate(ErrorTemplate, &ErrorTemplateData{
+		Error: invalid,
+		Icon:  config.Icons.Error,
+	})
 	if err != nil {
 		return err
 	}
@@ -68,7 +78,7 @@ func (r *Renderer) resetPrompt(lines int) {
 func (r *Renderer) Render(tmpl string, data interface{}) error {
 	r.resetPrompt(r.lineCount)
 	// render the template summarizing the current state
-	out, err := RunTemplate(tmpl, data)
+	out, err := core.RunTemplate(tmpl, data)
 	if err != nil {
 		return err
 	}
diff --git a/vendor/github.com/AlecAivazis/survey/select.go b/vendor/github.com/AlecAivazis/survey/v2/select.go
similarity index 58%
rename from vendor/github.com/AlecAivazis/survey/select.go
rename to vendor/github.com/AlecAivazis/survey/v2/select.go
index a30c994..ac369ba 100644
--- a/vendor/github.com/AlecAivazis/survey/select.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/select.go
@@ -2,10 +2,9 @@ package survey
 
 import (
 	"errors"
-	"strings"
 
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/core"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
 /*
@@ -17,60 +16,69 @@ for them to select using the arrow keys and enter. Response type is a string.
 		Message: "Choose a color:",
 		Options: []string{"red", "blue", "green"},
 	}
-	survey.AskOne(prompt, &color, nil)
+	survey.AskOne(prompt, &color)
 */
 type Select struct {
-	core.Renderer
+	Renderer
 	Message       string
 	Options       []string
-	Default       string
+	Default       interface{}
 	Help          string
 	PageSize      int
 	VimMode       bool
 	FilterMessage string
+	Filter        func(filter string, value string, index int) bool
 	filter        string
 	selectedIndex int
 	useDefault    bool
 	showingHelp   bool
 }
 
-// the data available to the templates when processing
+// SelectTemplateData is the data available to the templates when processing
 type SelectTemplateData struct {
 	Select
-	PageEntries   []string
+	PageEntries   []core.OptionAnswer
 	SelectedIndex int
 	Answer        string
 	ShowAnswer    bool
 	ShowHelp      bool
+	Config        *PromptConfig
 }
 
 var SelectQuestionTemplate = `
-{{- if .ShowHelp }}{{- color "cyan"}}{{ HelpIcon }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
-{{- color "green+hb"}}{{ QuestionIcon }} {{color "reset"}}
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
 {{- color "default+hb"}}{{ .Message }}{{ .FilterMessage }}{{color "reset"}}
 {{- if .ShowAnswer}}{{color "cyan"}} {{.Answer}}{{color "reset"}}{{"\n"}}
 {{- else}}
-  {{- "  "}}{{- color "cyan"}}[Use arrows to move, type to filter{{- if and .Help (not .ShowHelp)}}, {{ HelpInputRune }} for more help{{end}}]{{color "reset"}}
+  {{- "  "}}{{- color "cyan"}}[Use arrows to move, type to filter{{- if and .Help (not .ShowHelp)}}, {{ .Config.HelpInput }} for more help{{end}}]{{color "reset"}}
   {{- "\n"}}
   {{- range $ix, $choice := .PageEntries}}
-    {{- if eq $ix $.SelectedIndex}}{{color "cyan+b"}}{{ SelectFocusIcon }} {{else}}{{color "default+hb"}}  {{end}}
-    {{- $choice}}
+    {{- if eq $ix $.SelectedIndex }}{{color $.Config.Icons.SelectFocus.Format }}{{ $.Config.Icons.SelectFocus.Text }} {{else}}{{color "default"}}  {{end}}
+    {{- $choice.Value}}
     {{- color "reset"}}{{"\n"}}
   {{- end}}
 {{- end}}`
 
 // OnChange is called on every keypress.
-func (s *Select) OnChange(line []rune, pos int, key rune) (newLine []rune, newPos int, ok bool) {
-	options := s.filterOptions()
+func (s *Select) OnChange(key rune, config *PromptConfig) bool {
+	options := s.filterOptions(config)
 	oldFilter := s.filter
 
-	// if the user pressed the enter key
-	if key == terminal.KeyEnter {
-		if s.selectedIndex < len(options) {
-			return []rune(options[s.selectedIndex]), 0, true
+	// if the user pressed the enter key and the index is a valid option
+	if key == terminal.KeyEnter || key == '\n' {
+		// if the selected index is a valid option
+		if len(options) > 0 && s.selectedIndex < len(options) {
+
+			// we're done (stop prompting the user)
+			return true
 		}
+
+		// we're not done (keep prompting)
+		return false
+
 		// if the user pressed the up arrow or 'k' to emulate vim
-	} else if key == terminal.KeyArrowUp || (s.VimMode && key == 'k') {
+	} else if key == terminal.KeyArrowUp || (s.VimMode && key == 'k') && len(options) > 0 {
 		s.useDefault = false
 
 		// if we are at the top of the list
@@ -81,8 +89,9 @@ func (s *Select) OnChange(line []rune, pos int, key rune) (newLine []rune, newPo
 			// otherwise we are not at the top of the list so decrement the selected index
 			s.selectedIndex--
 		}
+
 		// if the user pressed down or 'j' to emulate vim
-	} else if key == terminal.KeyArrowDown || (s.VimMode && key == 'j') {
+	} else if key == terminal.KeyArrowDown || (s.VimMode && key == 'j') && len(options) > 0 {
 		s.useDefault = false
 		// if we are at the bottom of the list
 		if s.selectedIndex == len(options)-1 {
@@ -93,7 +102,7 @@ func (s *Select) OnChange(line []rune, pos int, key rune) (newLine []rune, newPo
 			s.selectedIndex++
 		}
 		// only show the help message if we have one
-	} else if key == core.HelpInputRune && s.Help != "" {
+	} else if string(key) == config.HelpInput && s.Help != "" {
 		s.showingHelp = true
 		// if the user wants to toggle vim mode on/off
 	} else if key == terminal.KeyEscape {
@@ -123,17 +132,24 @@ func (s *Select) OnChange(line []rune, pos int, key rune) (newLine []rune, newPo
 	}
 	if oldFilter != s.filter {
 		// filter changed
-		options = s.filterOptions()
+		options = s.filterOptions(config)
 		if len(options) > 0 && len(options) <= s.selectedIndex {
 			s.selectedIndex = len(options) - 1
 		}
 	}
 
 	// figure out the options and index to render
+	// figure out the page size
+	pageSize := s.PageSize
+	// if we dont have a specific one
+	if pageSize == 0 {
+		// grab the global value
+		pageSize = config.PageSize
+	}
 
 	// TODO if we have started filtering and were looking at the end of a list
 	// and we have modified the filter then we should move the page back!
-	opts, idx := paginate(s.PageSize, options, s.selectedIndex)
+	opts, idx := paginate(pageSize, options, s.selectedIndex)
 
 	// render the options
 	s.Render(
@@ -143,31 +159,45 @@ func (s *Select) OnChange(line []rune, pos int, key rune) (newLine []rune, newPo
 			SelectedIndex: idx,
 			ShowHelp:      s.showingHelp,
 			PageEntries:   opts,
+			Config:        config,
 		},
 	)
 
-	// if we are not pressing ent
-	if len(options) <= s.selectedIndex {
-		return []rune{}, 0, false
-	}
-	return []rune(options[s.selectedIndex]), 0, true
+	// keep prompting
+	return false
 }
 
-func (s *Select) filterOptions() []string {
-	filter := strings.ToLower(s.filter)
-	if filter == "" {
-		return s.Options
+func (s *Select) filterOptions(config *PromptConfig) []core.OptionAnswer {
+	// the filtered list
+	answers := []core.OptionAnswer{}
+
+	// if there is no filter applied
+	if s.filter == "" {
+		return core.OptionAnswerList(s.Options)
+	}
+
+	// the filter to apply
+	filter := s.Filter
+	if filter == nil {
+		filter = config.Filter
 	}
-	answer := []string{}
-	for _, o := range s.Options {
-		if strings.Contains(strings.ToLower(o), filter) {
-			answer = append(answer, o)
+
+	//
+	for i, opt := range s.Options {
+		// i the filter says to include the option
+		if filter(s.filter, opt, i) {
+			answers = append(answers, core.OptionAnswer{
+				Index: i,
+				Value: opt,
+			})
 		}
 	}
-	return answer
+
+	// return the list of answers
+	return answers
 }
 
-func (s *Select) Prompt() (interface{}, error) {
+func (s *Select) Prompt(config *PromptConfig) (interface{}, error) {
 	// if there are no options to render
 	if len(s.Options) == 0 {
 		// we failed
@@ -180,7 +210,7 @@ func (s *Select) Prompt() (interface{}, error) {
 	if s.Default != "" {
 		// find the choice
 		for i, opt := range s.Options {
-			// if the option correponds to the default
+			// if the option corresponds to the default
 			if opt == s.Default {
 				// we found our initial value
 				sel = i
@@ -192,8 +222,16 @@ func (s *Select) Prompt() (interface{}, error) {
 	// save the selected index
 	s.selectedIndex = sel
 
+	// figure out the page size
+	pageSize := s.PageSize
+	// if we dont have a specific one
+	if pageSize == 0 {
+		// grab the global value
+		pageSize = config.PageSize
+	}
+
 	// figure out the options and index to render
-	opts, idx := paginate(s.PageSize, s.Options, sel)
+	opts, idx := paginate(pageSize, core.OptionAnswerList(s.Options), sel)
 
 	// ask the question
 	err := s.Render(
@@ -202,6 +240,7 @@ func (s *Select) Prompt() (interface{}, error) {
 			Select:        *s,
 			PageEntries:   opts,
 			SelectedIndex: idx,
+			Config:        config,
 		},
 	)
 	if err != nil {
@@ -225,47 +264,65 @@ func (s *Select) Prompt() (interface{}, error) {
 		if err != nil {
 			return "", err
 		}
-		if r == '\r' || r == '\n' {
-			break
-		}
 		if r == terminal.KeyInterrupt {
 			return "", terminal.InterruptErr
 		}
 		if r == terminal.KeyEndTransmission {
 			break
 		}
-		s.OnChange(nil, 0, r)
+		if s.OnChange(r, config) {
+			break
+		}
 	}
-	options := s.filterOptions()
+	options := s.filterOptions(config)
 	s.filter = ""
 	s.FilterMessage = ""
 
+	// the index to report
 	var val string
 	// if we are supposed to use the default value
 	if s.useDefault || s.selectedIndex >= len(options) {
 		// if there is a default value
-		if s.Default != "" {
-			// use the default value
-			val = s.Default
+		if s.Default != nil {
+			// if the default is a string
+			if defaultString, ok := s.Default.(string); ok {
+				// use the default value
+				val = defaultString
+				// the default value could also be an interpret which is interpretted as the index
+			} else if defaultIndex, ok := s.Default.(int); ok {
+				val = s.Options[defaultIndex]
+			} else {
+				return val, errors.New("default value of select must be an int or string")
+			}
 		} else if len(options) > 0 {
 			// there is no default value so use the first
-			val = options[0]
+			val = options[0].Value
 		}
 		// otherwise the selected index points to the value
 	} else if s.selectedIndex < len(options) {
 		// the
-		val = options[s.selectedIndex]
+		val = options[s.selectedIndex].Value
 	}
-	return val, err
+
+	// now that we have the value lets go hunt down the right index to return
+	idx = -1
+	for i, optionValue := range s.Options {
+		if optionValue == val {
+			idx = i
+		}
+	}
+
+	return core.OptionAnswer{Value: val, Index: idx}, err
 }
 
-func (s *Select) Cleanup(val interface{}) error {
+func (s *Select) Cleanup(config *PromptConfig, val interface{}) error {
 	return s.Render(
 		SelectQuestionTemplate,
 		SelectTemplateData{
 			Select:     *s,
-			Answer:     val.(string),
+			Answer:     val.(core.OptionAnswer).Value,
 			ShowAnswer: true,
+			Config:     config,
 		},
 	)
 }
diff --git a/vendor/github.com/AlecAivazis/survey/survey.go b/vendor/github.com/AlecAivazis/survey/v2/survey.go
similarity index 50%
rename from vendor/github.com/AlecAivazis/survey/survey.go
rename to vendor/github.com/AlecAivazis/survey/v2/survey.go
index 73f0bf5..eaa8439 100644
--- a/vendor/github.com/AlecAivazis/survey/survey.go
+++ b/vendor/github.com/AlecAivazis/survey/v2/survey.go
@@ -4,21 +4,84 @@ import (
 	"errors"
 	"io"
 	"os"
+	"strings"
 
-	"gopkg.in/AlecAivazis/survey.v1/core"
-	"gopkg.in/AlecAivazis/survey.v1/terminal"
+	"github.com/AlecAivazis/survey/v2/core"
+	"github.com/AlecAivazis/survey/v2/terminal"
 )
 
-// PageSize is the default maximum number of items to show in select/multiselect prompts
-var PageSize = 7
-
 // DefaultAskOptions is the default options on ask, using the OS stdio.
-var DefaultAskOptions = AskOptions{
-	Stdio: terminal.Stdio{
-		In:  os.Stdin,
-		Out: os.Stdout,
-		Err: os.Stderr,
-	},
+func defaultAskOptions() *AskOptions {
+	return &AskOptions{
+		Stdio: terminal.Stdio{
+			In:  os.Stdin,
+			Out: os.Stdout,
+			Err: os.Stderr,
+		},
+		PromptConfig: PromptConfig{
+			PageSize:  7,
+			HelpInput: "?",
+			Icons: IconSet{
+				Error: Icon{
+					Text:   "X",
+					Format: "red",
+				},
+				Help: Icon{
+					Text:   "?",
+					Format: "cyan",
+				},
+				Question: Icon{
+					Text:   "?",
+					Format: "green+hb",
+				},
+				MarkedOption: Icon{
+					Text:   "[x]",
+					Format: "green",
+				},
+				UnmarkedOption: Icon{
+					Text:   "[ ]",
+					Format: "default+hb",
+				},
+				SelectFocus: Icon{
+					Text:   ">",
+					Format: "cyan+b",
+				},
+			},
+			Filter: func(filter string, value string, index int) (include bool) {
+				filter = strings.ToLower(filter)
+
+				// include this option if it matches
+				return strings.Contains(strings.ToLower(value), filter)
+			},
+		},
+	}
+}
+func defaultPromptConfig() *PromptConfig {
+	return &defaultAskOptions().PromptConfig
+}
+
+func defaultIcons() *IconSet {
+	return &defaultPromptConfig().Icons
+}
+
+// OptionAnswer is an ergonomic alias for core.OptionAnswer
+type OptionAnswer = core.OptionAnswer
+
+// Icon holds the text and format to show for a particular icon
+type Icon struct {
+	Text   string
+	Format string
+}
+
+// IconSet holds the icons to use for various prompts
+type IconSet struct {
+	HelpInput      Icon
+	Error          Icon
+	Help           Icon
+	Question       Icon
+	MarkedOption   Icon
+	UnmarkedOption Icon
+	SelectFocus    Icon
 }
 
 // Validator is a function passed to a Question after a user has provided a response.
@@ -41,12 +104,25 @@ type Question struct {
 	Transform Transformer
 }
 
+// PromptConfig holds the global configuration for a prompt
+type PromptConfig struct {
+	PageSize  int
+	Icons     IconSet
+	HelpInput string
+	Filter    func(filter string, option string, index int) bool
+}
+
 // Prompt is the primary interface for the objects that can take user input
 // and return a response.
 type Prompt interface {
-	Prompt() (interface{}, error)
-	Cleanup(interface{}) error
-	Error(error) error
+	Prompt(config *PromptConfig) (interface{}, error)
+	Cleanup(*PromptConfig, interface{}) error
+	Error(*PromptConfig, error) error
+}
+
+// PromptAgainer Interface for Prompts that support prompting again after invalid input
+type PromptAgainer interface {
+	PromptAgain(config *PromptConfig, invalid interface{}, err error) (interface{}, error)
 }
 
 // AskOpt allows setting optional ask options.
@@ -54,7 +130,9 @@ type AskOpt func(options *AskOptions) error
 
 // AskOptions provides additional options on ask.
 type AskOptions struct {
-	Stdio terminal.Stdio
+	Stdio        terminal.Stdio
+	Validators   []Validator
+	PromptConfig PromptConfig
 }
 
 // WithStdio specifies the standard input, output and error files survey
@@ -68,10 +146,64 @@ func WithStdio(in terminal.FileReader, out terminal.FileWriter, err io.Writer) A
 	}
 }
 
+// WithFilter specifies the default filter to use when asking questions.
+func WithFilter(filter func(filter string, value string, index int) (include bool)) AskOpt {
+	return func(options *AskOptions) error {
+		// save the filter internally
+		options.PromptConfig.Filter = filter
+
+		return nil
+	}
+}
+
+// WithValidator specifies a validator to use while prompting the user
+func WithValidator(v Validator) AskOpt {
+	return func(options *AskOptions) error {
+		// add the provided validator to the list
+		options.Validators = append(options.Validators, v)
+
+		// nothing went wrong
+		return nil
+	}
+}
+
 type wantsStdio interface {
 	WithStdio(terminal.Stdio)
 }
 
+// WithPageSize sets the default page size used by prompts
+func WithPageSize(pageSize int) AskOpt {
+	return func(options *AskOptions) error {
+		// set the page size
+		options.PromptConfig.PageSize = pageSize
+
+		// nothing went wrong
+		return nil
+	}
+}
+
+// WithHelpInput changes the character that prompts look for to give the user helpful information.
+func WithHelpInput(r rune) AskOpt {
+	return func(options *AskOptions) error {
+		// set the input character
+		options.PromptConfig.HelpInput = string(r)
+
+		// nothing went wrong
+		return nil
+	}
+}
+
+// WithIcons sets the icons that will be used when prompting the user
+func WithIcons(setIcons func(*IconSet)) AskOpt {
+	return func(options *AskOptions) error {
+		// update the default icons with whatever the user says
+		setIcons(&options.PromptConfig.Icons)
+
+		// nothing went wrong
+		return nil
+	}
+}
+
 /*
 AskOne performs the prompt for a single prompt and asks for validation if required.
 Response types should be something that can be casted from the response type designated
@@ -82,11 +214,11 @@ in the documentation. For example:
 		Message: "name",
 	}
 
-	survey.AskOne(prompt, &name, nil)
+	survey.AskOne(prompt, &name)
 
 */
-func AskOne(p Prompt, response interface{}, v Validator, opts ...AskOpt) error {
-	err := Ask([]*Question{{Prompt: p, Validate: v}}, response, opts...)
+func AskOne(p Prompt, response interface{}, opts ...AskOpt) error {
+	err := Ask([]*Question{{Prompt: p}}, response, opts...)
 	if err != nil {
 		return err
 	}
@@ -118,10 +250,13 @@ matching name. For example:
 	err := survey.Ask(qs, &answers)
 */
 func Ask(qs []*Question, response interface{}, opts ...AskOpt) error {
-
-	options := DefaultAskOptions
+	// build up the configuration options
+	options := defaultAskOptions()
 	for _, opt := range opts {
-		if err := opt(&options); err != nil {
+		if opt == nil {
+			continue
+		}
+		if err := opt(options); err != nil {
 			return err
 		}
 	}
@@ -140,24 +275,40 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error {
 		}
 
 		// grab the user input and save it
-		ans, err := q.Prompt.Prompt()
+		ans, err := q.Prompt.Prompt(&options.PromptConfig)
 		// if there was a problem
 		if err != nil {
 			return err
 		}
 
-		// if there is a validate handler for this question
+		// build up a list of validators that we have to apply to this question
+		validators := []Validator{}
+
+		// make sure to include the question specific one
 		if q.Validate != nil {
+			validators = append(validators, q.Validate)
+		}
+		// add any "global" validators
+		for _, validator := range options.Validators {
+			validators = append(validators, validator)
+		}
+
+		// apply every validator to thte response
+		for _, validator := range validators {
 			// wait for a valid response
-			for invalid := q.Validate(ans); invalid != nil; invalid = q.Validate(ans) {
-				err := q.Prompt.Error(invalid)
+			for invalid := validator(ans); invalid != nil; invalid = validator(ans) {
+				err := q.Prompt.Error(&options.PromptConfig, invalid)
 				// if there was a problem
 				if err != nil {
 					return err
 				}
 
 				// ask for more input
-				ans, err = q.Prompt.Prompt()
+				if promptAgainer, ok := q.Prompt.(PromptAgainer); ok {
+					ans, err = promptAgainer.PromptAgain(&options.PromptConfig, ans, invalid)
+				} else {
+					ans, err = q.Prompt.Prompt(&options.PromptConfig)
+				}
 				// if there was a problem
 				if err != nil {
 					return err
@@ -175,7 +326,7 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error {
 		}
 
 		// tell the prompt to cleanup with the validated value
-		q.Prompt.Cleanup(ans)
+		q.Prompt.Cleanup(&options.PromptConfig, ans)
 
 		// if something went wrong
 		if err != nil {
@@ -198,19 +349,7 @@ func Ask(qs []*Question, response interface{}, opts ...AskOpt) error {
 
 // paginate returns a single page of choices given the page size, the total list of
 // possible choices, and the current selected index in the total list.
-func paginate(page int, choices []string, sel int) ([]string, int) {
-	// the number of elements to show in a single page
-	var pageSize int
-	// if the select has a specific page size
-	if page != 0 {
-		// use the specified one
-		pageSize = page
-		// otherwise the select does not have a page size
-	} else {
-		// use the package default
-		pageSize = PageSize
-	}
-
+func paginate(pageSize int, choices []core.OptionAnswer, sel int) ([]core.OptionAnswer, int) {
 	var start, end, cursor int
 
 	if len(choices) < pageSize {
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/LICENSE.txt b/vendor/github.com/AlecAivazis/survey/v2/terminal/LICENSE.txt
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/LICENSE.txt
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/LICENSE.txt
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/README.md b/vendor/github.com/AlecAivazis/survey/v2/terminal/README.md
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/README.md
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/README.md
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/buffered_reader.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/buffered_reader.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/buffered_reader.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/buffered_reader.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/cursor.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/cursor.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/cursor.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/cursor_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/cursor_windows.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/cursor_windows.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/display.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/display.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display_posix.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display_posix.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/display_posix.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/display_windows.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/display_windows.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/error.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/error.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/error.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/error.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/output.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/output.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/output.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/output.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/output_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/output_windows.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/output_windows.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/runereader.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_bsd.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_bsd.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_bsd.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_bsd.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_linux.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_linux.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_linux.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_linux.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_posix.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_posix.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_posix.go
diff --git a/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_ppc64le.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_ppc64le.go
new file mode 100644
index 0000000..ae4eb09
--- /dev/null
+++ b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_ppc64le.go
@@ -0,0 +1,7 @@
+// +build ppc64le,linux
+
+package terminal
+
+// Used syscall numbers from https://github.com/golang/go/blob/master/src/syscall/ztypes_linux_ppc64le.go
+const ioctlReadTermios = 0x402c7413  // syscall.TCGETS
+const ioctlWriteTermios = 0x802c7414 // syscall.TCSETS
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_windows.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/runereader_windows.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/runereader_windows.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/sequences.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/sequences.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/sequences.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/stdio.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/stdio.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/stdio.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/stdio.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/syscall_windows.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/syscall_windows.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/syscall_windows.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/syscall_windows.go
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/terminal/terminal.go b/vendor/github.com/AlecAivazis/survey/v2/terminal/terminal.go
similarity index 100%
rename from vendor/gopkg.in/AlecAivazis/survey.v1/terminal/terminal.go
rename to vendor/github.com/AlecAivazis/survey/v2/terminal/terminal.go
diff --git a/vendor/github.com/AlecAivazis/survey/transform.go b/vendor/github.com/AlecAivazis/survey/v2/transform.go
similarity index 100%
rename from vendor/github.com/AlecAivazis/survey/transform.go
rename to vendor/github.com/AlecAivazis/survey/v2/transform.go
diff --git a/vendor/github.com/AlecAivazis/survey/validate.go b/vendor/github.com/AlecAivazis/survey/v2/validate.go
similarity index 100%
rename from vendor/github.com/AlecAivazis/survey/validate.go
rename to vendor/github.com/AlecAivazis/survey/v2/validate.go
diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go
index e17a547..404e10c 100644
--- a/vendor/github.com/mattn/go-colorable/colorable_windows.go
+++ b/vendor/github.com/mattn/go-colorable/colorable_windows.go
@@ -29,6 +29,15 @@ const (
 	backgroundMask      = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity)
 )
 
+const (
+	genericRead  = 0x80000000
+	genericWrite = 0x40000000
+)
+
+const (
+	consoleTextmodeBuffer = 0x1
+)
+
 type wchar uint16
 type short int16
 type dword uint32
@@ -69,14 +78,17 @@ var (
 	procGetConsoleCursorInfo       = kernel32.NewProc("GetConsoleCursorInfo")
 	procSetConsoleCursorInfo       = kernel32.NewProc("SetConsoleCursorInfo")
 	procSetConsoleTitle            = kernel32.NewProc("SetConsoleTitleW")
+	procCreateConsoleScreenBuffer  = kernel32.NewProc("CreateConsoleScreenBuffer")
 )
 
 // Writer provide colorable Writer to the console
 type Writer struct {
-	out     io.Writer
-	handle  syscall.Handle
-	oldattr word
-	oldpos  coord
+	out       io.Writer
+	handle    syscall.Handle
+	althandle syscall.Handle
+	oldattr   word
+	oldpos    coord
+	rest      bytes.Buffer
 }
 
 // NewColorable return new instance of Writer which handle escape sequence from File.
@@ -407,7 +419,18 @@ func (w *Writer) Write(data []byte) (n int, err error) {
 	var csbi consoleScreenBufferInfo
 	procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
 
-	er := bytes.NewReader(data)
+	handle := w.handle
+
+	var er *bytes.Reader
+	if w.rest.Len() > 0 {
+		var rest bytes.Buffer
+		w.rest.WriteTo(&rest)
+		w.rest.Reset()
+		rest.Write(data)
+		er = bytes.NewReader(rest.Bytes())
+	} else {
+		er = bytes.NewReader(data)
+	}
 	var bw [1]byte
 loop:
 	for {
@@ -425,29 +448,55 @@ loop:
 			break loop
 		}
 
-		if c2 == ']' {
-			if err := doTitleSequence(er); err != nil {
+		switch c2 {
+		case '>':
+			continue
+		case ']':
+			w.rest.WriteByte(c1)
+			w.rest.WriteByte(c2)
+			er.WriteTo(&w.rest)
+			if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 {
 				break loop
 			}
+			er = bytes.NewReader(w.rest.Bytes()[2:])
+			err := doTitleSequence(er)
+			if err != nil {
+				break loop
+			}
+			w.rest.Reset()
 			continue
-		}
-		if c2 != 0x5b {
+		// https://github.com/mattn/go-colorable/issues/27
+		case '7':
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
+			w.oldpos = csbi.cursorPosition
+			continue
+		case '8':
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
+			continue
+		case 0x5b:
+			// execute part after switch
+		default:
 			continue
 		}
 
+		w.rest.WriteByte(c1)
+		w.rest.WriteByte(c2)
+		er.WriteTo(&w.rest)
+
 		var buf bytes.Buffer
 		var m byte
-		for {
-			c, err := er.ReadByte()
-			if err != nil {
-				break loop
-			}
+		for i, c := range w.rest.Bytes()[2:] {
 			if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' {
 				m = c
+				er = bytes.NewReader(w.rest.Bytes()[2+i+1:])
+				w.rest.Reset()
 				break
 			}
 			buf.Write([]byte(string(c)))
 		}
+		if m == 0 {
+			break loop
+		}
 
 		switch m {
 		case 'A':
@@ -455,61 +504,64 @@ loop:
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.y -= short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'B':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.y += short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'C':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.x += short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'D':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.x -= short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			if csbi.cursorPosition.x < 0 {
+				csbi.cursorPosition.x = 0
+			}
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'E':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.x = 0
 			csbi.cursorPosition.y += short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'F':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.x = 0
 			csbi.cursorPosition.y -= short(n)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'G':
 			n, err = strconv.Atoi(buf.String())
 			if err != nil {
 				continue
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			csbi.cursorPosition.x = short(n - 1)
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'H', 'f':
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			if buf.Len() > 0 {
 				token := strings.Split(buf.String(), ";")
 				switch len(token) {
@@ -534,7 +586,7 @@ loop:
 			} else {
 				csbi.cursorPosition.y = 0
 			}
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition)))
 		case 'J':
 			n := 0
 			if buf.Len() > 0 {
@@ -545,20 +597,20 @@ loop:
 			}
 			var count, written dword
 			var cursor coord
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			switch n {
 			case 0:
 				cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
-				count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
+				count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)
 			case 1:
 				cursor = coord{x: csbi.window.left, y: csbi.window.top}
-				count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.window.top-csbi.cursorPosition.y)*csbi.size.x)
+				count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x)
 			case 2:
 				cursor = coord{x: csbi.window.left, y: csbi.window.top}
-				count = dword(csbi.size.x - csbi.cursorPosition.x + (csbi.size.y-csbi.cursorPosition.y)*csbi.size.x)
+				count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x)
 			}
-			procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
-			procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+			procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+			procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
 		case 'K':
 			n := 0
 			if buf.Len() > 0 {
@@ -567,28 +619,28 @@ loop:
 					continue
 				}
 			}
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			var cursor coord
 			var count, written dword
 			switch n {
 			case 0:
-				cursor = coord{x: csbi.cursorPosition.x + 1, y: csbi.cursorPosition.y}
-				count = dword(csbi.size.x - csbi.cursorPosition.x - 1)
+				cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y}
+				count = dword(csbi.size.x - csbi.cursorPosition.x)
 			case 1:
-				cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
+				cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}
 				count = dword(csbi.size.x - csbi.cursorPosition.x)
 			case 2:
-				cursor = coord{x: csbi.window.left, y: csbi.window.top + csbi.cursorPosition.y}
+				cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y}
 				count = dword(csbi.size.x)
 			}
-			procFillConsoleOutputCharacter.Call(uintptr(w.handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
-			procFillConsoleOutputAttribute.Call(uintptr(w.handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+			procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
+			procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written)))
 		case 'm':
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			attr := csbi.attributes
 			cs := buf.String()
 			if cs == "" {
-				procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr))
+				procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr))
 				continue
 			}
 			token := strings.Split(cs, ";")
@@ -627,6 +679,21 @@ loop:
 								attr |= n256foreAttr[n256]
 								i += 2
 							}
+						} else if len(token) == 5 && token[i+1] == "2" {
+							var r, g, b int
+							r, _ = strconv.Atoi(token[i+2])
+							g, _ = strconv.Atoi(token[i+3])
+							b, _ = strconv.Atoi(token[i+4])
+							i += 4
+							if r > 127 {
+								attr |= foregroundRed
+							}
+							if g > 127 {
+								attr |= foregroundGreen
+							}
+							if b > 127 {
+								attr |= foregroundBlue
+							}
 						} else {
 							attr = attr & (w.oldattr & backgroundMask)
 						}
@@ -654,6 +721,21 @@ loop:
 								attr |= n256backAttr[n256]
 								i += 2
 							}
+						} else if len(token) == 5 && token[i+1] == "2" {
+							var r, g, b int
+							r, _ = strconv.Atoi(token[i+2])
+							g, _ = strconv.Atoi(token[i+3])
+							b, _ = strconv.Atoi(token[i+4])
+							i += 4
+							if r > 127 {
+								attr |= backgroundRed
+							}
+							if g > 127 {
+								attr |= backgroundGreen
+							}
+							if b > 127 {
+								attr |= backgroundBlue
+							}
 						} else {
 							attr = attr & (w.oldattr & foregroundMask)
 						}
@@ -685,38 +767,52 @@ loop:
 							attr |= backgroundBlue
 						}
 					}
-					procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr))
+					procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr))
 				}
 			}
 		case 'h':
 			var ci consoleCursorInfo
 			cs := buf.String()
 			if cs == "5>" {
-				procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 				ci.visible = 0
-				procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 			} else if cs == "?25" {
-				procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 				ci.visible = 1
-				procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
+			} else if cs == "?1049" {
+				if w.althandle == 0 {
+					h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0)
+					w.althandle = syscall.Handle(h)
+					if w.althandle != 0 {
+						handle = w.althandle
+					}
+				}
 			}
 		case 'l':
 			var ci consoleCursorInfo
 			cs := buf.String()
 			if cs == "5>" {
-				procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 				ci.visible = 1
-				procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 			} else if cs == "?25" {
-				procGetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
 				ci.visible = 0
-				procSetConsoleCursorInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&ci)))
+				procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci)))
+			} else if cs == "?1049" {
+				if w.althandle != 0 {
+					syscall.CloseHandle(w.althandle)
+					w.althandle = 0
+					handle = w.handle
+				}
 			}
 		case 's':
-			procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi)))
+			procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi)))
 			w.oldpos = csbi.cursorPosition
 		case 'u':
-			procSetConsoleCursorPosition.Call(uintptr(w.handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
+			procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos)))
 		}
 	}
 
diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod
new file mode 100644
index 0000000..ef3ca9d
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/go.mod
@@ -0,0 +1,3 @@
+module github.com/mattn/go-colorable
+
+require github.com/mattn/go-isatty v0.0.8
diff --git a/vendor/github.com/mattn/go-colorable/go.sum b/vendor/github.com/mattn/go-colorable/go.sum
new file mode 100644
index 0000000..2c12960
--- /dev/null
+++ b/vendor/github.com/mattn/go-colorable/go.sum
@@ -0,0 +1,4 @@
+github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/vendor/github.com/mattn/go-isatty/go.mod b/vendor/github.com/mattn/go-isatty/go.mod
new file mode 100644
index 0000000..f310320
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/go.mod
@@ -0,0 +1,3 @@
+module github.com/mattn/go-isatty
+
+require golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223
diff --git a/vendor/github.com/mattn/go-isatty/go.sum b/vendor/github.com/mattn/go-isatty/go.sum
new file mode 100644
index 0000000..426c897
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/go.sum
@@ -0,0 +1,2 @@
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux.go b/vendor/github.com/mattn/go-isatty/isatty_android.go
similarity index 62%
rename from vendor/github.com/mattn/go-isatty/isatty_linux.go
rename to vendor/github.com/mattn/go-isatty/isatty_android.go
index 7384cf9..d3567cb 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_linux.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_android.go
@@ -1,5 +1,4 @@
-// +build linux
-// +build !appengine,!ppc64,!ppc64le
+// +build android
 
 package isatty
 
@@ -16,3 +15,9 @@ func IsTerminal(fd uintptr) bool {
 	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
 	return err == 0
 }
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+	return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_appengine.go b/vendor/github.com/mattn/go-isatty/isatty_appengine.go
deleted file mode 100644
index 9584a98..0000000
--- a/vendor/github.com/mattn/go-isatty/isatty_appengine.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// +build appengine
-
-package isatty
-
-// IsTerminal returns true if the file descriptor is terminal which
-// is always false on on appengine classic which is a sandboxed PaaS.
-func IsTerminal(fd uintptr) bool {
-	return false
-}
-
-// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
-// terminal. This is also always false on this environment.
-func IsCygwinTerminal(fd uintptr) bool {
-	return false
-}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_bsd.go b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
index 42f2514..07e9303 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_bsd.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_bsd.go
@@ -16,3 +16,9 @@ func IsTerminal(fd uintptr) bool {
 	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
 	return err == 0
 }
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+	return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go b/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
deleted file mode 100644
index 44e5d21..0000000
--- a/vendor/github.com/mattn/go-isatty/isatty_linux_ppc64x.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// +build linux
-// +build ppc64 ppc64le
-
-package isatty
-
-import (
-	"unsafe"
-
-	syscall "golang.org/x/sys/unix"
-)
-
-const ioctlReadTermios = syscall.TCGETS
-
-// IsTerminal return true if the file descriptor is terminal.
-func IsTerminal(fd uintptr) bool {
-	var termios syscall.Termios
-	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
-	return err == 0
-}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_others.go b/vendor/github.com/mattn/go-isatty/isatty_others.go
index 9d8b4a5..ff714a3 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_others.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_others.go
@@ -1,9 +1,14 @@
-// +build !windows
-// +build !appengine
+// +build appengine js nacl
 
 package isatty
 
-// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// IsTerminal returns true if the file descriptor is terminal which
+// is always false on js and appengine classic which is a sandboxed PaaS.
+func IsTerminal(fd uintptr) bool {
+	return false
+}
+
+// IsCygwinTerminal() return true if the file descriptor is a cygwin or msys2
 // terminal. This is also always false on this environment.
 func IsCygwinTerminal(fd uintptr) bool {
 	return false
diff --git a/vendor/github.com/mattn/go-isatty/isatty_solaris.go b/vendor/github.com/mattn/go-isatty/isatty_solaris.go
index 1f0c6bf..bdd5c79 100644
--- a/vendor/github.com/mattn/go-isatty/isatty_solaris.go
+++ b/vendor/github.com/mattn/go-isatty/isatty_solaris.go
@@ -14,3 +14,9 @@ func IsTerminal(fd uintptr) bool {
 	err := unix.IoctlSetTermio(int(fd), unix.TCGETA, &termio)
 	return err == nil
 }
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+	return false
+}
diff --git a/vendor/github.com/mattn/go-isatty/isatty_tcgets.go b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
new file mode 100644
index 0000000..453b025
--- /dev/null
+++ b/vendor/github.com/mattn/go-isatty/isatty_tcgets.go
@@ -0,0 +1,19 @@
+// +build linux aix
+// +build !appengine
+// +build !android
+
+package isatty
+
+import "golang.org/x/sys/unix"
+
+// IsTerminal return true if the file descriptor is terminal.
+func IsTerminal(fd uintptr) bool {
+	_, err := unix.IoctlGetTermios(int(fd), unix.TCGETS)
+	return err == nil
+}
+
+// IsCygwinTerminal return true if the file descriptor is a cygwin or msys2
+// terminal. This is also always false on this environment.
+func IsCygwinTerminal(fd uintptr) bool {
+	return false
+}
diff --git a/vendor/github.com/nats-io/cliprompts/go.sum b/vendor/github.com/nats-io/cliprompts/go.sum
deleted file mode 100644
index ada52dd..0000000
--- a/vendor/github.com/nats-io/cliprompts/go.sum
+++ /dev/null
@@ -1,28 +0,0 @@
-github.com/AlecAivazis/survey v1.7.0 h1:Hri7k8HCumnCO2ks0BjjYZdnLVL3b/nvfUjUUVJtHGs=
-github.com/AlecAivazis/survey v1.7.0/go.mod h1:MVECab6WqEH1aXhj8nKIwF7HEAJAj2bhhGiSjNy3wII=
-github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
-github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
-github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
-github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
-github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
-github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
-github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
-github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U=
-github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/sys v0.0.0-20180606202747-9527bec2660b h1:5rOiLYVqtE+JehJPVJTXQJaP8aT3cpJC1Iy22+5WLFU=
-golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-gopkg.in/AlecAivazis/survey.v1 v1.8.7 h1:oBJqtgsyBLg9K5FK9twNUbcPnbCPoh+R9a+7nag3qJM=
-gopkg.in/AlecAivazis/survey.v1 v1.8.7/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA=
diff --git a/vendor/github.com/nats-io/cliprompts/open_darwin.go b/vendor/github.com/nats-io/cliprompts/open_darwin.go
deleted file mode 100644
index 8daf718..0000000
--- a/vendor/github.com/nats-io/cliprompts/open_darwin.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build darwin
-
-package cliprompts
-
-import "os/exec"
-
-func open(url string) *exec.Cmd {
-	return exec.Command("open", url)
-}
diff --git a/vendor/github.com/nats-io/cliprompts/open_linux.go b/vendor/github.com/nats-io/cliprompts/open_linux.go
deleted file mode 100644
index 2324d34..0000000
--- a/vendor/github.com/nats-io/cliprompts/open_linux.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build !windows,!darwin
-
-package cliprompts
-
-import "os/exec"
-
-func open(url string) *exec.Cmd {
-	return nil
-}
diff --git a/vendor/github.com/nats-io/cliprompts/open_windows.go b/vendor/github.com/nats-io/cliprompts/open_windows.go
deleted file mode 100644
index 47ebd97..0000000
--- a/vendor/github.com/nats-io/cliprompts/open_windows.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// +build windows
-
-package cliprompts
-
-import "os/exec"
-
-func open(url string) *exec.Cmd {
-	return nil
-}
diff --git a/vendor/github.com/nats-io/cliprompts/prompts.go b/vendor/github.com/nats-io/cliprompts/prompts.go
deleted file mode 100644
index 68bab36..0000000
--- a/vendor/github.com/nats-io/cliprompts/prompts.go
+++ /dev/null
@@ -1,168 +0,0 @@
-package cliprompts
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"net/mail"
-	"net/url"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"github.com/mitchellh/go-homedir"
-)
-
-type Logger func(args ...interface{})
-
-type Validator func(string) error
-
-var cli PromptLib
-
-// set a Logger during a test (cli.LogFn = t.Log) to debug interactive prompts
-var LogFn Logger
-
-var output io.Writer = os.Stdout
-
-type PromptLib interface {
-	Prompt(label string, value string, edit bool, validator Validator) (string, error)
-	PromptWithHelp(label string, value string, edit bool, validator Validator, help string) (string, error)
-	PromptYN(m string, defaultValue bool) (bool, error)
-	PromptSecret(m string) (string, error)
-	PromptChoices(m string, value string, choices []string) (int, error)
-	PromptMultipleChoices(m string, choices []string) ([]int, error)
-}
-
-func init() {
-	ResetPromptLib()
-	LogFn = nil
-}
-
-func SetPromptLib(p PromptLib) {
-	cli = p
-}
-
-func ResetPromptLib() {
-	SetPromptLib(&SurveyUI{})
-	LogFn = nil
-}
-
-func SetOutput(out io.Writer) {
-	output = out
-}
-
-func Underline(s string) string {
-	return fmt.Sprintf("\xff\033[4m\xff%s\xff\033[0m\xff", s)
-}
-
-func Bold(s string) string {
-	return fmt.Sprintf("\033[1m%s\033[0m", s)
-}
-
-func Italic(s string) string {
-	return fmt.Sprintf("\033[3m%s\033[0m", s)
-}
-
-func Prompt(label string, value string, edit bool, validator Validator) (string, error) {
-	return cli.Prompt(label, value, edit, validator)
-}
-
-func PromptWithHelp(label string, value string, edit bool, validator Validator, help string) (string, error) {
-	return cli.PromptWithHelp(label, value, edit, validator, help)
-}
-
-func PromptYN(m string) (bool, error) {
-	return cli.PromptYN(m, true)
-}
-
-func PromptBoolean(m string, defaultValue bool) (bool, error) {
-	return cli.PromptYN(m, defaultValue)
-}
-
-func PromptSecret(m string) (string, error) {
-	return cli.PromptSecret(m)
-}
-
-func PromptChoices(m string, value string, choices []string) (int, error) {
-	return cli.PromptChoices(m, value, choices)
-}
-
-func PromptMultipleChoices(m string, choices []string) ([]int, error) {
-	return cli.PromptMultipleChoices(m, choices)
-}
-
-func EmailValidator() Validator {
-	return func(input string) error {
-		if input != "" {
-			_, err := mail.ParseAddress(input)
-			return err
-		}
-		return nil
-	}
-}
-
-func LengthValidator(min int) Validator {
-	return func(input string) error {
-		if len(input) >= min {
-			return nil
-		}
-		return errors.New("value is too short")
-	}
-}
-
-func PathOrURLValidator() Validator {
-	return func(s string) error {
-		if u, err := url.Parse(s); err == nil && u.Scheme != "" {
-			return nil
-		}
-
-		v, err := homedir.Expand(s)
-		if err != nil {
-			return err
-		}
-		v, err = filepath.Abs(v)
-		if err != nil {
-			return err
-		}
-		info, err := os.Stat(v)
-		if err != nil {
-			return err
-		}
-		if !info.Mode().IsRegular() {
-			return errors.New("path is not a file")
-		}
-		return nil
-	}
-}
-
-func URLValidator(protocol ...string) Validator {
-	return func(s string) error {
-		s = strings.TrimSpace(s)
-		if s == "" {
-			return errors.New("url cannot be empty")
-		}
-		u, err := url.Parse(s)
-		if err != nil {
-			return err
-		}
-		scheme := strings.ToLower(u.Scheme)
-
-		ok := false
-		for _, v := range protocol {
-			if scheme == v {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			var protos []string
-			protos = append(protos, protocol...)
-			return fmt.Errorf("scheme %q is not supported (%v)", scheme, strings.Join(protos, ", "))
-		}
-		if u.Host == "" {
-			return fmt.Errorf("no host specified (%v)", s)
-		}
-
-		return nil
-	}
-}
diff --git a/vendor/github.com/nats-io/cliprompts/sui.go b/vendor/github.com/nats-io/cliprompts/sui.go
deleted file mode 100644
index 4103949..0000000
--- a/vendor/github.com/nats-io/cliprompts/sui.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package cliprompts
-
-import (
-	"github.com/AlecAivazis/survey"
-)
-
-type SurveyUI struct{}
-
-func (sui *SurveyUI) Prompt(label string, value string, edit bool, validator Validator) (string, error) {
-	v := value
-	p := &survey.Input{
-		Message: label,
-		Default: value,
-	}
-	if err := survey.AskOne(p, &v, sui.wrap(validator)); err != nil {
-		return "", err
-	}
-	return v, nil
-}
-
-func (sui *SurveyUI) PromptWithHelp(label string, value string, edit bool, validator Validator, help string) (string, error) {
-	v := value
-	p := &survey.Input{
-		Message: label,
-		Default: value,
-		Help:    help,
-	}
-	if err := survey.AskOne(p, &v, sui.wrap(validator)); err != nil {
-		return "", err
-	}
-	return v, nil
-}
-
-func (sui *SurveyUI) wrap(validator Validator) survey.Validator {
-	if validator == nil {
-		return nil
-	}
-	return func(input interface{}) error {
-		s := input.(string)
-		return validator(s)
-	}
-}
-
-func (sui *SurveyUI) PromptYN(m string, defaultValue bool) (bool, error) {
-	v := defaultValue
-	p := &survey.Confirm{
-		Message: m,
-		Default: defaultValue,
-	}
-	if err := survey.AskOne(p, &v, nil); err != nil {
-		return false, err
-	}
-	return v, nil
-}
-
-func (sui *SurveyUI) PromptSecret(m string) (string, error) {
-	v := ""
-	p := &survey.Password{
-		Message: m,
-	}
-	if err := survey.AskOne(p, &v, nil); err != nil {
-		return "", err
-	}
-	return v, nil
-}
-
-func (sui *SurveyUI) PromptChoices(m string, value string, choices []string) (int, error) {
-	v := ""
-	p := &survey.Select{
-		Message: m,
-		Options: choices,
-	}
-
-	if value != "" {
-		p.Default = value
-	}
-	if err := survey.AskOne(p, &v, nil); err != nil {
-		return -1, err
-	}
-	idx := -1
-	for i, t := range choices {
-		if t == v {
-			idx = i
-			break
-		}
-	}
-	return idx, nil
-}
-
-func (sui *SurveyUI) PromptMultipleChoices(m string, choices []string) ([]int, error) {
-	v := make([]string, 0)
-	p := &survey.MultiSelect{
-		Message: m,
-		Options: choices,
-	}
-	if err := survey.AskOne(p, &v, nil); err != nil {
-		return nil, err
-	}
-
-	idx := make([]int, 0)
-	for _, t := range v {
-		for i, c := range choices {
-			if c == t {
-				idx = append(idx, i)
-			}
-		}
-	}
-	return idx, nil
-}
diff --git a/vendor/github.com/nats-io/cliprompts/LICENSE b/vendor/github.com/nats-io/cliprompts/v2/LICENSE
similarity index 100%
rename from vendor/github.com/nats-io/cliprompts/LICENSE
rename to vendor/github.com/nats-io/cliprompts/v2/LICENSE
diff --git a/vendor/github.com/nats-io/cliprompts/README.md b/vendor/github.com/nats-io/cliprompts/v2/README.md
similarity index 100%
rename from vendor/github.com/nats-io/cliprompts/README.md
rename to vendor/github.com/nats-io/cliprompts/v2/README.md
diff --git a/vendor/github.com/nats-io/cliprompts/go.mod b/vendor/github.com/nats-io/cliprompts/v2/go.mod
similarity index 52%
rename from vendor/github.com/nats-io/cliprompts/go.mod
rename to vendor/github.com/nats-io/cliprompts/v2/go.mod
index 4279e65..4e4a862 100644
--- a/vendor/github.com/nats-io/cliprompts/go.mod
+++ b/vendor/github.com/nats-io/cliprompts/v2/go.mod
@@ -1,11 +1,10 @@
-module github.com/nats-io/cliprompts
+module github.com/nats-io/cliprompts/v2
 
 go 1.13
 
 require (
-	github.com/AlecAivazis/survey v1.7.0
+	github.com/AlecAivazis/survey/v2 v2.0.4
 	github.com/mitchellh/go-homedir v1.1.0
 	github.com/mitchellh/go-wordwrap v1.0.0
 	github.com/stretchr/testify v1.2.1
-	gopkg.in/AlecAivazis/survey.v1 v1.8.7 // indirect
 )
diff --git a/vendor/github.com/nats-io/cliprompts/v2/go.sum b/vendor/github.com/nats-io/cliprompts/v2/go.sum
new file mode 100644
index 0000000..81ebde1
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/go.sum
@@ -0,0 +1,36 @@
+github.com/AlecAivazis/survey/v2 v2.0.4 h1:qzXnJSzXEvmUllWqMBWpZndvT2YfoAUzAMvZUax3L2M=
+github.com/AlecAivazis/survey/v2 v2.0.4/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
+github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
+github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ=
+github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
+github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
+github.com/kr/pty v1.1.4 h1:5Myjjh3JY/NaAi4IsUbHADytDyl1VE1Y9PXDlL+P/VQ=
+github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
+github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
+github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U=
+github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5 h1:8dUaAV7K4uHsF56JQWkprecIQKdPHtR9jCHF5nB8uzc=
+golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1 h1:R4dVlxdmKenVdMRS/tTspEpSTRWINYrHD8ySIU9yCIU=
+golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/vendor/github.com/nats-io/cliprompts/open.go b/vendor/github.com/nats-io/cliprompts/v2/open.go
similarity index 100%
rename from vendor/github.com/nats-io/cliprompts/open.go
rename to vendor/github.com/nats-io/cliprompts/v2/open.go
diff --git a/vendor/github.com/nats-io/cliprompts/v2/open_darwin.go b/vendor/github.com/nats-io/cliprompts/v2/open_darwin.go
new file mode 100644
index 0000000..4a3c7bc
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/open_darwin.go
@@ -0,0 +1,24 @@
+// +build darwin
+
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import "os/exec"
+
+func open(url string) *exec.Cmd {
+	return exec.Command("open", url)
+}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/open_linux.go b/vendor/github.com/nats-io/cliprompts/v2/open_linux.go
new file mode 100644
index 0000000..abdb8ff
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/open_linux.go
@@ -0,0 +1,24 @@
+// +build !windows,!darwin
+
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import "os/exec"
+
+func open(url string) *exec.Cmd {
+	return nil
+}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/open_windows.go b/vendor/github.com/nats-io/cliprompts/v2/open_windows.go
new file mode 100644
index 0000000..bb2d3d0
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/open_windows.go
@@ -0,0 +1,24 @@
+// +build windows
+
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import "os/exec"
+
+func open(url string) *exec.Cmd {
+	return nil
+}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/prompts.go b/vendor/github.com/nats-io/cliprompts/v2/prompts.go
new file mode 100644
index 0000000..c680b5e
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/prompts.go
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"net/mail"
+	"net/url"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/mitchellh/go-homedir"
+)
+
+type Logger func(args ...interface{})
+
+type Validator func(string) error
+
+var cli PromptLib
+
+// set a Logger during a test (cli.LogFn = t.Log) to debug interactive prompts
+var LogFn Logger
+
+// lint:ignore U1000
+var output io.Writer = os.Stdout
+
+type PromptLib interface {
+	Prompt(label string, value string, opt ...Opt) (string, error)
+	Confirm(m string, defaultValue bool, o ...Opt) (bool, error)
+	Password(m string, o ...Opt) (string, error)
+	Select(m string, value string, choices []string, o ...Opt) (int, error)
+	MultiSelect(m string, choices []string, o ...Opt) ([]int, error)
+}
+
+type Opts struct {
+	Help string
+	Fn   Validator
+}
+
+type Opt func(o *Opts)
+
+func processOpts(opt ...Opt) Opts {
+	var opts Opts
+	for _, o := range opt {
+		o(&opts)
+	}
+	return opts
+}
+
+func Help(h string) Opt {
+	return func(o *Opts) {
+		o.Help = h
+	}
+}
+
+func Val(fn Validator) Opt {
+	return func(o *Opts) {
+		o.Fn = fn
+	}
+}
+
+func init() {
+	ResetPromptLib()
+	LogFn = nil
+}
+
+func SetPromptLib(p PromptLib) {
+	cli = p
+}
+
+func ResetPromptLib() {
+	SetPromptLib(&SurveyUI{})
+	LogFn = nil
+}
+
+func SetOutput(out io.Writer) {
+	output = out
+}
+
+func GetOutput() io.Writer {
+	return output
+}
+
+const underlineTemplate = "\xff\033[4m\xff%s\xff\033[0m\xff"
+
+func Underline(s string) string {
+	return fmt.Sprintf(underlineTemplate, s)
+}
+
+const boldTemplate = "\033[1m%s\033[0m"
+
+func Bold(s string) string {
+	return fmt.Sprintf(boldTemplate, s)
+}
+
+const italicTemplate = "\033[3m%s\033[0m"
+
+func Italic(s string) string {
+	return fmt.Sprintf(italicTemplate, s)
+}
+
+func Prompt(label string, value string, o ...Opt) (string, error) {
+	return cli.Prompt(label, value, o...)
+}
+
+func Confirm(m string, value bool, o ...Opt) (bool, error) {
+	if err := insureNoValidator(o...); err != nil {
+		return false, err
+	}
+	return cli.Confirm(m, value, o...)
+}
+
+func Password(m string, o ...Opt) (string, error) {
+	return cli.Password(m, o...)
+}
+
+func Select(m string, value string, choices []string, o ...Opt) (int, error) {
+	if err := insureNoValidator(o...); err != nil {
+		return -1, err
+	}
+	return cli.Select(m, value, choices, o...)
+}
+
+func MultiSelect(m string, choices []string, o ...Opt) ([]int, error) {
+	if err := insureNoValidator(o...); err != nil {
+		return nil, err
+	}
+	return cli.MultiSelect(m, choices, o...)
+}
+
+var errValidatorNotSupported = errors.New("validators are not supported on this control")
+
+func insureNoValidator(o ...Opt) error {
+	var opts Opts
+	for _, v := range o {
+		v(&opts)
+	}
+	if opts.Fn != nil {
+		return errValidatorNotSupported
+	}
+	return nil
+}
+
+func NewEmailValidator() Opt {
+	return Val(EmailValidator())
+}
+
+func EmailValidator() Validator {
+	return func(input string) error {
+		if input != "" {
+			_, err := mail.ParseAddress(input)
+			return err
+		}
+		return nil
+	}
+}
+
+func NewLengthValidator(min int) Opt {
+	return Val(LengthValidator(min))
+}
+
+func LengthValidator(min int) Validator {
+	return func(input string) error {
+		if len(input) >= min {
+			return nil
+		}
+		return errors.New("value is too short")
+	}
+}
+
+func NewPathOrURLValidator() Opt {
+	return Val(PathOrURLValidator())
+}
+
+func PathOrURLValidator() Validator {
+	return func(s string) error {
+		if u, err := url.Parse(s); err == nil && u.Scheme != "" {
+			return nil
+		}
+
+		v, err := homedir.Expand(s)
+		if err != nil {
+			return err
+		}
+		v, err = filepath.Abs(v)
+		if err != nil {
+			return err
+		}
+		info, err := os.Stat(v)
+		if err != nil {
+			return err
+		}
+		if !info.Mode().IsRegular() {
+			return errors.New("path is not a file")
+		}
+		return nil
+	}
+}
+
+func NewURLValidator(protocol ...string) Opt {
+	return Val(URLValidator(protocol...))
+}
+
+func URLValidator(protocol ...string) Validator {
+	return func(s string) error {
+		s = strings.TrimSpace(s)
+		if s == "" {
+			return errors.New("url cannot be empty")
+		}
+		u, err := url.Parse(s)
+		if err != nil {
+			return err
+		}
+		scheme := strings.ToLower(u.Scheme)
+
+		ok := false
+		for _, v := range protocol {
+			if scheme == v {
+				ok = true
+				break
+			}
+		}
+		if !ok {
+			var protos []string
+			protos = append(protos, protocol...)
+			return fmt.Errorf("scheme %q is not supported (%v)", scheme, strings.Join(protos, ", "))
+		}
+		if u.Host == "" {
+			return fmt.Errorf("no host specified (%v)", s)
+		}
+
+		return nil
+	}
+}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/sui.go b/vendor/github.com/nats-io/cliprompts/v2/sui.go
new file mode 100644
index 0000000..e3c02fc
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/sui.go
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import (
+	"github.com/AlecAivazis/survey/v2"
+)
+
+type SurveyUI struct{}
+
+func (sui *SurveyUI) Prompt(label string, value string, o ...Opt) (string, error) {
+	v := value
+	p := &survey.Input{
+		Message: label,
+		Default: value,
+	}
+
+	opts := processOpts(o...)
+	if opts.Help != "" {
+		p.Help = opts.Help
+	}
+	if err := survey.AskOne(p, &v, survey.WithValidator(sui.wrap(opts.Fn))); err != nil {
+		return "", err
+	}
+	return v, nil
+}
+
+func (sui *SurveyUI) wrap(validator Validator) survey.Validator {
+	if validator == nil {
+		return nil
+	}
+	return func(input interface{}) error {
+		s := input.(string)
+		return validator(s)
+	}
+}
+
+func (sui *SurveyUI) Confirm(m string, defaultValue bool, o ...Opt) (bool, error) {
+	v := defaultValue
+	p := &survey.Confirm{
+		Message: m,
+		Default: defaultValue,
+	}
+	opts := processOpts(o...)
+	if opts.Help != "" {
+		p.Help = opts.Help
+	}
+
+	if err := survey.AskOne(p, &v); err != nil {
+		return false, err
+	}
+	return v, nil
+}
+
+func (sui *SurveyUI) Password(m string, o ...Opt) (string, error) {
+	v := ""
+	p := &survey.Password{
+		Message: m,
+	}
+
+	opts := processOpts(o...)
+	if opts.Help != "" {
+		p.Help = opts.Help
+	}
+
+	if err := survey.AskOne(p, &v, survey.WithValidator(sui.wrap(opts.Fn))); err != nil {
+		return "", err
+	}
+	return v, nil
+}
+
+func (sui *SurveyUI) Select(m string, value string, choices []string, o ...Opt) (int, error) {
+	var v int
+
+	if value == "" && len(choices) > 0 {
+		value = choices[0]
+	}
+	p := &survey.Select{
+		Message: m,
+		Options: choices,
+		Default: value,
+	}
+	opts := processOpts(o...)
+	if opts.Help != "" {
+		p.Help = opts.Help
+	}
+
+	if err := survey.AskOne(p, &v); err != nil {
+		return -1, err
+	}
+	return v, nil
+}
+
+func (sui *SurveyUI) MultiSelect(m string, choices []string, o ...Opt) ([]int, error) {
+	var idx []int
+	p := &survey.MultiSelect{
+		Message: m,
+		Options: choices,
+	}
+
+	opts := processOpts(o...)
+	if opts.Help != "" {
+		p.Help = opts.Help
+	}
+
+	if err := survey.AskOne(p, &idx); err != nil {
+		return nil, err
+	}
+
+	return idx, nil
+}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/wrap.go b/vendor/github.com/nats-io/cliprompts/v2/wrap.go
new file mode 100644
index 0000000..3cb468f
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/wrap.go
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import (
+	"bytes"
+	"fmt"
+
+	"github.com/mitchellh/go-wordwrap"
+)
+
+func WrapString(lim uint, s string) string {
+	return wordwrap.WrapString(s, lim)
+}
+
+func WrapSprintf(lim uint, format string, a ...interface{}) string {
+	return WrapString(lim, fmt.Sprintf(format, a...))
+}
+
+func Wrap(lim uint, args ...interface{}) string {
+	var buf bytes.Buffer
+	for i, arg := range args {
+		if i > 0 {
+			buf.WriteByte(' ')
+		}
+		buf.WriteString(fmt.Sprintf("%v", arg))
+	}
+
+	return WrapString(lim, buf.String())
+}
diff --git a/vendor/github.com/nats-io/cliprompts/wrap.go b/vendor/github.com/nats-io/cliprompts/wrap.go
deleted file mode 100644
index b584637..0000000
--- a/vendor/github.com/nats-io/cliprompts/wrap.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package cliprompts
-
-import (
-	"bytes"
-	"fmt"
-
-	"github.com/mitchellh/go-wordwrap"
-)
-
-func WrapString(lim uint, s string) string {
-	return wordwrap.WrapString(s, lim)
-}
-
-func WrapSprintf(lim uint, format string, a ...interface{}) string {
-	return WrapString(lim, fmt.Sprintf(format, a...))
-}
-
-func Wrap(lim uint, args ...interface{}) string {
-	var buf bytes.Buffer
-	for i, arg := range args {
-		if i > 0 {
-			buf.WriteByte(' ')
-		}
-		buf.WriteString(fmt.Sprintf("%v", arg))
-	}
-
-	return WrapString(lim, buf.String())
-}
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/LICENSE b/vendor/gopkg.in/AlecAivazis/survey.v1/LICENSE
deleted file mode 100644
index 07a709a..0000000
--- a/vendor/gopkg.in/AlecAivazis/survey.v1/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018 Alec Aivazis
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/gopkg.in/AlecAivazis/survey.v1/core/template.go b/vendor/gopkg.in/AlecAivazis/survey.v1/core/template.go
deleted file mode 100644
index 7a3a190..0000000
--- a/vendor/gopkg.in/AlecAivazis/survey.v1/core/template.go
+++ /dev/null
@@ -1,120 +0,0 @@
-package core
-
-import (
-	"bytes"
-	"sync"
-	"text/template"
-
-	"github.com/mgutz/ansi"
-)
-
-var DisableColor = false
-
-var (
-	// HelpInputRune is the rune which the user should enter to trigger
-	// more detailed question help
-	HelpInputRune = '?'
-
-	// ErrorIcon will be be shown before an error
-	ErrorIcon = "X"
-
-	// HelpIcon will be shown before more detailed question help
-	HelpIcon = "?"
-	// QuestionIcon will be shown before a question Message
-	QuestionIcon = "?"
-
-	// MarkedOptionIcon will be prepended before a selected multiselect option
-	MarkedOptionIcon = "[x]"
-	// UnmarkedOptionIcon will be prepended before an unselected multiselect option
-	UnmarkedOptionIcon = "[ ]"
-
-	// SelectFocusIcon is prepended to an option to signify the user is
-	// currently focusing that option
-	SelectFocusIcon = ">"
-)
-
-/*
-  SetFancyIcons changes the err, help, marked, and focus input icons to their
-  fancier forms. These forms may not be compatible with most terminals.
-  This function will not touch the QuestionIcon as its fancy and non fancy form
-  are the same.
-*/
-func SetFancyIcons() {
-	ErrorIcon = "✘"
-	HelpIcon = "ⓘ"
-	// QuestionIcon fancy and non-fancy form are the same
-
-	MarkedOptionIcon = "◉"
-	UnmarkedOptionIcon = "◯"
-
-	SelectFocusIcon = "❯"
-}
-
-var TemplateFuncs = map[string]interface{}{
-	// Templates with Color formatting. See Documentation: https://github.com/mgutz/ansi#style-format
-	"color": func(color string) string {
-		if DisableColor {
-			return ""
-		}
-		return ansi.ColorCode(color)
-	},
-	"HelpInputRune": func() string {
-		return string(HelpInputRune)
-	},
-	"ErrorIcon": func() string {
-		return ErrorIcon
-	},
-	"HelpIcon": func() string {
-		return HelpIcon
-	},
-	"QuestionIcon": func() string {
-		return QuestionIcon
-	},
-	"MarkedOptionIcon": func() string {
-		return MarkedOptionIcon
-	},
-	"UnmarkedOptionIcon": func() string {
-		return UnmarkedOptionIcon
-	},
-	"SelectFocusIcon": func() string {
-		return SelectFocusIcon
-	},
-}
-
-var (
-	memoizedGetTemplate = map[string]*template.Template{}
-
-	memoMutex = &sync.RWMutex{}
-)
-
-func getTemplate(tmpl string) (*template.Template, error) {
-	memoMutex.RLock()
-	if t, ok := memoizedGetTemplate[tmpl]; ok {
-		memoMutex.RUnlock()
-		return t, nil
-	}
-	memoMutex.RUnlock()
-
-	t, err := template.New("prompt").Funcs(TemplateFuncs).Parse(tmpl)
-	if err != nil {
-		return nil, err
-	}
-
-	memoMutex.Lock()
-	memoizedGetTemplate[tmpl] = t
-	memoMutex.Unlock()
-	return t, nil
-}
-
-func RunTemplate(tmpl string, data interface{}) (string, error) {
-	t, err := getTemplate(tmpl)
-	if err != nil {
-		return "", err
-	}
-	buf := bytes.NewBufferString("")
-	err = t.Execute(buf, data)
-	if err != nil {
-		return "", err
-	}
-	return buf.String(), err
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 1ed3102..985a782 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,5 +1,7 @@
-# github.com/AlecAivazis/survey v1.7.0
-github.com/AlecAivazis/survey
+# github.com/AlecAivazis/survey/v2 v2.0.4
+github.com/AlecAivazis/survey/v2
+github.com/AlecAivazis/survey/v2/core
+github.com/AlecAivazis/survey/v2/terminal
 # github.com/blang/semver v3.5.1+incompatible
 github.com/blang/semver
 # github.com/briandowns/spinner v0.0.0-20181029155426-195c31b675a7
@@ -41,9 +43,9 @@ github.com/inconshreveable/mousetrap
 github.com/kballard/go-shellquote
 # github.com/magiconair/properties v1.8.0
 github.com/magiconair/properties
-# github.com/mattn/go-colorable v0.0.9
+# github.com/mattn/go-colorable v0.1.2
 github.com/mattn/go-colorable
-# github.com/mattn/go-isatty v0.0.4
+# github.com/mattn/go-isatty v0.0.8
 github.com/mattn/go-isatty
 # github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
 github.com/mgutz/ansi
@@ -53,8 +55,8 @@ github.com/mitchellh/go-homedir
 github.com/mitchellh/go-wordwrap
 # github.com/mitchellh/mapstructure v1.1.2
 github.com/mitchellh/mapstructure
-# github.com/nats-io/cliprompts v0.3.16
-github.com/nats-io/cliprompts
+# github.com/nats-io/cliprompts/v2 v2.0.0-20191203200115-ae8d3743105d
+github.com/nats-io/cliprompts/v2
 # github.com/nats-io/jwt v0.3.2
 github.com/nats-io/jwt
 # github.com/nats-io/nats-server/v2 v2.0.1-0.20190625001713-2db76bde3329
@@ -134,8 +136,5 @@ google.golang.org/appengine/internal/log
 google.golang.org/appengine/internal/remote_api
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/urlfetch
-# gopkg.in/AlecAivazis/survey.v1 v1.8.7
-gopkg.in/AlecAivazis/survey.v1/core
-gopkg.in/AlecAivazis/survey.v1/terminal
 # gopkg.in/yaml.v2 v2.2.2
 gopkg.in/yaml.v2


Test patch:
diff --git a/cmd/addimport_test.go b/cmd/addimport_test.go
index 55b908e..86ea893 100644
--- a/cmd/addimport_test.go
+++ b/cmd/addimport_test.go
@@ -488,3 +488,20 @@ func Test_ImportStreamLocalWildcards(t *testing.T) {
 	require.Error(t, err)
 	require.Contains(t, "stream prefix subject cannot have wildcards", err.Error())
 }
+
+func Test_AddImportToAccount(t *testing.T) {
+	ts := NewTestStore(t, t.Name())
+	defer ts.Done(t)
+
+	ts.AddAccount(t, "A")
+	ts.AddAccount(t, "B")
+
+	bpk := ts.GetAccountPublicKey(t, "B")
+
+	_, _, err := ExecuteCmd(createAddImportCmd(), "--account", "A", "--src-account", bpk, "--remote-subject", "s.>")
+	require.NoError(t, err)
+
+	bc, err := ts.Store.ReadAccountClaim("A")
+	require.NoError(t, err)
+	require.Len(t, bc.Imports, 1)
+}
diff --git a/cmd/cmd_test.go b/cmd/cmd_test.go
index 919b1d6..440cd93 100644
--- a/cmd/cmd_test.go
+++ b/cmd/cmd_test.go
@@ -22,7 +22,7 @@ import (
 	"strings"
 	"testing"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/spf13/cobra"
 )
 
diff --git a/cmd/editexport_test.go b/cmd/editexport_test.go
index bf84e45..87e0ac6 100644
--- a/cmd/editexport_test.go
+++ b/cmd/editexport_test.go
@@ -45,6 +45,7 @@ func Test_EditExport_Latency(t *testing.T) {
 	ts.AddExport(t, "A", jwt.Service, "a", true)
 
 	ac, err := ts.Store.ReadAccountClaim("A")
+	require.NoError(t, err)
 	require.Nil(t, ac.Exports[0].Latency)
 
 	_, _, err = ExecuteCmd(createEditExportCmd(), "--subject", "a", "--sampling", "100", "--latency", "lat")
@@ -95,6 +96,26 @@ func Test_EditExportInteractiveLatency(t *testing.T) {
 	require.EqualValues(t, jwt.ResponseTypeChunked, ac.Exports[0].ResponseType)
 }
 
+func Test_EditExportRmLatencySampling(t *testing.T) {
+	ts := NewTestStore(t, "O")
+	defer ts.Done(t)
+
+	ts.AddAccount(t, "A")
+	ts.AddExport(t, "A", jwt.Service, "a", true)
+
+	_, _, err := ExecuteCmd(createEditExportCmd(), "--subject", "a", "--sampling", "100", "--latency", "metrics.a")
+	require.NoError(t, err)
+
+	ac, err := ts.Store.ReadAccountClaim("A")
+	require.NoError(t, err)
+	require.NotNil(t, ac.Exports[0].Latency)
+
+	_, _, err = ExecuteCmd(createEditExportCmd(), "--subject", "a", "--rm-latency-sampling")
+	ac, err = ts.Store.ReadAccountClaim("A")
+	require.NoError(t, err)
+	require.Nil(t, ac.Exports[0].Latency)
+}
+
 func Test_EditExportNoExports(t *testing.T) {
 	ts := NewTestStore(t, "O")
 	defer ts.Done(t)
diff --git a/cmd/edituser_test.go b/cmd/edituser_test.go
index 6f2836a..53b2572 100644
--- a/cmd/edituser_test.go
+++ b/cmd/edituser_test.go
@@ -20,7 +20,7 @@ import (
 	"testing"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/stretchr/testify/require"
 )
diff --git a/cmd/init_test.go b/cmd/init_test.go
index 2bea6c6..2fe751c 100644
--- a/cmd/init_test.go
+++ b/cmd/init_test.go
@@ -19,7 +19,7 @@ import (
 	"net/url"
 	"testing"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/stretchr/testify/require"
 )
 
diff --git a/cmd/util_test.go b/cmd/util_test.go
index dc479fb..26b7b96 100644
--- a/cmd/util_test.go
+++ b/cmd/util_test.go
@@ -29,7 +29,7 @@ import (
 	"testing"
 	"time"
 
-	cli "github.com/nats-io/cliprompts"
+	cli "github.com/nats-io/cliprompts/v2"
 	"github.com/nats-io/jwt"
 	"github.com/nats-io/nats-server/v2/server"
 	nats "github.com/nats-io/nats.go"
diff --git a/vendor/github.com/nats-io/cliprompts/testprompts.go b/vendor/github.com/nats-io/cliprompts/testprompts.go
deleted file mode 100644
index 70205ec..0000000
--- a/vendor/github.com/nats-io/cliprompts/testprompts.go
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright 2018 The NATS Authors
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package cliprompts
-
-import (
-	"fmt"
-	"strings"
-)
-
-type TestPrompts struct {
-	count  int
-	inputs []interface{}
-}
-
-func NewTestPrompts(inputs []interface{}) PromptLib {
-	return &TestPrompts{
-		count:  0,
-		inputs: inputs,
-	}
-}
-
-func (t *TestPrompts) logInputs(kind string, label string, value interface{}) {
-	if LogFn == nil {
-		return
-	}
-	LogFn(fmt.Sprintf("[%s %d] %s = %v\n", kind, t.count, label, value))
-}
-
-func (t *TestPrompts) Prompt(label string, value string, edit bool, validator Validator) (string, error) {
-	t.logInputs("prompt", label, t.inputs[t.count])
-	return t.prompt(label, value, edit, validator)
-}
-
-func (t *TestPrompts) PromptWithHelp(label string, value string, edit bool, validator Validator, help string) (string, error) {
-	t.logInputs("promptWithHelp", label, t.inputs[t.count])
-	return t.prompt(label, value, edit, validator)
-}
-
-func (t *TestPrompts) PromptYN(m string, defaultValue bool) (bool, error) {
-	t.logInputs("yn", m, t.inputs[t.count])
-	val := t.inputs[t.count].(bool)
-	t.count = t.count + 1
-	return val, nil
-}
-
-func (t *TestPrompts) PromptSecret(m string) (string, error) {
-	t.logInputs("secret", m, t.inputs[t.count])
-	val := t.inputs[t.count].(string)
-	t.count = t.count + 1
-	return val, nil
-}
-
-func (t *TestPrompts) PromptChoices(m string, value string, choices []string) (int, error) {
-	t.logInputs("choices", m, fmt.Sprintf("[%s]", strings.Join(choices, ",\n\t")))
-	val := t.inputs[t.count].(int)
-	t.logInputs("choices", "   selection", fmt.Sprintf("%d (%s)", val, choices[val]))
-	t.count = t.count + 1
-	return val, nil
-}
-
-func (t *TestPrompts) PromptMultipleChoices(m string, choices []string) ([]int, error) {
-	t.logInputs("multiple-choice", m, t.inputs[t.count])
-	val := t.inputs[t.count].([]int)
-	t.count = t.count + 1
-	return val, nil
-}
-
-func (t *TestPrompts) prompt(label string, value string, edit bool, validator Validator) (string, error) {
-	val, ok := t.inputs[t.count].(string)
-	if !ok {
-		val = fmt.Sprintf("%v", val)
-	}
-	t.count = t.count + 1
-
-	if validator != nil {
-		err := validator(val)
-		if err != nil {
-			return Prompt(label, value, edit, validator)
-		}
-	}
-	return val, nil
-}
diff --git a/vendor/github.com/nats-io/cliprompts/v2/testprompts.go b/vendor/github.com/nats-io/cliprompts/v2/testprompts.go
new file mode 100644
index 0000000..421a1ec
--- /dev/null
+++ b/vendor/github.com/nats-io/cliprompts/v2/testprompts.go
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2018-2019 The NATS Authors
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cliprompts
+
+import (
+	"fmt"
+	"strings"
+)
+
+type TestPrompts struct {
+	count  int
+	inputs []interface{}
+}
+
+func NewTestPrompts(inputs []interface{}) PromptLib {
+	return &TestPrompts{
+		count:  0,
+		inputs: inputs,
+	}
+}
+
+func (t *TestPrompts) logInputs(kind string, label string, value interface{}) {
+	if LogFn == nil {
+		return
+	}
+	LogFn(fmt.Sprintf("[%s %d] %s = %v\n", kind, t.count, label, value))
+}
+
+func (t *TestPrompts) Prompt(label string, value string, o ...Opt) (string, error) {
+	val, ok := t.inputs[t.count].(string)
+	if !ok {
+		return "", fmt.Errorf("%s prompt expected a string: %v", label, t.inputs[t.count])
+	}
+	t.logInputs("prompt", label, t.inputs[t.count])
+	t.count = t.count + 1
+
+	opts := processOpts(o...)
+	if opts.Fn != nil {
+		if err := opts.Fn(val); err != nil {
+			return "", err
+		}
+	}
+	return val, nil
+}
+
+func (t *TestPrompts) Confirm(m string, v bool, o ...Opt) (bool, error) {
+	val, ok := t.inputs[t.count].(bool)
+	if !ok {
+		return false, fmt.Errorf("%s confirm expected a bool: %v", m, t.inputs[t.count])
+	}
+	t.logInputs("confirm", m, t.inputs[t.count])
+	t.count = t.count + 1
+	return val, nil
+}
+
+func (t *TestPrompts) Password(m string, o ...Opt) (string, error) {
+	val, ok := t.inputs[t.count].(string)
+	if !ok {
+		return "", fmt.Errorf("%s password expected a string: %v", m, t.inputs[t.count])
+	}
+	t.logInputs("password", m, t.inputs[t.count])
+
+	opts := processOpts(o...)
+	if opts.Fn != nil {
+		if err := opts.Fn(val); err != nil {
+			return "", err
+		}
+	}
+
+	t.count = t.count + 1
+	return val, nil
+}
+
+func (t *TestPrompts) Select(m string, value string, choices []string, o ...Opt) (int, error) {
+	val, ok := t.inputs[t.count].(int)
+	if !ok {
+		return -1, fmt.Errorf("%s select expected an int: %v", m, t.inputs[t.count])
+	}
+	t.logInputs("select", m, fmt.Sprintf("[%s]", strings.Join(choices, ",\n\t")))
+	t.logInputs("select", "   selection", fmt.Sprintf("%d (%s)", val, choices[val]))
+	t.count = t.count + 1
+	return val, nil
+}
+
+func (t *TestPrompts) MultiSelect(m string, choices []string, o ...Opt) ([]int, error) {
+	val, ok := t.inputs[t.count].([]int)
+	if !ok {
+		return nil, fmt.Errorf("%s multiselect expected []int: %v", m, t.inputs[t.count])
+	}
+	t.logInputs("multiselect", m, t.inputs[t.count])
+	t.count = t.count + 1
+	return val, nil
+}