package cli import ( "bufio" "context" "fmt" "io" "strings" "email-mcp/internal/secretstore" ) type SetupPrompter interface { PromptSetup(ctx context.Context) (secretstore.Credential, error) } type InteractiveSetupPrompter struct { input *bufio.Reader output io.Writer } func NewInteractiveSetupPrompter(input io.Reader, output io.Writer) *InteractiveSetupPrompter { if input == nil { input = strings.NewReader("") } if output == nil { output = io.Discard } return &InteractiveSetupPrompter{ input: bufio.NewReader(input), output: output, } } func (p *InteractiveSetupPrompter) PromptSetup(context.Context) (secretstore.Credential, error) { host, err := p.prompt("IMAP host: ") if err != nil { return secretstore.Credential{}, err } username, err := p.prompt("Username: ") if err != nil { return secretstore.Credential{}, err } password, err := p.prompt("Password: ") if err != nil { return secretstore.Credential{}, err } cred := secretstore.Credential{ Host: host, Username: username, Password: password, } if err := cred.Validate(); err != nil { return secretstore.Credential{}, err } return cred, nil } func (p *InteractiveSetupPrompter) prompt(label string) (string, error) { if _, err := fmt.Fprint(p.output, label); err != nil { return "", err } value, err := p.input.ReadString('\n') if err != nil && err != io.EOF { return "", err } return strings.TrimSpace(value), nil }