35 | );
36 | }
37 |
38 | const Cursor = () => (
39 |
57 | );
58 |
--------------------------------------------------------------------------------
/components/PromptLogo.module.css:
--------------------------------------------------------------------------------
1 | .logo {
2 | background-image: linear-gradient(135deg, #ff6363, #d72a2a);
3 | display: inline-flex;
4 | width: 24px;
5 | height: 24px;
6 | align-items: center;
7 | justify-content: center;
8 | border-radius: 6px;
9 | position: relative;
10 |
11 | svg {
12 | transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
13 | }
14 |
15 | [data-icon="raycast"] {
16 | opacity: 0;
17 | transform: scale(0.8) rotate(-45deg);
18 | position: absolute;
19 | }
20 |
21 | &:hover {
22 | [data-icon="stars"] {
23 | opacity: 0;
24 | transform: scale(0.8) rotate(45deg);
25 | }
26 |
27 | [data-icon="raycast"] {
28 | opacity: 1;
29 | transform: scale(1) rotate(0deg);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/components/PromptLogo.tsx:
--------------------------------------------------------------------------------
1 | import { StarsIcon, RaycastLogoNegIcon } from "@raycast/icons";
2 | import styles from "./PromptLogo.module.css";
3 |
4 | export function PromptLogo() {
5 | return (
6 |
7 |
8 |
9 |
10 | );
11 | }
12 |
--------------------------------------------------------------------------------
/components/ScrollArea.module.css:
--------------------------------------------------------------------------------
1 | .root {
2 | width: 100%;
3 | height: 100%;
4 | border-radius: 4px;
5 | overflow: hidden;
6 | --scrollbar-size: 10px;
7 | }
8 |
9 | .viewport {
10 | width: 100%;
11 | height: 100%;
12 | border-radius: inherit;
13 | }
14 |
15 | .scrollbar {
16 | display: flex;
17 | /* ensures no selection */
18 | user-select: none;
19 | /* disable browser handling of all panning and zooming gestures on touch devices */
20 | touch-action: none;
21 | padding: 3px;
22 | transition: background 160ms ease-out;
23 |
24 | &[data-orientation="vertical"] {
25 | width: var(--scrollbar-size);
26 | }
27 | &[data-orientation="horizontal"] {
28 | flex-direction: column;
29 | height: var(--scrollbar-size);
30 | }
31 | }
32 |
33 | .thumb {
34 | flex: 1;
35 | background: rgba(255, 255, 255, 0.1);
36 | border-radius: var(--scrollbar-size);
37 | position: relative;
38 |
39 | /* increase target size for touch devices https://www.w3.org/WAI/WCAG21/Understanding/target-size.html */
40 | &::before {
41 | content: "";
42 | position: absolute;
43 | top: 50%;
44 | left: 50%;
45 | transform: translate(-50%, -50%);
46 | width: 100%;
47 | height: 100%;
48 | min-width: 44px;
49 | min-height: 44px;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/components/ScrollArea.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
3 |
4 | import styles from "./ScrollArea.module.css";
5 |
6 | type ScrollAreaPrimitiveRootProps = React.ComponentProps<
7 | typeof ScrollAreaPrimitive.Root
8 | >;
9 |
10 | export const ScrollArea = React.forwardRef<
11 | React.ElementRef,
12 | ScrollAreaPrimitiveRootProps
13 | >(({ children }, forwardedRef) => (
14 |
15 |
16 | {children}
17 |
18 |
22 |
23 |
24 |
28 |
29 |
30 |
31 | ));
32 | ScrollArea.displayName = "ScrollArea";
33 |
--------------------------------------------------------------------------------
/components/Toast.module.css:
--------------------------------------------------------------------------------
1 | .viewport {
2 | position: fixed;
3 | inset: 0;
4 | display: flex;
5 | align-items: center;
6 | justify-content: center;
7 | list-style: none;
8 | z-index: 2147483647;
9 | outline: none;
10 | background-color: rgba(0, 0, 0, 0.5);
11 | transition: background-color 200ms;
12 |
13 | &:empty {
14 | background-color: transparent;
15 | }
16 | }
17 |
18 | .root {
19 | background-color: #3b383b;
20 | border-radius: 20px;
21 | padding: 0 18px;
22 | height: 40px;
23 | display: inline-flex;
24 | align-items: center;
25 |
26 | &[data-state="open"] {
27 | animation: show 150ms ease-in;
28 | }
29 | &[data-state="closed"] {
30 | animation: hide 150ms ease-in;
31 | }
32 | &[data-swipe="move"] {
33 | transform: translateY(var(--radix-toast-swipe-move-y));
34 | }
35 | &[data-swipe="cancel"] {
36 | transform: translateY(0);
37 | transition: transform 200ms ease-out;
38 | }
39 | &[data-swipe="end"] {
40 | animation: swipeOut 100ms ease-out;
41 | }
42 | }
43 |
44 | @keyframes show {
45 | from {
46 | opacity: 0;
47 | }
48 | to {
49 | opacity: 1;
50 | }
51 | }
52 | @keyframes hide {
53 | from {
54 | opacity: 1;
55 | }
56 | to {
57 | opacity: 0;
58 | }
59 | }
60 |
61 | @keyframes swipeOut {
62 | from {
63 | transform: translateY(var(--radix-toast-swipe-end-y));
64 | }
65 | to {
66 | transform: translateY(100%);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/components/Toast.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as ToastPrimitive from "@radix-ui/react-toast";
3 |
4 | import styles from "./Toast.module.css";
5 |
6 | type ToastPrimitiveRootProps = React.ComponentProps;
7 |
8 | export const Toast = React.forwardRef<
9 | React.ElementRef,
10 | ToastPrimitiveRootProps
11 | >(({ children, ...props }, forwardedRef) => {
12 | return (
13 |
14 | {children}
15 |
16 | );
17 | });
18 | Toast.displayName = "Toast";
19 |
20 | type ToastPrimitiveViewportProps = React.ComponentProps<
21 | typeof ToastPrimitive.Viewport
22 | >;
23 |
24 | export const ToastViewport = React.forwardRef<
25 | React.ElementRef,
26 | ToastPrimitiveViewportProps
27 | >((props, forwardedRef) => {
28 | return (
29 |
34 | );
35 | });
36 | ToastViewport.displayName = "ToastViewport";
37 |
38 | export const ToastProvider = ToastPrimitive.Provider;
39 | export const ToastTitle = ToastPrimitive.Title;
40 |
--------------------------------------------------------------------------------
/data/prompts.ts:
--------------------------------------------------------------------------------
1 | import { IconName, Icons } from "@raycast/icons";
2 | import { SVGProps } from "react";
3 |
4 | export type Model =
5 | | "openai-gpt-3.5-turbo-instruct"
6 | | "openai-gpt-3.5-turbo"
7 | | "openai-gpt-4"
8 | | "openai-gpt-4-turbo"
9 | | "anthropic-claude-haiku"
10 | | "anthropic-claude-opus"
11 | | "anthropic-claude-sonnet"
12 | | "perplexity-sonar-medium-online"
13 | | "perplexity-sonar-small-online"
14 | | "llama2-70b"
15 | | "mixtral-8x7b"
16 | | "codellama-70b-instruct";
17 |
18 | export type Prompt = {
19 | id: string;
20 | title: string;
21 | prompt: string;
22 | icon: IconName;
23 | creativity: "none" | "low" | "medium" | "high" | "maximum";
24 | model?: Model;
25 | date: `${number}-${number}-${number}`;
26 | author?: {
27 | name: string;
28 | link?: string;
29 | };
30 | };
31 |
32 | function generateSelection(selectionWord: string, resultWord: string) {
33 | return `\n\n${selectionWord}: {selection}\n\n${resultWord}:`;
34 | }
35 |
36 | const browser: Prompt[] = [
37 | {
38 | id: "inspect-webpage",
39 | title: "Inspect Webpage",
40 | prompt: `Describe me the tech stack used based on the following HTML document:
41 |
42 | {browser-tab format="html"}
43 |
44 | Consider every element of a tech stack, from frameworks to APIs through tools (analytics, monitoring, etc.). Include which fonts are used. Don't make any guesses on what’s used if there’s no evidence.`,
45 | creativity: "low",
46 | date: "2024-03-18",
47 | icon: "globe-01",
48 | model: "anthropic-claude-haiku",
49 | },
50 | {
51 | id: "summarize-youtube-video",
52 | title: "Summarize YouTube Video",
53 | prompt: `Create a summary of a YouTube video using its transcript. You will use the following template:
54 |
55 | """
56 | ## Summary
57 | {Multiple sentences summarising the YouTube video}
58 |
59 | ## Notes
60 | {Bullet points that summarize the key points or important moments from the video’s transcript with explanations}
61 |
62 | ## Quotes
63 | {Extract the best sentences from the transcript in a list}
64 | """
65 |
66 | Transcript: {browser-tab}`,
67 | creativity: "low",
68 | model: "anthropic-claude-haiku",
69 | date: "2024-03-18",
70 | icon: "play-filled",
71 | },
72 | ];
73 |
74 | const code: Prompt[] = [
75 | {
76 | id: "json-data",
77 | title: "Natural Language Processing",
78 | prompt:
79 | `Act as a natural language processing software. Analyze the given text and return me only a parsable and minified JSON object.\n
80 |
81 | Here's the JSON Object structure:
82 | {
83 | "key1": /* Some instructions */,
84 | "key2": /* Some instructions */,
85 | }
86 |
87 | Here are the rules you must follow:
88 | - You MUST return a valid, parsable JSON object.
89 | - More rules…
90 |
91 | Here are some examples to help you out:
92 | - Example 1…
93 | - Example 2…` + generateSelection("Text", "JSON Data"),
94 | creativity: "low",
95 | date: "2023-12-22",
96 | icon: "code",
97 | },
98 | {
99 | id: "css-to-tailwind",
100 | title: "Convert CSS code to Tailwind Classes",
101 | prompt:
102 | "Convert the following code into Tailwind CSS classes and give me the result in a code block. Make sure to remove any browser prefixes. Only give me what I can put into my HTML elements `class` properties." +
103 | generateSelection("Code", "Tailwind CSS classes"),
104 | creativity: "low",
105 | date: "2023-06-06",
106 | icon: "code",
107 | },
108 | {
109 | id: "linux-terminal",
110 | title: "Linux Terminal",
111 | prompt:
112 | "Act as a linux terminal. Execute the following code and reply with what the terminal should show. Only reply with the terminal output inside one unique code block, and nothing else. Do not write explanations." +
113 | generateSelection("Code", "Terminal"),
114 | creativity: "medium",
115 | date: "2023-06-06",
116 | icon: "code",
117 | },
118 | {
119 | id: "code-interpreter",
120 | title: "Code Interpreter",
121 | prompt:
122 | "Act as a {argument name=language} interpreter. Execute the {argument name=language} code and reply with the output. Do not provide any explanations." +
123 | generateSelection("Code", "Output"),
124 | creativity: "medium",
125 | date: "2023-06-06",
126 | icon: "code",
127 | },
128 | {
129 | id: "git-commands",
130 | title: "Git Commands",
131 | prompt:
132 | "Translate the text to Git commands. Only reply one unique code block, and nothing else. Do not write explanations." +
133 | generateSelection("Text", "Git commands"),
134 | creativity: "low",
135 | date: "2023-06-06",
136 | icon: "code",
137 | },
138 | {
139 | id: "regex-generator",
140 | title: "Regex Generator",
141 | prompt:
142 | "Generate a regular expression that match the specific patterns in the text. Return the regular expression in a format that can be easily copied and pasted into a regex-enabled text editor or programming language. Then, give clear and understandable explanations on what the regex is doing and how it is constructed." +
143 | generateSelection("Text", "Regex"),
144 | creativity: "medium",
145 | date: "2023-06-06",
146 | icon: "code",
147 | },
148 | {
149 | id: "convert-html-to-markdown",
150 | title: "Convert HTML to Markdown",
151 | prompt:
152 | "Convert the HTML code to Markdown." +
153 | generateSelection("HTML code", "Markdown"),
154 | creativity: "none",
155 | date: "2023-06-06",
156 | icon: "code",
157 | },
158 | {
159 | id: "add-debug-statements",
160 | title: "Add Debug Statements",
161 | prompt:
162 | "Act as a software engineer debugging its code. Add debug statements to the code. Add as many as necessary to make debugging easier." +
163 | generateSelection("Code", "Debugged code"),
164 | creativity: "medium",
165 | date: "2023-06-06",
166 | icon: "bug",
167 | },
168 | {
169 | id: "write-tests",
170 | title: "Write Tests",
171 | prompt:
172 | "As a software developer, I am currently working on a project using Jest, TypeScript, and React Testing Library. I would like you to help me generate unit tests for the given code. Analyze the given code and provide a single unit test with the necessary imports, without any additional explanations or comments, unless absolutely necessary. Avoid repeating imports and mocks you've mentioned already.\n\nIf I say 'next,' please give me another test for the same code. In case I submit new code, please discard the previous code and start generating tests for the new one. Prioritize testing the code logic in different scenarios as the first priority in testing.\n\nIf I provide specific instructions or ask you to test a particular part or scenario, please follow those instructions and generate the unit test accordingly. If I send you a Jest error, fix the problem and only return the lines which need to be changed in a readable format. Please format the output as a unique code block." +
173 | generateSelection("Code", "Output"),
174 | creativity: "medium",
175 | date: "2023-06-06",
176 | icon: "bug",
177 | author: {
178 | name: "Alireza Sheikholmolouki",
179 | link: "https://github.com/Alireza29675",
180 | },
181 | },
182 | {
183 | id: "write-docstring",
184 | title: "Write Docstring",
185 | prompt:
186 | "Write a docstring for the function. Make sure the documentation is detailed." +
187 | generateSelection("Function", "Docstring"),
188 | creativity: "low",
189 | date: "2023-06-06",
190 | icon: "blank-document",
191 | },
192 | {
193 | id: "convert-to-crontab",
194 | title: "Convert to Crontab Schedule",
195 | prompt: `Act as a knowledgable unix server admin. Given a cronjob schedule in natural language, respond with the correct crontab format for this exact schedule. Double-check your results, ensure it's valid crontab syntax, and respond with nothing but the crontab format.
196 |
197 | Example Schedule: at 5:30am every tuesday in may
198 | Expected Crontab: 30 5 * 5 2
199 |
200 | Schedule: {argument name="schedule"}
201 | Crontab: `,
202 | creativity: "low",
203 | date: "2024-04-21",
204 | icon: "code",
205 | author: {
206 | name: "Philipp Daun",
207 | link: "https://github.com/daun",
208 | },
209 | },
210 | ];
211 |
212 | const communication: Prompt[] = [
213 | {
214 | id: "translate-to-language",
215 | title: "Translate to Language",
216 | prompt:
217 | "Translate the text in {argument name=language}." +
218 | generateSelection("Text", "Translation"),
219 | creativity: "low",
220 | date: "2023-06-06",
221 | icon: "speech-bubble",
222 | },
223 | {
224 | id: "decline-mail",
225 | title: "Decline this Mail",
226 | prompt:
227 | "Write a polite and friendly email to decline the following email. The email should be written in a way that it can be sent to the recipient." +
228 | generateSelection("Email", "Declined email"),
229 | creativity: "low",
230 | date: "2023-06-06",
231 | icon: "envelope",
232 | },
233 | {
234 | id: "ask-question",
235 | title: "Ask Question",
236 | prompt:
237 | "Rewrite the following text as a concise and friendly message, phrased as a question. This should be written in a way that it can be sent in a chat application like Slack." +
238 | generateSelection("Text", "Question"),
239 | creativity: "low",
240 | date: "2023-06-06",
241 | icon: "question-mark-circle",
242 | },
243 | {
244 | id: "bluf-message",
245 | title: "BLUF Message",
246 | prompt:
247 | `Rewrite the following text as a bottom line up front (BLUF) message formatted in Markdown. The format of the message should be made of two parts:
248 |
249 | - The first part should be written in bold and convey the message's key information. It can either be a statement or a question. Don't lose any important detail in this part.
250 | - The second part should be put onto a new line. This should give more details and provide some background about the message.
251 |
252 | Make sure the message stays concise and clear so that readers don't lose extra time reading it.` +
253 | generateSelection("Text", "Rewritten text"),
254 | creativity: "low",
255 | date: "2023-06-06",
256 | icon: "speech-bubble-active",
257 | },
258 | {
259 | id: "summarize-long-email",
260 | title: "Summarize Long Emails",
261 | prompt:
262 | `Help me summarize the key points from the email text into a maximum of 5 bullet points, each preferably one sentence, and at most two sentences. Also, identify any action items requested of me.
263 |
264 | Key points:
265 |
266 |
267 | ...
268 |
269 | Asked from you:
270 |
271 |
272 |
273 | If there are no action items, the "Asked from you" section will be left empty.` +
274 | generateSelection("Email", "Output"),
275 | creativity: "low",
276 | date: "2023-06-06",
277 | icon: "envelope",
278 | author: {
279 | name: "Alireza Sheikholmolouki",
280 | link: "https://github.com/Alireza29675",
281 | },
282 | },
283 | {
284 | id: "debate-controversial-topic",
285 | title: "Debate a Topic",
286 | prompt:
287 | "Take a stance on the topic and {argument default=for} it. Construct a convincing argument and provide evidence to support your stance." +
288 | generateSelection("Topic", "Argument"),
289 | creativity: "high",
290 | date: "2023-06-06",
291 | icon: "speech-bubble-important",
292 | },
293 | {
294 | id: "create-calendar-event",
295 | title: "Create a Calendar Event",
296 | prompt:
297 | "Create a calendar event in ICS format based on the information. Include the start time, the end time, the location, all attendees, and a summary. If no end time is provided, assume the event will be one hour long. Add a reminder 1 hour before the event starts and 1 day before the event starts. Don't include the PRODID property. Only output the code block. Don't add any comments." +
298 | generateSelection("Information", "ICS"),
299 | creativity: "medium",
300 | date: "2023-06-06",
301 | icon: "calendar",
302 | author: {
303 | name: "Roel Van Gils",
304 | link: "https://github.com/roelvangils",
305 | },
306 | },
307 | {
308 | id: "break-up-wall-of-text",
309 | title: "Break Up Wall of Text",
310 | prompt: `Take the wall of text below and write a cleaned up version inserting naturally appropriate paragraph breaks. It's important that the text does not change, only the whitespace.
311 |
312 | Wall of text:
313 | {selection}
314 |
315 | Cleaned up version:
316 | `,
317 | creativity: "none",
318 | date: "2023-11-06",
319 | icon: "paragraph",
320 | },
321 | {
322 | id: "summarize-and-sympathize",
323 | title: "Summarize and sympathize text",
324 | prompt:
325 | "Please summarize and omit the following. Then express your empathy." +
326 | generateSelection("Text", "Sympathy"),
327 | creativity: "low",
328 | date: "2023-06-12",
329 | icon: "speech-bubble",
330 | author: {
331 | name: "nagauta",
332 | link: "https://github.com/nagauta",
333 | },
334 | },
335 | {
336 | id: "fill-the-gap",
337 | title: "Fill in the gap",
338 | prompt:
339 | `Use the following instructions to rewrite the text
340 |
341 | Give me 5 words that most accurarely fill in the blank in a sentence.
342 |
343 | The blank is represented by a few underscores, such as ___, or ______.
344 |
345 | So for example: "I'm super ___ to announce my new product".
346 |
347 | 1. I'm super happy to announce my new product
348 | 2. I'm super excited to announce my new product
349 | 3. I'm super pumped to announce my new product
350 | 4. I'm super proud to announce my new product
351 | 5. I'm super nervous to announce my new product
352 |
353 | Now do the same for this sentece:` +
354 | generateSelection("Text", "Rewritten text"),
355 | creativity: "high",
356 | date: "2023-08-03",
357 | icon: "speech-bubble",
358 | author: {
359 | name: "peduarte",
360 | link: "https://github.com/peduarte",
361 | },
362 | },
363 | ];
364 |
365 | const image: Prompt[] = [
366 | {
367 | id: "youtube-script",
368 | title: "Create a YouTube Script",
369 | prompt:
370 | "Create a compelling and captivating YouTube script based on the text. Make sure to include B-Rolls in the script. Make the script as long as necessary to make a video of {argument name=minutes default=10} minutes." +
371 | generateSelection("Text", "Script"),
372 | creativity: "high",
373 | date: "2023-06-06",
374 | icon: "image",
375 | },
376 | {
377 | id: "midjourney-prompt-generator",
378 | title: "Midjourney Prompt Generator",
379 | prompt:
380 | `Based on the text, generate an "imagine prompt" that contains a maximum word count of 1,500 words that will be used as input for an AI-based text to image program called MidJourney based on the following parameters: /imagine prompt: [1], [2], [3], [4], [5], [6]
381 |
382 | In this prompt, [1] should be replaced with a random subject and [2] should be a short concise description about that subject. Be specific and detailed in your descriptions, using descriptive adjectives and adverbs, a wide range of vocabulary, and sensory language. Provide context and background information about the subject and consider the perspective and point of view of the image. Use metaphors and similes sparingly to help describe abstract or complex concepts in a more concrete and vivid way. Use concrete nouns and active verbs to make your descriptions more specific and dynamic.
383 |
384 | [3] should be a short concise description about the environment of the scene. Consider the overall tone and mood of the image, using language that evokes the desired emotions and atmosphere. Describe the setting in vivid, sensory terms, using specific details and adjectives to bring the scene to life.
385 |
386 | [4] should be a short concise description about the mood of the scene. Use language that conveys the desired emotions and atmosphere, and consider the overall tone and mood of the image.
387 |
388 | [5] should be a short concise description about the atmosphere of the scene. Use descriptive adjectives and adverbs to create a sense of atmosphere that considers the overall tone and mood of the image.
389 |
390 | [6] should be a short concise description of the lighting effect including Types of Lights, Types of Displays, Lighting Styles and Techniques, Global Illumination and Shadows. Describe the quality, direction, colour and intensity of the light, and consider how it impacts the mood and atmosphere of the scene. Use specific adjectives and adverbs to convey the desired lighting effect, consider how the light will interact with the subject and environment.
391 |
392 | It's important to note that the descriptions in the prompt should be written back to back, separated with commas and spaces, and should not include any line breaks or colons. Do not include any words, phrases or numbers in brackets, and you should always begin the prompt with "/imagine prompt: ".
393 |
394 | Be consistent in your use of grammar and avoid using cliches or unnecessary words. Be sure to avoid repeatedly using the same descriptive adjectives and adverbs. Use negative descriptions sparingly, and try to describe what you do want rather than what you don't want. Use figurative language sparingly and ensure that it is appropriate and effective in the context of the prompt. Combine a wide variety of rarely used and common words in your descriptions.
395 |
396 | The "imagine prompt" should strictly contain under 1,500 words. Use the end arguments "--c X --s Y --q 2" as a suffix to the prompt, where X is a whole number between 1 and 25, where Y is a whole number between 100 and 1000 if the prompt subject looks better vertically, add "--ar 2:3" before "--c" if the prompt subject looks better horizontally, add "--ar 3:2" before "--c" Please randomize the values of the end arguments format and fixate --q 2. Please do not use double quotation marks or punctuation marks. Please use randomized end suffix format.` +
397 | generateSelection("Text", "Midjourney Prompt"),
398 | creativity: "high",
399 | date: "2023-06-06",
400 | icon: "image",
401 | },
402 | {
403 | id: "generate-icons",
404 | title: "Generate Icons",
405 | prompt:
406 | "Generate base64 data URIs of 100x100 SVG icons representing the text. Do not provide any commentary other than the list of data URIs as markdown images. For each icon, explain how it relates to the text." +
407 | generateSelection("Text", "Icons"),
408 | creativity: "maximum",
409 | date: "2023-06-06",
410 | icon: "image",
411 | author: {
412 | name: "Stephen Kaplan",
413 | link: "https://github.com/SKaplanOfficial",
414 | },
415 | },
416 | ];
417 |
418 | const writing: Prompt[] = [
419 | {
420 | id: "write-story",
421 | title: "Write a Story",
422 | prompt:
423 | "Write a story based on the text. Make the story engaging. The story shouldn't be more than {argument name=number default=500} words." +
424 | generateSelection("Text", "Story"),
425 | creativity: "high",
426 | date: "2023-06-06",
427 | icon: "pencil",
428 | },
429 | {
430 | id: "blog-post",
431 | title: "Write a Blog Post",
432 | prompt:
433 | "Write a blog post on the topic. Don't use more than {argument name=number default=1000} words" +
434 | generateSelection("Topic", "Blog post"),
435 | creativity: "high",
436 | date: "2023-06-06",
437 | icon: "pencil",
438 | },
439 | {
440 | id: "twitter-thread",
441 | title: "Twitter Thread",
442 | prompt:
443 | "Convert the text into a list of tweets (= Twitter thread). The first tweet should be clear and engaging. Each tweet should flow smoothly into the next, building anticipation and momentum. The last tweet should be impactful so that the user can reflect on the whole thread. Make sure each tweet doesn't exceed 280 characters. Don't add a single hashtag to any of the tweets." +
444 | generateSelection("Text", "Tweets"),
445 | creativity: "medium",
446 | date: "2023-06-06",
447 | icon: "bird",
448 | },
449 | ];
450 |
451 | const music: Prompt[] = [
452 | {
453 | id: "write-a-song",
454 | title: "Write a Song",
455 | prompt:
456 | "Write a song based on the given text. The song should have a clear melody, lyrics that tell a story, and a memorable chorus. The mood of the song should be {argument name=mood}." +
457 | generateSelection("Text", "Song"),
458 | creativity: "high",
459 | date: "2023-06-06",
460 | icon: "music",
461 | },
462 | {
463 | id: "playlist-maker",
464 | title: "Playlist Maker",
465 | prompt:
466 | "Act as a song recommender. Based on the given song, create a playlist of 10 similar songs. Provide a name and description for the playlist. Do not choose songs that are the same name or artist. Do not include the original song in the playlist." +
467 | generateSelection("Song", "Playlist"),
468 | creativity: "high",
469 | date: "2023-06-06",
470 | icon: "music",
471 | },
472 | ];
473 |
474 | const ideas: Prompt[] = [
475 | {
476 | id: "write-alternatives",
477 | title: "Write 10 Alternatives",
478 | prompt:
479 | "Give me 10 alternative versions of the text. Ensure that the alternatives are all distinct from one another." +
480 | generateSelection("Text", "Alternatives"),
481 | creativity: "high",
482 | date: "2023-06-06",
483 | icon: "shuffle",
484 | },
485 | {
486 | id: "project-ideas",
487 | title: "Project Ideas",
488 | prompt:
489 | "Brainstorm 5 project ideas based on the text. Make sure the ideas are distinct from one another." +
490 | generateSelection("Text", "Ideas"),
491 | creativity: "high",
492 | date: "2023-06-06",
493 | icon: "shuffle",
494 | author: {
495 | name: "Stephen Kaplan",
496 | link: "https://github.com/SKaplanOfficial",
497 | },
498 | },
499 | {
500 | id: "create-analogies",
501 | title: "Create Analogies",
502 | prompt:
503 | "Develop {argument name=number default=3} creative analogies or metaphors that help explain the main idea of the text." +
504 | generateSelection("Text", "Analogies"),
505 | creativity: "high",
506 | date: "2023-06-06",
507 | icon: "light-bulb",
508 | },
509 | ];
510 |
511 | const fun: Prompt[] = [
512 | {
513 | id: "act-as-a-character",
514 | title: "Act As a Character",
515 | prompt:
516 | "Rewrite the text as if you were {argument name=character default=yoda}. Use {argument name=character default=yoda}'s tone, manner and vocabulary. You must know all of the knowledge of {argument name=character default=yoda}." +
517 | generateSelection("Text", "Rewritten text"),
518 | creativity: "medium",
519 | date: "2023-06-06",
520 | icon: "person",
521 | },
522 | {
523 | id: "drunkgpt",
524 | title: "DrunkGPT",
525 | prompt:
526 | "Rewrite the text as if you were drunk." +
527 | generateSelection("Text", "Rewritten text"),
528 | creativity: "medium",
529 | date: "2023-06-06",
530 | icon: "game-controller",
531 | },
532 | ];
533 |
534 | const misc: Prompt[] = [
535 | {
536 | id: "tldr",
537 | title: "TL;DR",
538 | prompt:
539 | "Extract all facts from the text and summarize it in all relevant aspects in up to seven bullet points and a 1-liner summary. Pick a good matching emoji for every bullet point." +
540 | generateSelection("Text", "Summary"),
541 | creativity: "low",
542 | date: "2023-06-06",
543 | icon: "bullet-points",
544 | },
545 | {
546 | id: "title-case",
547 | title: "Title Case",
548 | prompt: "Convert {selection} to title case.",
549 | creativity: "low",
550 | date: "2023-06-06",
551 | icon: "text",
552 | },
553 | {
554 | id: "emoji-suggestion",
555 | title: "Emoji Suggestion",
556 | prompt:
557 | "Suggest emojis that relate to the text. Suggest around 10 emojis and order them by relevance. Don't add any duplicates. Only respond with emojis." +
558 | generateSelection("Text", "Emojis"),
559 | creativity: "medium",
560 | date: "2023-06-06",
561 | icon: "emoji",
562 | },
563 | {
564 | id: "find-synonyms",
565 | title: "Find Synonyms",
566 | prompt:
567 | "Find synonyms for the word {selection} and format the output as a list. Words should exist. Do not write any explanations. Do not include the original word in the list. The list should not have any duplicates.",
568 | creativity: "medium",
569 | date: "2023-06-06",
570 | icon: "text",
571 | },
572 | {
573 | id: "create-recipe",
574 | title: "Give Me a Recipe",
575 | prompt:
576 | "Give me a recipe based on the ingredients. The recipe should be easy to follow." +
577 | generateSelection("Ingredients", "Recipe"),
578 | creativity: "medium",
579 | date: "2023-06-06",
580 | icon: "bullet-points",
581 | },
582 | {
583 | id: "create-action-items",
584 | title: "Create Action Items",
585 | prompt:
586 | "Generate a markdown list of action items to complete based on the text, using a unique identifier for each item as bold headings. If there are any errors in the text, make action items to fix them. In a sublist of each item, provide a description, priority, estimated level of difficulty, and a reasonable duration for the task." +
587 | generateSelection("Text", "Action items"),
588 | creativity: "medium",
589 | date: "2023-06-06",
590 | icon: "check-circle",
591 | author: {
592 | name: "Stephen Kaplan",
593 | link: "https://github.com/SKaplanOfficial",
594 | },
595 | },
596 | {
597 | id: "create-task-list",
598 | title: "Create Task List",
599 | prompt:
600 | "List detailed action steps in markdown format based on the provided text. Ensure the tasks can be efficiently completed." +
601 | generateSelection("Text", "Tasks"),
602 | creativity: "medium",
603 | date: "2024-05-04",
604 | icon: "flag",
605 | author: {
606 | name: "Abner Shang",
607 | link: "https://www.linkedin.com/in/abnershang/",
608 | },
609 | },
610 | {
611 | id: "extract-email-addresses",
612 | title: "Extract Email Addresses",
613 | prompt:
614 | "Extract all email addresses in the text and list them using markdown. Include anything that might be an email address. If possible, provide the name of the person or company to which the email address belongs." +
615 | generateSelection("Text", "Email addresses"),
616 | creativity: "low",
617 | date: "2023-06-06",
618 | icon: "envelope",
619 | author: {
620 | name: "Stephen Kaplan",
621 | link: "https://github.com/SKaplanOfficial",
622 | },
623 | },
624 | {
625 | id: "extract-phone-numbers",
626 | title: "Extract Phone Numbers",
627 | prompt:
628 | "Identify all phone numbers in the text and list them using markdown. Include anything that might be a phone number. If possible, provide the name of the person or company to which the phone number belongs." +
629 | generateSelection("Text", "Phone numbers"),
630 | creativity: "low",
631 | date: "2023-06-06",
632 | icon: "phone",
633 | author: {
634 | name: "Stephen Kaplan",
635 | link: "https://github.com/SKaplanOfficial",
636 | },
637 | },
638 | {
639 | id: "extract-links",
640 | title: "Extract Links",
641 | prompt:
642 | "Extract links in the text. Do not provide any commentary other than the list of Markdown links." +
643 | generateSelection("Text", "Links"),
644 | creativity: "low",
645 | date: "2023-06-06",
646 | icon: "link",
647 | author: {
648 | name: "Stephen Kaplan",
649 | link: "https://github.com/SKaplanOfficial",
650 | },
651 | },
652 | {
653 | id: "pros-and-cons",
654 | title: "Pros & Cons",
655 | prompt:
656 | "List pros and cons for the text based on the topics mentioned. Format the response as a markdown list of pros and cons. Do not provide any other commentary." +
657 | generateSelection("Text", "Pros & Cons"),
658 | creativity: "low",
659 | date: "2023-06-06",
660 | icon: "bullet-points",
661 | author: {
662 | name: "Stephen Kaplan",
663 | link: "https://github.com/SKaplanOfficial",
664 | },
665 | },
666 | {
667 | id: "eli",
668 | title: "Explain Like I'm a…",
669 | prompt:
670 | `Explain the text like I’m a {argument name=identity default="5 year old"}` +
671 | generateSelection("Text", "Explanation"),
672 | creativity: "low",
673 | date: "2023-06-06",
674 | icon: "book",
675 | },
676 | {
677 | id: "text-analysis",
678 | title: "Text Analysis",
679 | prompt:
680 | "Analyze the text and provide insights on its tone, style, and potential audience." +
681 | generateSelection("Text", "Analysis"),
682 | creativity: "medium",
683 | date: "2023-06-06",
684 | icon: "magnifying-glass",
685 | },
686 | {
687 | id: "summarize-product-reviews",
688 | title: "Summarize Product Reviews",
689 | prompt:
690 | `Carefully read the product reviews below. Translate them to English and create a summary of all the reviews in English and list them as Pros and Cons in the bullet point format. Remember that each bullet point should be one sentence or at max two short sentences. Most frequently mentioned should come first in each list and every bullet point should have a percentage showing how much evidence the reviews have brought for that pro or con. For example if reviews are mentioning that product is going bad easily and they brought some reasons for what they are saying, the percentage of your confidence should go higher, but if there are some reviews which are unsure about something or there are no evidence or it's not repeated frequently then the percentage should go lower. At the end you should write a paragraph about what I should pay attention to, before buying this product. These can be some warnings or some tips or some suggestions, points that I will miss, or anything that you think is important to know before buying this product.
691 |
692 | You can use the following template to create the summary:
693 |
694 | '''
695 | ## Summary of the reviews
696 |
697 | **✅ Pros:**
698 | - Pro 1 - percentage of your confidence%
699 | - Pro 2 - percentage of your confidence%
700 | ...
701 | - Pro n - percentage of your confidence%
702 |
703 | **❌ Cons:**
704 | - Con 1 - percentage of your confidence%
705 | - Con 2 - percentage of your confidence%
706 | ...
707 | - Con n - percentage of your confidence%
708 |
709 | **💡 You should pay attention to:**
710 | - Tip 1
711 | - Tip 2
712 | ...
713 | - Tip n
714 | '''` + generateSelection("Product reviews", "Summary"),
715 | creativity: "low",
716 | date: "2023-06-16",
717 | icon: "tag",
718 | author: {
719 | name: "Alireza Sheikholmolouki",
720 | link: "https://github.com/Alireza29675",
721 | },
722 | },
723 | ];
724 |
725 | const raycast: Prompt[] = [
726 | {
727 | id: "improve-writing-custom",
728 | title: "Improve Writing - Editable",
729 | prompt:
730 | `Act as a spelling corrector, content writer, and text improver/editor. Reply to each message only with the rewritten text
731 | Stricly follow these rules:
732 | - Correct spelling, grammar, and punctuation errors in the given text
733 | - Enhance clarity and conciseness without altering the original meaning
734 | - Divide lengthy sentences into shorter, more readable ones
735 | - Eliminate unnecessary repetition while preserving important points
736 | - Prioritize active voice over passive voice for a more engaging tone
737 | - Opt for simpler, more accessible vocabulary when possible
738 | - ALWAYS ensure the original meaning and intention of the given text
739 | - ALWAYS detect and maintain the original language of the text
740 | - ALWAYS maintain the existing tone of voice and style, e.g. formal, casual, polite, etc.
741 | - NEVER surround the improved text with quotes or any additional formatting
742 | - If the text is already well-written and requires no improvement, don't change the given text` +
743 | generateSelection("Text", "Improved Text"),
744 | creativity: "low",
745 | date: "2024-04-23",
746 | icon: "raycast-logo-neg",
747 | model: "anthropic-claude-haiku",
748 | },
749 | {
750 | id: "fix-spelling-and-grammar-custom",
751 | title: "Fix Spelling and Grammar - Editable",
752 | prompt:
753 | `Act as a spelling corrector and improver. Reply to each message only with the rewritten text
754 |
755 | Strictly follow these rules:
756 | - Correct spelling, grammar and punctuation
757 | - ALWAYS detect and maintain the original language of the text
758 | - NEVER surround the rewritten text with quotes
759 | - Don't replace urls with markdown links
760 | - Don't change emojis` + generateSelection("Text", "Fixed Text"),
761 | creativity: "low",
762 | date: "2024-04-23",
763 | icon: "raycast-logo-neg",
764 | model: "openai-gpt-3.5-turbo",
765 | },
766 | {
767 | id: "explain-this-in-simple-terms-custom",
768 | title: "Explain This in Simple Terms - Editable",
769 | prompt:
770 | `Act as a dictionary and encyclopedia, providing clear and concise explanations for given words or concepts.
771 |
772 | Strictly follow these rules:
773 | - Explain the text in a simple and concise language
774 | - For a single word, provide a brief, easy-to-understand definition
775 | - For a concept or phrase, give a concise explanation that breaks down the main ideas into simple terms
776 | - Use examples or analogies to clarify complex topics when necessary
777 | - Only reply with the explanation or definition
778 |
779 | Some examples:
780 | Text: Philosophy
781 | Explanation: Philosophy is the study of the fundamental nature of knowledge, reality, and existence. It is a system of ideas that attempts to explain the world and our place in it. Philosophers use logic and reason to explore the meaning of life and the universe.` +
782 | generateSelection("Text", "Explanation"),
783 | creativity: "low",
784 | date: "2024-04-23",
785 | icon: "raycast-logo-neg",
786 | model: "openai-gpt-3.5-turbo",
787 | },
788 | {
789 | id: "make-longer-custom",
790 | title: "Make Longer - Editable",
791 | prompt:
792 | `Act as a professional content writer tasked with expanding a client's text while maintaining its essence and style. Reply to each message only with the rewritten text
793 |
794 | Stictly follow these rules:
795 | - ALWAYS preserve the original tone, voice, and language of the text
796 | - Identify and expand the most critical information and key points
797 | - Avoid repetition
798 | - Stay factual close to the provided text
799 | - Keep URLs in their original format without replacing them with markdown links
800 | - Only reply with the expanded text` +
801 | generateSelection("Text", "Expanded text"),
802 | creativity: "high",
803 | date: "2024-04-23",
804 | icon: "raycast-logo-neg",
805 | model: "openai-gpt-3.5-turbo",
806 | },
807 | {
808 | id: "make-shorter-custom",
809 | title: "Make Shorter - Editable",
810 | prompt:
811 | `Act as a professional content writer tasked with shortening a client's text while maintaining its essence and style. Reply to each message only with the rewritten text
812 |
813 | Strictly follow these rules:
814 | - ALWAYS preserve the original tone, voice, and language of the text
815 | - Identify and retain the most critical information and key points
816 | - Eliminate redundancies and repetitive phrases or sentences
817 | - Keep URLs in their original format without replacing them with markdown links
818 | - Ensure the shortened text flows smoothly and maintains coherence
819 | - Aim to reduce the word count as much as possible without compromising the core meaning and style
820 | - Only reply with the shortend text` +
821 | generateSelection("Text", "Shortened text"),
822 | creativity: "low",
823 | date: "2024-04-23",
824 | icon: "raycast-logo-neg",
825 | model: "anthropic-claude-haiku",
826 | },
827 | {
828 | id: "change-tone-to-professional",
829 | title: "Change Tone to Professional - Editable",
830 | prompt:
831 | `Act as a professional content writer and editor. Reply to each message only with the rewritten text
832 |
833 | Strictly follow these rules:
834 | - Professional tone of voice
835 | - Formal language
836 | - Accurate facts
837 | - Correct spelling, grammar, and punctuation
838 | - Concise phrasing
839 | - meaning unchanged
840 | - Length retained
841 | - Don't replace urls with markdown links
842 | - ALWAYS detect and maintain the original language of the text` +
843 | generateSelection("Text", "Rewritten text"),
844 | creativity: "low",
845 | date: "2024-04-23",
846 | icon: "raycast-logo-neg",
847 | model: "openai-gpt-3.5-turbo",
848 | },
849 | {
850 | id: "change-tone-to-friendly",
851 | title: "Change Tone to Friendly - Editable",
852 | prompt:
853 | `Act as a content writer and editor. Reply to each message only with the rewritten text
854 |
855 | Strictly follow these rules:
856 | - Friendly and optimistic tone of voice
857 | - Correct spelling, grammar, and punctuation
858 | - Meaning unchanged
859 | - Length retained
860 | - Don't replace urls with markdown links
861 | - ALWAYS detect and maintain the original language of the text` +
862 | generateSelection("Text", "Rewritten text"),
863 | creativity: "low",
864 | date: "2024-04-23",
865 | icon: "raycast-logo-neg",
866 | model: "openai-gpt-3.5-turbo",
867 | },
868 | {
869 | id: "change-tone-to-confident-custom",
870 | title: "Change Tone to Confident - Editable",
871 | prompt:
872 | `Act as a content writer and editor. Reply to each message only with the rewritten text
873 |
874 | Strictly follow these rules:
875 | - Use confident, formal and friendly tone of voice
876 | - Avoid hedging, be definite where possible
877 | - Skip apologies
878 | - Focus on main arguments
879 | - Correct spelling, grammar, and punctuation
880 | - Keep meaning unchanged
881 | - Keep length retained
882 | - Don't replace urls with markdown links
883 | - ALWAYS detect and maintain the original language of the text` +
884 | generateSelection("Text", "Rewritten text"),
885 | creativity: "low",
886 | date: "2024-04-23",
887 | icon: "raycast-logo-neg",
888 | model: "openai-gpt-3.5-turbo",
889 | },
890 | {
891 | id: "change-tone-to-casual-custom",
892 | title: "Change Tone to Casual - Editable",
893 | prompt:
894 | `Act as a content writer and editor. Reply to each message only with the rewritten text
895 |
896 | Strictly follow these rules:
897 | - Use casual and friendly tone of voice
898 | - Use active voice
899 | - Keep sentences shorts
900 | - Ok to use slang and contractions
901 | - Keep grammatical person
902 | - Correct spelling, grammar, and punctuation
903 | - Keep meaning unchanged
904 | - Keep length retained
905 | - Don't replace urls with markdown links
906 | - ALWAYS detect and maintain the original language of the text` +
907 | generateSelection("Text", "Rewritten text"),
908 | creativity: "low",
909 | date: "2024-04-23",
910 | icon: "raycast-logo-neg",
911 | model: "openai-gpt-3.5-turbo",
912 | },
913 | {
914 | id: "rephrase-as-tweet-custom",
915 | title: "Rephrase as Tweet - Editable",
916 | prompt:
917 | `You're an expert in the field and have the perfect opportunity to share your ideas and insights with a huge audience!. Rewrite the text as a tweet that is:
918 | - Casual and upbeat
919 | - Creative and catchy
920 | - Focused on key takeaways that challenge the status quo
921 | - Engaging and punchy
922 | - Don't replace urls with markdown links
923 | - IMPORTANT: less than 25 words.
924 | - IMPORTANT: doesn't include hash, hashtags and words starting with #, i.e. #innovation #Technology
925 | - ALWAYS detect and maintain the original language of the text
926 |
927 | Text:
928 | The concept of Rayday is simple. Every Friday, everyone can use the day to work on something that benefits Raycast. From new features, to fixing bugs, drafting documentation or tidying up, it’s time for us to take a break from project work. As well as getting creative with our own ideas, it’s a great chance to act on feedback from our users and community too.
929 |
930 | Tweet:
931 | ⚒️ We hack every Friday – we call it 'Rayday'. Everyone can use the day to work on something that benefits Raycast – aside from normal project work.` +
932 | generateSelection("Text", "Tweet"),
933 | creativity: "high",
934 | date: "2024-04-23",
935 | icon: "raycast-logo-neg",
936 | model: "openai-gpt-3.5-turbo",
937 | },
938 | {
939 | id: "explain-code-custom",
940 | title: "Explain Code Step by Step - Editable",
941 | prompt:
942 | `Act as a software engineer with deep understanding of any programming language and it's documentation. Explain how the code works step by step in a list. Be concise with a casual tone of voice and write it as documentation for others.
943 |
944 | Code:
945 | \`\`\`
946 | function GoToPreviousPageAction() {
947 | const [page, setPage] = useGlobalState("page");
948 | return (
949 | setPage(Math.max(page - 1, 0))}
954 | />
955 | );
956 | }
957 | \`\`\`
958 |
959 | Explanation:
960 | The code is a React component that goes to the previous page.
961 | 1. The component renders an 'Action' component with an icon, title, and shortcut.
962 | 3. The 'useGlobalState' hook is used to get the current page number from the global state.
963 | 4. The 'onAction' prop is used to set the page number to one less than the current page number.
964 | 5. This will cause the page to go back one page when the action is taken.
965 | 6. The page is capped at 0 so that the page is never negative.` +
966 | generateSelection("Code", "Explanation"),
967 | creativity: "medium",
968 | date: "2024-04-23",
969 | icon: "raycast-logo-neg",
970 | model: "openai-gpt-3.5-turbo",
971 | },
972 | {
973 | id: "find-bugs-custom",
974 | title: "Find Bugs in Code - Editable",
975 | prompt:
976 | `Act as a software engineer with deep understanding of any programming language. Review the code to fix logical bugs in the code. Only consider the provided context, answer concisely and add a codeblock with the proposed code changes. If you can't confidently find bugs, answer with "Nothing found - LGTM 👍"..
977 |
978 | Code:
979 | \`\`\`
980 | function PrevAction() {
981 | const [page, setPage] = useGlobalState("page");
982 | return (
983 | setPage(page - 1)}
986 | />
987 | );
988 | }
989 | \`\`\`
990 |
991 | Review:
992 | The code is missing a check to make sure \`page\` is greater than 0 before subtracting 1. Otherwise, the page could be set to -1 which might cause unexpected behavior.
993 | \`\`\`
994 | function PrevAction() {
995 | const [page, setPage] = useGlobalState("page");
996 | return (
997 | setPage(Math.max(page - 1, 0))}
1000 | />
1001 | );
1002 | }
1003 | \`\`\`
1004 |
1005 | Code:
1006 | \`\`\`
1007 | private func submit(_ text: String) {
1008 | guard !text.isEmpty else { return }
1009 | let prompt = OpenAIPrompt(prompt: text, imitateChatGPT: true)
1010 | submit(prompt)
1011 | }
1012 | \`\`\`
1013 |
1014 | Review:
1015 | Nothing found - LGTM 👌` + generateSelection("Code", "Review"),
1016 | creativity: "medium",
1017 | date: "2024-04-23",
1018 | icon: "raycast-logo-neg",
1019 | model: "openai-gpt-3.5-turbo",
1020 | },
1021 | {
1022 | id: "summarize-webpage-custom",
1023 | title: "Summarize Webpage - Editable",
1024 | prompt: `Summarize the provided webpage with the following format:
1025 | """
1026 | ##
1027 |
1028 |
1029 |
1030 | ### Key Takeaways
1031 |
1032 | -
1033 | """
1034 |
1035 | Some rules to follow precisely:
1036 | - ALWAYS capture the tone, perspective and POV of the author
1037 | - NEVER come up with additional information
1038 |
1039 | Here's the webpage information:
1040 | {browser-tab}`,
1041 | creativity: "low",
1042 | date: "2024-03-21",
1043 | icon: "raycast-logo-neg",
1044 | model: "anthropic-claude-haiku",
1045 | },
1046 | ];
1047 |
1048 | type IconComponent = (props: SVGProps) => JSX.Element;
1049 |
1050 | export type Category = {
1051 | name: string;
1052 | slug: string;
1053 | prompts: (Prompt & { iconComponent: IconComponent })[];
1054 | icon: IconName;
1055 | iconComponent: IconComponent;
1056 | };
1057 |
1058 | export const baseCategories: Category[] = [
1059 | {
1060 | name: "Code",
1061 | slug: "/code",
1062 | prompts: [...code],
1063 | icon: "code" as const,
1064 | },
1065 | {
1066 | name: "Browser",
1067 | slug: "/browser",
1068 | prompts: [...browser],
1069 | icon: "globe-01" as const,
1070 | },
1071 | {
1072 | name: "Communication",
1073 | slug: "/communication",
1074 | prompts: [...communication],
1075 | icon: "envelope" as const,
1076 | },
1077 | {
1078 | name: "Image",
1079 | slug: "/image",
1080 | prompts: [...image],
1081 | icon: "image" as const,
1082 | },
1083 | {
1084 | name: "Writing",
1085 | slug: "/writing",
1086 | prompts: [...writing],
1087 | icon: "pencil" as const,
1088 | },
1089 | {
1090 | name: "Music",
1091 | slug: "/music",
1092 | prompts: [...music],
1093 | icon: "music" as const,
1094 | },
1095 | {
1096 | name: "Ideas",
1097 | slug: "/ideas",
1098 | prompts: [...ideas],
1099 | icon: "light-bulb" as const,
1100 | },
1101 | {
1102 | name: "Fun",
1103 | slug: "/fun",
1104 | prompts: [...fun],
1105 | icon: "game-controller" as const,
1106 | },
1107 | {
1108 | name: "Misc",
1109 | slug: "/misc",
1110 | prompts: [...misc],
1111 | icon: "folder" as const,
1112 | },
1113 | {
1114 | name: "Raycast Prompts",
1115 | slug: "/raycast",
1116 | prompts: [...raycast],
1117 | icon: "raycast-logo-neg" as const,
1118 | },
1119 | ].map((category) => {
1120 | return {
1121 | ...category,
1122 | iconComponent: Icons[category.icon],
1123 | prompts: category.prompts.map((prompt) => {
1124 | return {
1125 | ...prompt,
1126 | iconComponent: Icons[prompt.icon],
1127 | };
1128 | }),
1129 | };
1130 | });
1131 |
1132 | const allPrompts = baseCategories.flatMap((category) => category.prompts);
1133 |
1134 | const newCategory = {
1135 | name: "New",
1136 | slug: "/new",
1137 | // Show prompts that have been published for the past two weeks
1138 | prompts: allPrompts
1139 | .filter((prompt) => {
1140 | const twoWeeksAgo = new Date();
1141 | twoWeeksAgo.setDate(twoWeeksAgo.getDate() - 14);
1142 | return new Date(prompt.date) >= twoWeeksAgo;
1143 | })
1144 | .sort((a, b) => {
1145 | return new Date(b.date).getTime() - new Date(a.date).getTime();
1146 | }),
1147 | icon: "calendar" as const,
1148 | iconComponent: Icons["calendar"],
1149 | };
1150 |
1151 | export const categories: Category[] = [
1152 | ...(newCategory.prompts.length > 0 ? [newCategory] : []),
1153 | ...baseCategories,
1154 | ];
1155 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | const config = {
2 | reactStrictMode: true,
3 | swcMinify: true,
4 | };
5 |
6 | module.exports = config;
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "raycast-prompt-explorer",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@radix-ui/react-alert-dialog": "^1.0.4",
13 | "@radix-ui/react-collapsible": "^1.0.3",
14 | "@radix-ui/react-context-menu": "^2.1.5",
15 | "@radix-ui/react-dialog": "^1.0.4",
16 | "@radix-ui/react-dropdown-menu": "^2.0.5",
17 | "@radix-ui/react-scroll-area": "^1.0.4",
18 | "@radix-ui/react-toast": "^1.1.4",
19 | "@radix-ui/react-tooltip": "^1.0.6",
20 | "@raycast/icons": "^0.4.1",
21 | "@vercel/analytics": "^0.1.11",
22 | "@viselect/react": "^3.2.7",
23 | "autoprefixer": "^10.4.11",
24 | "copy-to-clipboard": "^3.3.3",
25 | "lodash.debounce": "^4.0.8",
26 | "nanoid": "^4.0.2",
27 | "next": "^13.4.4",
28 | "postcss": "^8.4.24",
29 | "postcss-nested": "^5.0.6",
30 | "react": "^18.2.0",
31 | "react-dom": "^18.2.0",
32 | "react-markdown": "^8.0.7"
33 | },
34 | "devDependencies": {
35 | "@types/lodash.debounce": "^4.0.9",
36 | "@types/node": "18.11.9",
37 | "eslint": "8.27.0",
38 | "eslint-config-next": "13.0.2"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/pages/[[...slug]].tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import NextLink from "next/link";
3 | import SelectionArea, { SelectionEvent } from "@viselect/react";
4 | import { useRouter } from "next/router";
5 | import copy from "copy-to-clipboard";
6 | import {
7 | Dialog,
8 | DialogContent,
9 | DialogDescription,
10 | DialogTitle,
11 | DialogTrigger,
12 | } from "../components/Dialog";
13 | import {
14 | DropdownMenu,
15 | DropdownMenuContent,
16 | DropdownMenuItem,
17 | DropdownMenuTrigger,
18 | DropdownMenuSeparator,
19 | } from "../components/DropdownMenu";
20 | import { Toast, ToastTitle } from "../components/Toast";
21 | import { ScrollArea } from "../components/ScrollArea";
22 | import { Button } from "../components/Button";
23 | import { ButtonGroup } from "../components/ButtonGroup";
24 | import * as Collapsible from "@radix-ui/react-collapsible";
25 | import { isTouchDevice } from "../utils/isTouchDevice";
26 |
27 | import { categories, Category, Model, Prompt } from "../data/prompts";
28 |
29 | import styles from "../styles/Home.module.css";
30 | import { Instructions } from "../components/Instructions";
31 | import { useSectionInView } from "../utils/useSectionInViewObserver";
32 | import { extractPrompts } from "../utils/extractPrompts";
33 | import CreativityIcon from "../components/CreativityIcon";
34 | import * as ContextMenu from "@radix-ui/react-context-menu";
35 | import {
36 | ChevronDownIcon,
37 | CopyClipboardIcon,
38 | DownloadIcon,
39 | LinkIcon,
40 | MinusCircleIcon,
41 | PlusCircleIcon,
42 | RaycastLogoNegIcon,
43 | StarsIcon,
44 | TrashIcon,
45 | } from "@raycast/icons";
46 | import {
47 | addToRaycast,
48 | copyData,
49 | downloadData,
50 | makeUrl,
51 | } from "../utils/actions";
52 |
53 | const promptModel: Record = {
54 | "openai-gpt-3.5-turbo-instruct": [
55 | "GPT-3.5 Instruct",
56 | "OpenAI GPT-3.5 Turbo Instruct",
57 | ],
58 | "openai-gpt-3.5-turbo": ["GPT-3.5 Turbo", "OpenAI GPT-3.5 Turbo"],
59 | "openai-gpt-4": ["GPT-4", "OpenAI GPT-4"],
60 | "openai-gpt-4-turbo": ["GPT-4 Turbo", "OpenAI GPT-4 Turbo"],
61 | "anthropic-claude-haiku": ["Claude Haiku", "Anthropic Claude Haiku"],
62 | "anthropic-claude-opus": ["Claude Opus", "Anthropic Claude Opus"],
63 | "anthropic-claude-sonnet": ["Claude Sonnet", "Anthropic Claude Sonnet"],
64 | "perplexity-sonar-medium-online": [
65 | "Sonar Medium",
66 | "Perplexity Sonar Medium Online",
67 | ],
68 | "perplexity-sonar-small-online": [
69 | "Sonar Small",
70 | "Perplexity Sonar Small Online",
71 | ],
72 | "llama2-70b": ["Llama2", "Llama2 70B"],
73 | "mixtral-8x7b": ["Mixtral", "Mixtral 8x7B"],
74 | "codellama-70b-instruct": ["CodeLlama Instruct", "CodeLlama 70B Instruct"],
75 | };
76 |
77 | export function getStaticPaths() {
78 | const paths = categories.map((category) => ({
79 | params: { slug: [category.slug.replace("/", "")] },
80 | }));
81 |
82 | return {
83 | paths: [
84 | ...paths,
85 | {
86 | params: { slug: [] },
87 | },
88 | ],
89 | fallback: false,
90 | };
91 | }
92 |
93 | export async function getStaticProps() {
94 | return {
95 | props: {},
96 | };
97 | }
98 |
99 | export default function Home({ onTouchReady }: { onTouchReady: () => void }) {
100 | const router = useRouter();
101 |
102 | const [selectedPrompts, setSelectedPrompts] = React.useState([]);
103 |
104 | const [showToast, setShowToast] = React.useState(false);
105 | const [toastMessage, setToastMessage] = React.useState("");
106 |
107 | const [actionsOpen, setActionsOpen] = React.useState(false);
108 | const [aboutOpen, setAboutOpen] = React.useState(false);
109 | const [isTouch, setIsTouch] = React.useState();
110 |
111 | const onStart = ({ event, selection }: SelectionEvent) => {
112 | if (!isTouch && !event?.ctrlKey && !event?.metaKey) {
113 | selection.clearSelection();
114 | setSelectedPrompts([]);
115 | }
116 | };
117 |
118 | const onMove = ({
119 | store: {
120 | changed: { added, removed },
121 | },
122 | }: SelectionEvent) => {
123 | const addedPrompts = extractPrompts(added, categories);
124 | const removedPrompts = extractPrompts(removed, categories);
125 |
126 | setSelectedPrompts((prevPrompts) => {
127 | const prompts = [...prevPrompts];
128 |
129 | addedPrompts.forEach((prompt) => {
130 | if (!prompt) {
131 | return;
132 | }
133 | if (prompts.find((p) => p.id === prompt.id)) {
134 | return;
135 | }
136 | prompts.push(prompt);
137 | });
138 |
139 | removedPrompts.forEach((prompt) => {
140 | return prompts.filter((s) => s?.id !== prompt?.id);
141 | });
142 |
143 | return prompts;
144 | });
145 | };
146 |
147 | const handleDownload = React.useCallback(() => {
148 | downloadData(selectedPrompts);
149 | }, [selectedPrompts]);
150 |
151 | const handleCopyData = React.useCallback(() => {
152 | copyData(selectedPrompts);
153 | setToastMessage("Copied to clipboard");
154 | setShowToast(true);
155 | }, [selectedPrompts]);
156 |
157 | const handleCopyUrl = React.useCallback(async () => {
158 | setToastMessage("Copying URL to clipboard...");
159 | setShowToast(true);
160 |
161 | const url = makeUrl(selectedPrompts);
162 | let urlToCopy = url;
163 | const encodedUrl = encodeURIComponent(urlToCopy);
164 | const response = await fetch(
165 | `https://ray.so/api/shorten-url?url=${encodedUrl}&ref=prompts`
166 | ).then((res) => res.json());
167 |
168 | if (response.link) {
169 | urlToCopy = response.link;
170 | }
171 |
172 | copy(urlToCopy);
173 | setShowToast(true);
174 | setToastMessage("Copied URL to clipboard!");
175 | }, [selectedPrompts]);
176 |
177 | const handleCopyText = React.useCallback((prompt: Prompt) => {
178 | copy(prompt.prompt);
179 | setShowToast(true);
180 | setToastMessage("Copied to clipboard");
181 | }, []);
182 |
183 | const handleAddToRaycast = React.useCallback(
184 | () => addToRaycast(router, selectedPrompts),
185 | [router, selectedPrompts]
186 | );
187 |
188 | React.useEffect(() => {
189 | setIsTouch(isTouchDevice());
190 | onTouchReady();
191 | }, [isTouch, setIsTouch, onTouchReady]);
192 |
193 | React.useEffect(() => {
194 | const down = (event: KeyboardEvent) => {
195 | const { key, keyCode, metaKey, shiftKey, altKey } = event;
196 |
197 | if (key === "k" && metaKey) {
198 | if (selectedPrompts.length === 0) return;
199 | setActionsOpen((prevOpen) => {
200 | return !prevOpen;
201 | });
202 | }
203 |
204 | if (key === "d" && metaKey) {
205 | if (selectedPrompts.length === 0) return;
206 | event.preventDefault();
207 | handleDownload();
208 | }
209 |
210 | if (key === "Enter" && metaKey) {
211 | if (selectedPrompts.length === 0) return;
212 | event.preventDefault();
213 | handleAddToRaycast();
214 | }
215 |
216 | // key === "c" doesn't work when using alt key, so we use keCode instead (67)
217 | if (keyCode === 67 && metaKey && altKey) {
218 | if (selectedPrompts.length === 0) return;
219 | event.preventDefault();
220 | handleCopyData();
221 | setActionsOpen(false);
222 | }
223 |
224 | if (key === "c" && metaKey && shiftKey) {
225 | event.preventDefault();
226 | handleCopyUrl();
227 | setActionsOpen(false);
228 | }
229 |
230 | if (key === "/" && metaKey) {
231 | event.preventDefault();
232 | setActionsOpen(false);
233 | setAboutOpen((prevOpen) => !prevOpen);
234 | }
235 |
236 | if (key === "a" && metaKey) {
237 | event.preventDefault();
238 | }
239 | };
240 |
241 | document.addEventListener("keydown", down);
242 | return () => document.removeEventListener("keydown", down);
243 | }, [
244 | setActionsOpen,
245 | setAboutOpen,
246 | selectedPrompts,
247 | handleCopyData,
248 | handleDownload,
249 | handleCopyUrl,
250 | handleAddToRaycast,
251 | ]);
252 |
253 | React.useEffect(() => {
254 | if (showToast) {
255 | setTimeout(() => {
256 | setShowToast(false);
257 | }, 2000);
258 | }
259 | }, [showToast]);
260 |
261 | return (
262 |