├── .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 | 
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 |
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 |
--------------------------------------------------------------------------------