├── .gitignore ├── images ├── authorize.png └── screenshot1.gif ├── awesome-chatgpt-prompts-alfred.alfredworkflow ├── go.mod ├── main.go ├── LICENSE ├── README.md ├── go.sum └── getAwesomeChatGPTPrompts.go /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | awesome-chatgpt-prompts.json -------------------------------------------------------------------------------- /images/authorize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluewolfali/awesome-chatgpt-prompts-alfred/HEAD/images/authorize.png -------------------------------------------------------------------------------- /images/screenshot1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluewolfali/awesome-chatgpt-prompts-alfred/HEAD/images/screenshot1.gif -------------------------------------------------------------------------------- /awesome-chatgpt-prompts-alfred.alfredworkflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluewolfali/awesome-chatgpt-prompts-alfred/HEAD/awesome-chatgpt-prompts-alfred.alfredworkflow -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module alfred-chatgpt-prompts 2 | 3 | go 1.18 4 | 5 | require github.com/deanishe/awgo v0.29.1 6 | 7 | require ( 8 | github.com/magefile/mage v1.11.0 // indirect 9 | go.deanishe.net/env v0.5.1 // indirect 10 | go.deanishe.net/fuzzy v1.0.0 // indirect 11 | golang.org/x/text v0.3.6 // indirect 12 | ) 13 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | 6 | aw "github.com/deanishe/awgo" 7 | ) 8 | 9 | var wf *aw.Workflow 10 | 11 | func init() { 12 | wf = aw.New() 13 | } 14 | 15 | func run() { 16 | prompts, err := GetPrompts() 17 | if err != nil { 18 | wf.FatalError(err) 19 | } 20 | 21 | for _, prompt := range prompts { 22 | wf.NewItem(prompt.Act). 23 | Subtitle(prompt.Prompt). 24 | Var("prompt", prompt.Prompt). 25 | Icon(&aw.Icon{Value: "./icon.png"}). 26 | Valid(true) 27 | } 28 | 29 | wf.Filter(os.Args[1]) 30 | 31 | wf.WarnEmpty("No Chat-GPT Prompts.", "Try different prompts.") 32 | 33 | wf.SendFeedback() 34 | } 35 | 36 | func main() { 37 | wf.Run(run) 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 bluewolfali 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🔍🧠 Alfred Plugin for ChatGPT Prompts 2 | 3 | This is a plugin for the Alfred app that provides a search feature using the array of prompts from the [awesome-chatgpt-prompts](https://github.com/f/awesome-chatgpt-prompts) project. 4 | 5 | ## Functionality 6 | 7 | This plugin allows users to search for prompts that can be used with the ChatGPT model for generating conversational responses. The array of prompts is sourced from the awesome-chatgpt-prompts project, which is continuously updated by contributors. 8 | 9 | The plugin fetches the latest data from the API provided by [Hugging Face](https://huggingface.co/datasets/fka/awesome-chatgpt-prompts) every 24 hours to ensure that the data is always up-to-date. 10 | 11 | ## Installation 12 | 13 | To install the plugin, simply download the [latest release](https://github.com/bluewolfali/awesome-chatgpt-prompts-alfred/releases) and double-click on the `.alfredworkflow` file to add it to Alfred. 14 | 15 | ## Usage 16 | 17 | Once installed, users can access the plugin by typing in the keyword `cp` followed by their search query. The plugin will display a list of prompts matching the search query, and the user can select one to copy it to their clipboard. 18 | 19 | ![MarineGEO circle logo](./images/screenshot1.gif "MarineGEO logo") 20 | 21 | ## Authorization 22 | 23 | The first time you use the workflow after installing or upgrading, you will see a security warning: 24 | 25 | 26 | 27 | This is a quirk of macOS 10.15 and above. Apple currently forces developers to pay $99 a year to be able to officially sign their executables and avoid this warning, which I'm not going to pay since I'm providing this workflow for free as an open source project. 28 | 29 | After seeing this warning, you have to go to **System Preferences > Security & Privacy > General** and click the new button that has appeared to allow the executable to run. You then have to run it again and you will see this security warning _again_ but now it will have a new button that lets you allow the executable to run. 30 | 31 | These warnings will appear once for each of the executables inside the workflow as you use new features. Once you have authorized all of them, you won't see these warnings anymore until you install a new version. 32 | 33 | ### Authorize All Executables 34 | 35 | If you want to authorize all Bear Workflow executables at once or if you do not see the above security warnings but the workflow isn't working, you can do the following: 36 | 37 | 1. Go to the **Workflows** section in Alfred Preferences 38 | 2. Right click on **Bear** _by drgrib_ and select **Open in Terminal** 39 | 3. Copy this command and execute it: 40 | 41 | ``` 42 | xattr -rd com.apple.quarantine cmd 43 | ``` 44 | 45 | This should authorize all the Alfred Bear the executables and fix the security errors. 46 | 47 | ### 🍎 Apple Silicon Macs 48 | 49 | If your mac is based on Apple Silicon chip, you need to have Rosetta installed on your system, otherwise Alfred workflows will fail silently. 50 | 51 | Screen Shot 2021-12-29 at 9 06 02 AM 52 | 53 | Copy this command and execute in terminal to install Rosetta: 54 | 55 | ```sh 56 | softwareupdate --install-rosetta 57 | ``` 58 | 59 | by [alfred-bear](https://github.com/drgrib/alfred-bear) 60 | 61 | ## Contribution 62 | 63 | If you have any suggestions or feature requests, please feel free to open an issue or submit a pull request on the [GitHub repository](https://github.com/yourusername/alfred-chatgpt-prompts). Contributions are always welcome! 64 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= 2 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 3 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 5 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/deanishe/awgo v0.29.1 h1:yKAyy0e+HR60iPxaKHhY3hdTM5GCsECpWTP79j04bHg= 7 | github.com/deanishe/awgo v0.29.1/go.mod h1:1yGF+uQfWXX99TiDfAYYKjJpHTq5lHEmvHFEVCHo6KA= 8 | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= 9 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 10 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 11 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 12 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 13 | github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= 14 | github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= 15 | github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= 16 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 17 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 18 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 19 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 20 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 21 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 22 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 23 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 24 | go.deanishe.net/env v0.5.1 h1:WiOncK5uJj8Um57Vj2dc1bq1lMN7fgRag9up7I3LZy0= 25 | go.deanishe.net/env v0.5.1/go.mod h1:ihEYfDm0K0hq3f5ACTCQDrMTWxH9fTiA1lh1i0aMqm0= 26 | go.deanishe.net/fuzzy v1.0.0 h1:3Qp6PCX0DLb9z03b5OHwAGsbRSkgJpSLncsiDdXDt4Y= 27 | go.deanishe.net/fuzzy v1.0.0/go.mod h1:2yEEMfG7jWgT1s5EO0TteVWmx2MXFBRMr5cMm84bQNY= 28 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 29 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 30 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 31 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 32 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 33 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 34 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 35 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 36 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 37 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 38 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= 39 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 40 | howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0= 41 | -------------------------------------------------------------------------------- /getAwesomeChatGPTPrompts.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "net/http" 9 | "os" 10 | "time" 11 | ) 12 | 13 | const AwesomeChatGETPromptsApiUrl = "https://datasets-server.huggingface.co/rows?dataset=fka%2Fawesome-chatgpt-prompts&config=default&split=train&offset=0&limit=100" 14 | 15 | type huggingFaceResponse struct { 16 | Dataset string `json:"dataset"` 17 | Config string `json:"config"` 18 | Split string `json:"split"` 19 | Features []struct { 20 | FeatureIdx int `json:"feature_idx"` 21 | Name string `json:"name"` 22 | Type struct { 23 | Dtype string `json:"dtype"` 24 | Type string `json:"_type"` 25 | } `json:"type"` 26 | } `json:"features"` 27 | Rows []struct { 28 | RowIdx int `json:"row_idx"` 29 | Row struct { 30 | Act string `json:"act"` 31 | Prompt string `json:"prompt"` 32 | } `json:"row"` 33 | TruncatedCells []interface{} `json:"truncated_cells"` 34 | } `json:"rows"` 35 | } 36 | 37 | type Prompts struct { 38 | Act string `json:"act"` 39 | Prompt string `json:"prompt"` 40 | } 41 | 42 | func GetPrompts() ([]Prompts, error) { 43 | if err := updateCheck(); err != nil { 44 | fmt.Println("Error updating check:", err) 45 | return nil, err 46 | } 47 | 48 | jsonBytes, err := ioutil.ReadFile("awesome-chatgpt-prompts.json") 49 | if err != nil { 50 | fmt.Println("Error reading JSON file:", err) 51 | return nil, err 52 | } 53 | 54 | var hfResp huggingFaceResponse 55 | err = json.Unmarshal(jsonBytes, &hfResp) 56 | 57 | var prompts []Prompts 58 | for _, row := range hfResp.Rows { 59 | prompts = append(prompts, Prompts{ 60 | Act: row.Row.Act, 61 | Prompt: row.Row.Prompt, 62 | }) 63 | } 64 | 65 | return prompts, nil 66 | } 67 | 68 | func updateCheck() error { 69 | if !fileExists("awesome-chatgpt-prompts.json") { 70 | err := downloadJSONFile() 71 | if err != nil { 72 | fmt.Println("Error downloading JSON file:", err) 73 | return err 74 | } 75 | } 76 | jsonBytes, err := ioutil.ReadFile("awesome-chatgpt-prompts.json") 77 | if err != nil { 78 | fmt.Println("Error reading JSON file:", err) 79 | return err 80 | } 81 | 82 | var hfResp huggingFaceResponse 83 | err = json.Unmarshal(jsonBytes, &hfResp) 84 | if err != nil { 85 | fmt.Println("Error unmarshalling JSON:", err) 86 | return err 87 | } 88 | 89 | fileModTime, err := getFileModTime("awesome-chatgpt-prompts.json") 90 | if err != nil { 91 | fmt.Println("Error getting file mod time:", err) 92 | return err 93 | } 94 | 95 | if time.Since(fileModTime) > 24*time.Hour { 96 | err := downloadJSONFile() 97 | if err != nil { 98 | fmt.Println("Error downloading JSON file:", err) 99 | return err 100 | } 101 | } 102 | 103 | return nil 104 | } 105 | 106 | func fileExists(filename string) bool { 107 | _, err := os.Stat(filename) 108 | return !os.IsNotExist(err) 109 | } 110 | 111 | func getFileModTime(filename string) (time.Time, error) { 112 | fileInfo, err := os.Stat(filename) 113 | if err != nil { 114 | return time.Time{}, err 115 | } 116 | return fileInfo.ModTime(), nil 117 | } 118 | 119 | func downloadJSONFile() error { 120 | resp, err := http.Get(AwesomeChatGETPromptsApiUrl) 121 | if err != nil { 122 | return err 123 | } 124 | defer func(Body io.ReadCloser) { 125 | err := Body.Close() 126 | if err != nil { 127 | fmt.Println("Error closing response body:", err) 128 | os.Exit(1) 129 | } 130 | }(resp.Body) 131 | jsonBytes, err := ioutil.ReadAll(resp.Body) 132 | if err != nil { 133 | return err 134 | } 135 | 136 | filename := fmt.Sprintf("awesome-chatgpt-prompts-%d.json", time.Now().Unix()) 137 | err = ioutil.WriteFile(filename, jsonBytes, 0644) 138 | if err != nil { 139 | return err 140 | } 141 | 142 | return os.Rename(filename, "awesome-chatgpt-prompts.json") 143 | 144 | } 145 | --------------------------------------------------------------------------------