{"id":26504983,"url":"https://github.com/oxequa/interact","last_synced_at":"2025-09-07T22:42:58.619Z","repository":{"id":57482283,"uuid":"78041163","full_name":"oxequa/interact","owner":"oxequa","description":"Question/answer and multiple choice by command line","archived":false,"fork":false,"pushed_at":"2017-12-16T12:59:38.000Z","size":55,"stargazers_count":42,"open_issues_count":0,"forks_count":11,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-06T13:22:23.154Z","etag":null,"topics":["go","golang","golang-package","golang-tools","questions-and-answers","tockins"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oxequa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-01-04T18:21:27.000Z","updated_at":"2025-03-13T03:54:44.000Z","dependencies_parsed_at":"2022-09-02T04:21:01.627Z","dependency_job_id":null,"html_url":"https://github.com/oxequa/interact","commit_stats":null,"previous_names":["tockins/interact"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/oxequa/interact","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxequa%2Finteract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxequa%2Finteract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxequa%2Finteract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxequa%2Finteract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oxequa","download_url":"https://codeload.github.com/oxequa/interact/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxequa%2Finteract/sbom","scorecard":{"id":715928,"data":{"date":"2025-08-11","repo":{"name":"github.com/oxequa/interact","commit":"f8fb5795b5d713c41dab6771ffe1fdfdfd0c3285"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":0,"reason":"Found 2/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 5 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T09:39:02.780Z","repository_id":57482283,"created_at":"2025-08-22T09:39:02.780Z","updated_at":"2025-08-22T09:39:02.780Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274107987,"owners_count":25223473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-package","golang-tools","questions-and-answers","tockins"],"created_at":"2025-03-20T20:56:18.392Z","updated_at":"2025-09-07T22:42:58.554Z","avatar_url":"https://github.com/oxequa.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Interact\n\nAn easy and fast Go library, without external imports, to handle questions and answers by command line\n\n##### Features\n\n- [Single question](#single-question)\n- [Questions list](#questions-list)\n- [Multiple choice](#multiple-choice)\n- [Sub questions](#sub-questions)\n- [Question prefix](#question-prefix)\n- [Default values](#default-values)\n- [Custom errors](#custom-errors)\n- [After/Before listeners](#after-before)\n- [Skip a Question](#skip-a-question)\n- [Reload a Question](#reload-a-question)\n- [End signal](#end-signal)\n- [Colors support (fatih/color)](#color-support)\n\n##### Installation\n\nTo install interact:\n```\n$ go get github.com/tockins/interact\n```\n\n##### Single question\n\nRun a simple question and manage the response. \nThe response field is used to get the answer as a specific type.\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n\ti.Run(\u0026i.Interact{\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg:      \"Would you like some coffee?\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t\tval, err := c.Ans().Bool()\n\t\t\t\t\tif err != nil{\n\t\t\t\t\t    return err\n\t\t\t\t\t}\n\t\t\t\t\tfmt.Println(val)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n``` \n\n##### Questions list\n\nDefine a list of questions to be run in sequence.\nThe Action func can be used for validate the answer and can return a custom error.\n\nQuestion struct is only for single question whereas **Interact struct** supports multiple questions\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n\ti.Run(\u0026i.Interact{\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg:     \"Would you like some coffee?\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t\tval, err := c.Ans().Bool()\n\t\t\t\t\tif err != nil{\n\t\t\t\t\t    return err\n\t\t\t\t\t}\n\t\t\t\t\tfmt.Println(val)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg:     \"What's 2+2?\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t    val, _ := c.Ans().Int()\n\t\t\t\t\t// get the answer as integer\n\t\t\t\t\tif val \u003c 4 {\n\t\t\t\t\t\t// return a custom error and rerun the question\n\t\t\t\t\t\treturn \"INCREASE\"\n\t\t\t\t\t}else if val \u003e 4 {\n\t\t\t\t\t\treturn \"DECREASE\"\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n```\n\n##### Multiple choice\n\nDefine a multiple choice question\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n\ti.Run(\u0026i.Interact{\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n                    Msg:     \"how much for a teacup?\",\n                    Choices: i.Choices{\n                        Alternatives: []i.Choice{\n                            {\n                                Text: \"Gyokuro teapcup\",\n                                Response: \"20\",\n                            },\n                            {\n                                Text: \"Sencha teacup\",\n                                Response: -10,\n                            },\n                            {\n                                Text: \"Matcha teacup\",\n                                Response: 15.50,\n                            },\n                        },\n                    },\n                },\n                Action: func(c i.Context) interface{} {\n                    val, _ := c.Ans().Int()\n                    fmt.Println(val)\n                    return nil\n                },\n\t\t\t},\n\t\t},\n\t})\n}\n```\n\n##### Sub questions\n\nThe sub questions list is managed by the **\"Resolve\"** func.\nEach sub question can access to the parent answer by the **\"Parent\"** method\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n    i.Run(\u0026i.Interact{\n        Questions: []*i.Question{\n            {\n                Quest: i.Quest{\n                    Msg:     \"Would you like some coffee?\",\n                    Resolve: func(c i.Context) bool {     \n                        val, _ := c.Ans().Bool()\n                        return val\n                    },\n                },\n                Subs: []*i.Question{\n                    {\n                        Quest: i.Quest{\n                            Msg:     \"What Kind of Coffee?\",\n                            Choices: i.Choices{\n                                Alternatives: []i.Choice{\n                                    {\n                                        Text: \"Black coffee\",\n                                        Response: \"black\",\n                                    },\n                                    {\n                                        Text: \"With milk\",\n                                        Response: \"milk\",\n                                    },\n                                },\n                            },\n                        },\n                        Action: func(c i.Context) interface{} {\n                            // question (sub) answer\n                            val, _ := c.Ans().String()\n                            fmt.Println(val)\n                            // parent answer\n                            val, _ = c.Parent().Ans().String()\n                            fmt.Println(val)\n                            return nil\n                        },\n                    },\n                },\n                Action: func(c i.Context) interface{} {\n                    // question answer   \n                    val, _ := c.Ans().String()\n                    fmt.Println(val)\n                    // sub question answer\n                    fmt.Println(c.Qns().Get(0).Ans().Raw())\n                    return nil\n                },\n            },\n        },\n    })\n}\n```\n\n##### Question prefix\n\nInteract support a custom prefix for each question\n\nYou can define a **global prefix** for all questions but you can **overwrite it** in each question with ease\n\nAs the first param you can pass a custom **io.writer** instance\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n    i.Run(\u0026i.Interact{\n        Before: func(c i.Context) error{\n            c.SetPrfx(nil,\"GLOBAL PREFIX\")\n            return nil\n        },\n        Questions: []*i.Question{\n            {\n                Before: func(c i.Context) error{\n                    c.SetPrfx(nil,\"OVERWRITTEN PREFIX\")\n                    // print current prefix\n                    fmt.Println(c.Prfx())\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"Would you like some coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n            },\n            {\n                Before: func(c i.Context) error{\n                    fmt.Println(c.Prfx())\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"What's 2+2?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n            },\n        },\n    })\n}\n```\n\n##### Default values\n\nYou can define a default value for each question and get it in the action func as an answer\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n    i.Run(\u0026i.Interact{\n        Questions: []*i.Question{\n            {\n                Before: func(c i.Context) error{\n                    c.SetDef(\"test\",default val\")\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"Would you like some coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    val, _ := c.Ans().String()\n                    fmt.Println(val)\n                    return nil\n                },\n            },\n            {\n                Before: func(c i.Context) error{\n                    c.SetDef(\"default\",\"default val\")\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"Would you like some coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    val, _ := c.Ans().Bool()\n                    fmt.Println(val)\n                    return nil\n                },\n            },\n        },\n    })\n}\n``` \n\n##### Custom errors\n\nYou can define a default error for every question or you can set a default error message\n\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n\n\ti.Run(\u0026i.Interact{\n\t\tBefore: func(c i.Context) error{\n\t\t\tc.SetErr(\"Default error\")\n\t\t\treturn nil\n\t\t},\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg: \"Would you like some coffee?\",\n\t\t\t\t\tErr: \"Custom error fot this question\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n                    val, err := c.Ans().Bool()\n\t\t\t\t\tif err {\n\t\t\t\t\t\treturn \"Invalid answer\"\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg: \"Would you like some coffee?\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t\tval, err := c.Ans().Bool()\n                    if err {\n                        return c.Err()\n                    }\n                    return nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n```\n\n##### After Before\n\nFor every question and for each list of questions you can define custom commands to be run before or after the relative instance\n\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunction main(){\n    i.Run(\u0026i.Interact{\n        Before: func(c i.Context) error{\n            c.SetPrfx(nil, \"TEST\")\n            return nil\n        },\n        Questions: []*i.Question{\n            {\n                Before: func(c i.Context) error{\n                    c.SetPrfx(nil, \"TEST A\")\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"How much coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n                After: func(c i.Context) error{\n                    val, _ := c.Ans().Int()\n                    fmt.Println(val)\n                    return nil\n                },\n            },\n            {\n                Quest: i.Quest{\n                    Msg:     \"How much coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n            },\n        },\n        After: func(c i.Context) error{\n            for _, v := range c.Qns().List(){\n                fmt.Println(v.Quest(),v.Ans().Raw())\n            }\n            return nil\n        },\n    })\n}\n```\n\n##### Skip a Question\n\nWith the skip func you can stop the execution of the current question or you can skip the next.\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunction main(){\n    i.Run(\u0026i.Interact{\n        Before: func(c i.Context) error{\n            // skip all questions\n            //c.Skip()\n            return nil\n        },\n        Questions: []*i.Question{\n            {\n                Before: func(c i.Context) error{\n                    // skip the current question\n                    //c.Skip()\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"How much coffee?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n                After: func(c i.Context) error{\n                    // skip the next question\n                    c.Skip()\n                    return nil\n                },\n            },\n            {\n                Before: func(c i.Context) error{\n                    return nil\n                },\n                Quest: i.Quest{\n                    Msg:     \"How much tea?\",\n                },\n                Action: func(c i.Context) interface{} {\n                    return nil\n                },\n                After: func(c i.Context) error{\n                    return nil\n                },\n            },\n        },\n    })\n}\n```\n\n##### Reload a Question\n\nYou can reload a question how many times as you want\n\n``` go\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunction main(){\n    i.Run(\u0026i.Interact{\n        Questions: []*i.Question{\n            {\n                Quest: i.Quest{\n                    Msg:     \"Would you like Interact?\",\n                },\n                Action: func(c i.Context) interface{}{\n                    val, err := c.Ans().Bool()\n                    if (err != nil || !val){\n                        c.Reload()\n                    }\n                    return nil\n                },\n            },\n        },\n    })\n}\n```\n\n##### End signal\n\nEnd a group of questions or sub-questions with a specific character or string\n\n```\npackage main\n\nimport (\n\ti \"github.com/tockins/interact\"\n)\n\nfunc main() {\n\ti.Run(\u0026i.Interact{\n\t\tBefore: func(c i.Context) error {\n\t\t\tc.SetEnd(\"!*\")\n\t\t\treturn nil\n\t\t},\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tBefore: func(c i.Context) error {\n\t\t\t\t\tc.SetEnd(\"*\")\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg: \"Would you like some coffee? (insert '*' to stop this question or the sub questions)\",\n\t\t\t\t\tResolve: func(c i.Context) bool {\n\t\t\t\t\t\tval, _ := c.Ans().Bool()\n\t\t\t\t\t\treturn val\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSubs: []*i.Question{\n\t\t\t\t\t{\n\t\t\t\t\t\tBefore: func(c i.Context) error {\n\t\t\t\t\t\t\tc.SetEnd(\"!\")\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t},\n\t\t\t\t\t\tQuest: i.Quest{\n\t\t\t\t\t\t\tMsg: \"What kind of Coffee? (insert '!' to stop)\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t\t\t\tc.Reload()\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tQuest: i.Quest{\n\t\t\t\t\t\t\tMsg: \"What type of Coffee?\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg: \"Would you like some tea?\",\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t\tc.Reload()\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n```\n\n##### Colors support\n\nInteract supports the color scheme defined by the package \"fatih/color\"\n\n``` go\npackage main\n\nimport (\n\t\"github.com/fatih/color\"\n\ti \"github.com/tockins/interact\"\n\t\"fmt\"\n)\n\nfunc main() {\n\n\tb := color.New(color.FgHiWhite).Add(color.BgRed).SprintfFunc()\n\ty := color.New(color.FgYellow).SprintFunc()\n\tr := color.New(color.FgRed).SprintFunc()\n\tg := color.New(color.FgGreen).SprintFunc()\n\tprefix := y(\"[\") + \"INTERACT\" + y(\"]\")\n\n\ti.Run(\u0026i.Interact{\n\t\tBefore: func(c i.Context) error{\n\t\t\tc.SetPrfx(color.Output, prefix)\n\t\t\treturn nil\n\t\t},\n\t\tQuestions: []*i.Question{\n\t\t\t{\n\t\t\t\tBefore: func(c i.Context) error{\n\t\t\t\t\tc.SetPrfx(nil,y(\"[\") + \"INTERACT QUEST\" + y(\"]\"))\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tQuest: i.Quest{\n\t\t\t\t\tMsg:     \"Would you like some coffee?\",\n\t\t\t\t\tOptions:  g(\"[yes/no]\"),\n\t\t\t\t\tErr:      b(\"INVALID\"),\n\t\t\t\t\tResolve: func(c i.Context) bool{\n\t\t\t\t\t\tval, _ := c.Ans().Bool()\n\t\t\t\t\t\treturn val\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tSubs: []*i.Question{\n\t\t\t\t\t{\n\t\t\t\t\t\tQuest: i.Quest{\n\t\t\t\t\t\t\tMsg:     \"What Kind of Coffee?\",\n\t\t\t\t\t\t\tErr:      b(\"INVALID\"),\n\t\t\t\t\t\t\tChoices: i.Choices{\n\t\t\t\t\t\t\t\tColor: g,\n\t\t\t\t\t\t\t\tAlternatives: []i.Choice{\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tText: \"Black coffee\",\n\t\t\t\t\t\t\t\t\t\tResponse: \"black\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tText: \"With milk\",\n\t\t\t\t\t\t\t\t\t\tResponse: \"milk\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tAction: func(c i.Context) interface{}{\n\t\t\t\t\t\t    val, _ := c.Ans().String()\n\t\t\t\t\t\t\tfmt.Println(val)\n\t\t\t\t\t\t\tval, _ := c.Parent().Ans().String()\n\t\t\t\t\t\t\tfmt.Println(val)\n\t\t\t\t\t\t\treturn nil\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tAction: func(c i.Context) interface{} {\n\t\t\t\t    val, _ := c.Ans().Bool()\n\t\t\t\t\tif !val{\n\t\t\t\t\t\treturn r(\"INVALID INPUT\")\n\t\t\t\t\t}\n\t\t\t\t\tfmt.Println(c.Quest(), val)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxequa%2Finteract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foxequa%2Finteract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxequa%2Finteract/lists"}