├── .gitignore ├── CHANGELOG.md ├── README.md ├── blueprints ├── flux-with-replicate.md └── supabase-drizzle-actions.md ├── codex ├── codex.md ├── learn.md └── split-codex.md ├── lib └── nuqs.md ├── plugins └── v0.md ├── rules ├── code-tutor.md └── mckay.md ├── session ├── end-session.md └── start-session.md ├── snippets ├── create-snippet.md ├── efc.md └── shadcn.md └── status └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## snippets@1.3.0 4 | 5 | Introducing Snippets. Snippets include code templates that AI can use to generate or refactor code. They help in writing shorter prompts for better results. 6 | 7 | - [create-snippet.md](snippets/create-snippet.md) 8 | 9 | ## rules@1.2.0 10 | 11 | - New rule [mckay.md](rules/mckay.md) by @mckaywrigley 12 | - New rule [code-tutor.md](rules/code-tutor.md) by @mckaywrigley 13 | 14 | ## codex@1.1.1 15 | 16 | - [learn.md](codex/learn.md): add exclusions and focus. Cursor captures many TS and ESLint errors that we should ignore. 17 | 18 | ## 1.1.0 19 | 20 | - New folder [session](session): 21 | - [start-session](session/start-session.md) 22 | - [end-session](session/end-session.md) 23 | - New folder [blueprints](blueprints): 24 | - [supabase-drizzle-actions](blueprints/supabase-drizzle-actions.md) by @mckaywrigley 25 | - [flux-with-replicate](blueprints/flux-with-replicate.md) by @mckaywrigley 26 | - New folder [plugins](plugins): 27 | - [v0](plugins/v0.md) by @mckaywrigley 28 | - New folder [lib](lib): 29 | - [nuqs](lib/nuqs.md) example for library usage 30 | 31 | ## codex@1.0.0 32 | 33 | - New folder [codex](codex): 34 | - [codex.md](codex/codex.md) 35 | - [learn.md](codex/learn.md) 36 | - [split-codex.md](codex/split-codex.md) 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # .ai 2 | 3 | This folder contains AI-assisted development tools for improving code quality and consistency. 4 | 5 | ## How to use? 6 | 7 | - Click on the "Use this template" button 8 | - Create a `.ai` folder in your repository 9 | - Move the content of this template into the `.ai` folder 10 | 11 | ## Codex 12 | 13 | ### Files 14 | 15 | - [codex.md](codex/codex.md): AI Codex - A repository of learnings and errors. 16 | - [learn.md](codex/learn.md): AI Learn - Protocol for updating the AI Codex. 17 | 18 | ### Usage 19 | 20 | 1. Review the Codex: [codex.md](codex/codex.md) (silent load, no output) 21 | 2. Update the Codex: [learn.md](codex/learn.md) 22 | 23 | ### Important Note 24 | 25 | [codex.md](codex/codex.md) should be added to the context of every chat: 26 | 27 | - For regular chats: Use the plus button at the top of the chat to add the file. 28 | - For Composers: Add the file to a Project Composer so all Composers created in that project will automatically have the file. 29 | 30 | ### Structure 31 | 32 | The [Codex](codex/codex.md) is divided into two main sections: 33 | 34 | 1. Errors: Mistakes made and how to prevent them. 35 | 2. Learnings: Insights gained and their applications. 36 | 37 | Each entry includes context, description, correction/application, and related entries. 38 | 39 | ## Snippets 40 | 41 | Snippets include code templates that AI can use to generate or refactor code. They help in writing shorter prompts for better results. 42 | 43 | - [create-snippet.md](snippets/create-snippet.md): Prompt for creating new snippets 44 | 45 | ## Session 46 | 47 | - [start-session.md](session/start-session.md): Initiates a new AI session 48 | - [end-session.md](session/end-session.md): Concludes the current AI session 49 | 50 | Session files create a "memory layer" for the AI across multiple interactions, enabling contextual awareness and adaptive assistance. 51 | 52 | Key benefits: 53 | 54 | - Maintains project context between sessions 55 | - Reduces repetition of project details 56 | - Provides consistent guidance aligned with project direction 57 | 58 | Usage: 59 | 60 | 1. End a session: Use [@end-session](session/end-session.md) command 61 | 2. Start a new session: Use [@start-session](session/start-session.md) command 62 | 63 | The AI will generate and read status files in [status](status) to maintain project continuity. 64 | 65 | ## Blueprints 66 | 67 | Blueprints are comprehensive guides for implementing specific technical architectures or project setups. They provide step-by-step instructions for installing, configuring, and integrating various technologies to create a functional foundation for your project. 68 | 69 | - [supabase-drizzle-actions.md](blueprints/supabase-drizzle-actions.md): Backend architecture with Supabase, Drizzle ORM, and Server Actions 70 | - [flux-with-replicate.md](blueprints/flux-with-replicate.md): Image generation using Flux and Replicate 71 | 72 | ## Libraries 73 | 74 | - [lib](lib): Contains documentation examples for library usage 75 | 76 | ## Plugins 77 | 78 | ### v0 79 | 80 | - [v0.dev](https://v0.dev/) is a tool for generating React components from screenshots and chat. Currently, they don't have a Cursor plugin, so you can use [v0](v0/v0.md) bridging prompt. 81 | - [v0.md](v0/v0.md): Guide for using v0.dev to generate component ideas and prompts 82 | 83 | ## Rules of AI 84 | 85 | [Rules](rules) contains rules for default AI behavior and interaction. These rules are meant to be added to the global "Rules of AI" setting. 86 | 87 | ## Contributing 88 | 89 | This is an open-source template. Contributions are welcome! Please add a changelog entry with your contribution. 90 | 91 | ## Note 92 | 93 | This system is designed for AI consumption. Entries should prioritize precision and relevance over human readability 94 | -------------------------------------------------------------------------------- /blueprints/flux-with-replicate.md: -------------------------------------------------------------------------------- 1 | # Flux with Replicate Documentation 2 | 3 | Use this guide to setup generating images with Flux and Replicate. 4 | 5 | Write the complete code for every step. Do not get lazy. Write everything that is needed. 6 | 7 | Your goal is to completely finish the feature. 8 | 9 | ## Helpful Links 10 | 11 | - [Replicate](https://replicate.com) 12 | - [Flux Schnell](https://replicate.com/black-forest-labs/flux-schnell?input=nodejs) 13 | 14 | ## Required Environment Variables 15 | 16 | Make sure the user has the following environment variables set: 17 | 18 | - REPLICATE_API_TOKEN= 19 | 20 | ## Install Replicate 21 | 22 | Make sure the user has the Replicate package installed: 23 | 24 | ```bash 25 | npm install replicate 26 | ``` 27 | 28 | ## Setup Steps 29 | 30 | ### Create a Replicate Client 31 | 32 | This file should go in `/lib/replicate.ts` 33 | 34 | ```ts 35 | import Replicate from "replicate"; 36 | 37 | const replicate = new Replicate({ 38 | auth: process.env.REPLICATE_API_TOKEN, 39 | }); 40 | ``` 41 | 42 | ### Create a Server Action 43 | 44 | This file should go in `/actions/replicate-actions.ts` 45 | 46 | ```ts 47 | "use server"; 48 | 49 | import replicate from "@/lib/replicate"; 50 | 51 | export async function generateFluxImage(prompt: string) { 52 | const input = { 53 | prompt: prompt, 54 | num_outputs: 1, 55 | aspect_ratio: "1:1", 56 | output_format: "webp", 57 | output_quality: 80 58 | }; 59 | 60 | const output = await http://replicate.run("black-forest-labs/flux-schnell", { input }); 61 | return output; 62 | } 63 | ``` 64 | 65 | ### Build the Frontend 66 | 67 | This file should go in `/app/flux/page.tsx`. 68 | 69 | - Create a form that takes a prompt 70 | - Create a button that calls the server action 71 | - Have a nice ui for when the image is blank or loading 72 | - Display the image that is returned 73 | - Have a button to generate a new image 74 | - Have a button to download the image 75 | -------------------------------------------------------------------------------- /blueprints/supabase-drizzle-actions.md: -------------------------------------------------------------------------------- 1 | # Backend Setup Instructions 2 | 3 | Use this guide to setup the backend for this project. 4 | 5 | It uses Supabase, Drizzle ORM, and Server Actions. 6 | 7 | Write the complete code for every step. Do not get lazy. Write everything that is needed. 8 | 9 | Your goal is to completely finish the backend setup. 10 | 11 | ## Helpful Links 12 | 13 | If the user gets stuck, refer them to the following links: 14 | 15 | - [Supabase Docs](https://supabase.com) 16 | - [Drizzle Docs](https://orm.drizzle.team/docs/overview) 17 | - [Drizzle with Supabase Quickstart](https://orm.drizzle.team/learn/tutorials/drizzle-with-supabase) 18 | 19 | ## Install Libraries 20 | 21 | Make sure the user knows to install the following libraries: 22 | 23 | ```bash 24 | npm i drizzle-orm dotenv postgres 25 | npm i -D drizzle-kit 26 | ``` 27 | 28 | ## Setup Steps 29 | 30 | - [ ] Create a `/db` folder in the root of the project 31 | 32 | - [ ] Create a `/types` folder in the root of the project 33 | 34 | - [ ] Add a `drizzle.config.ts` file to the root of the project with the following code: 35 | 36 | ```ts 37 | import { config } from "dotenv"; 38 | import { defineConfig } from "drizzle-kit"; 39 | 40 | config({ path: ".env.local" }); 41 | 42 | export default defineConfig({ 43 | schema: "./db/schema/index.ts", 44 | out: "./db/migrations", 45 | dialect: "postgresql", 46 | dbCredentials: { 47 | url: process.env.DATABASE_URL!, 48 | }, 49 | }); 50 | ``` 51 | 52 | - [ ] Add a file called `db.ts` to the `/db` folder with the following code: 53 | 54 | ```ts 55 | import { config } from "dotenv"; 56 | import { drizzle } from "drizzle-orm/postgres-js"; 57 | import postgres from "postgres"; 58 | import { exampleTable } from "./schema"; 59 | 60 | config({ path: ".env.local" }); 61 | 62 | const schema = { 63 | exampleTable, 64 | }; 65 | 66 | const client = postgres(process.env.DATABASE_URL!); 67 | 68 | export const db = drizzle(client, { schema }); 69 | ``` 70 | 71 | - [ ] Create 2 folders in the `/db` folder: 72 | 73 | - `/schema` 74 | - Add a file called `index.ts` to the `/schema` folder 75 | - `/queries` 76 | 77 | - [ ] Create an example table in the `/schema` folder called `example-schema.ts` with the following code: 78 | 79 | ```ts 80 | import { integer, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core"; 81 | 82 | export const exampleTable = pgTable("example", { 83 | id: uuid("id").defaultRandom().primaryKey(), 84 | name: text("name").notNull(), 85 | age: integer("age").notNull(), 86 | email: text("email").notNull(), 87 | createdAt: timestamp("created_at").defaultNow().notNull(), 88 | updatedAt: timestamp("updated_at") 89 | .notNull() 90 | .defaultNow() 91 | .$onUpdate(() => new Date()), 92 | }); 93 | 94 | export type InsertExample = typeof exampleTable.$inferInsert; 95 | export type SelectExample = typeof exampleTable.$inferSelect; 96 | ``` 97 | 98 | - [ ] Export the example table in the `/schema/index.ts` file like so: 99 | 100 | ```ts 101 | export * from "./example-schema"; 102 | ``` 103 | 104 | - [ ] Create a new file called `example-queries.ts` in the `/queries` folder with the following code: 105 | 106 | ```ts 107 | "use server"; 108 | 109 | import { eq } from "drizzle-orm"; 110 | import { db } from "../db"; 111 | import { InsertExample, SelectExample } from "../schema/example-schema"; 112 | import { exampleTable } from "./../schema/example-schema"; 113 | 114 | export const createExample = async (data: InsertExample) => { 115 | try { 116 | const [newExample] = await db.insert(exampleTable).values(data).returning(); 117 | return newExample; 118 | } catch (error) { 119 | console.error("Error creating example:", error); 120 | throw new Error("Failed to create example"); 121 | } 122 | }; 123 | 124 | export const getExampleById = async (id: string) => { 125 | try { 126 | const example = await db.query.exampleTable.findFirst({ 127 | where: eq(http://exampleTable.id, id) 128 | }); 129 | if (!example) { 130 | throw new Error("Example not found"); 131 | } 132 | return example; 133 | } catch (error) { 134 | console.error("Error getting example by ID:", error); 135 | throw new Error("Failed to get example"); 136 | } 137 | }; 138 | 139 | export const getAllExamples = async (): Promise => { 140 | return db.query.exampleTable.findMany(); 141 | }; 142 | 143 | export const updateExample = async (id: string, data: Partial) => { 144 | try { 145 | const [updatedExample] = await db.update(exampleTable).set(data).where(eq(http://exampleTable.id, id)).returning(); 146 | return updatedExample; 147 | } catch (error) { 148 | console.error("Error updating example:", error); 149 | throw new Error("Failed to update example"); 150 | } 151 | }; 152 | 153 | export const deleteExample = async (id: string) => { 154 | try { 155 | await db.delete(exampleTable).where(eq(http://exampleTable.id, id)); 156 | } catch (error) { 157 | console.error("Error deleting example:", error); 158 | throw new Error("Failed to delete example"); 159 | } 160 | }; 161 | ``` 162 | 163 | - [ ] In `package.json`, add the following scripts: 164 | 165 | ```json 166 | "scripts": { 167 | "db:generate": "npx drizzle-kit generate", 168 | "db:migrate": "npx drizzle-kit migrate" 169 | } 170 | ``` 171 | 172 | - [ ] Run the following command to generate the tables: 173 | 174 | ```bash 175 | npm run db:generate 176 | ``` 177 | 178 | - [ ] Run the following command to migrate the tables: 179 | 180 | ```bash 181 | npm run db:migrate 182 | ``` 183 | 184 | - [ ] Create a folder called `/actions` in the root of the project for server actions 185 | 186 | - [ ] Create folder called `/types` in the root of the project for shared types 187 | 188 | - [ ] Create a file called `action-types.ts` in the `/types/actions` folder for server action types with the following code: 189 | 190 | - [ ] Create file called `/types/index.ts` and export all the types from the `/types` folder like so: 191 | 192 | ```ts 193 | export * from "./action-types"; 194 | ``` 195 | 196 | - [ ] Create a file called `example-actions.ts` in the `/actions` folder for the example table's actions: 197 | 198 | ```ts 199 | "use server"; 200 | 201 | import { 202 | createExample, 203 | deleteExample, 204 | getAllExamples, 205 | getExampleById, 206 | updateExample, 207 | } from "@/db/queries/example-queries"; 208 | import { InsertExample } from "@/db/schema/example-schema"; 209 | import { ActionState } from "@/types"; 210 | import { revalidatePath } from "next/cache"; 211 | 212 | export async function createExampleAction( 213 | data: InsertExample 214 | ): Promise { 215 | try { 216 | const newExample = await createExample(data); 217 | revalidatePath("/examples"); 218 | return { 219 | status: "success", 220 | message: "Example created successfully", 221 | data: newExample, 222 | }; 223 | } catch (error) { 224 | return { status: "error", message: "Failed to create example" }; 225 | } 226 | } 227 | 228 | export async function getExampleByIdAction(id: string): Promise { 229 | try { 230 | const example = await getExampleById(id); 231 | return { 232 | status: "success", 233 | message: "Example retrieved successfully", 234 | data: example, 235 | }; 236 | } catch (error) { 237 | return { status: "error", message: "Failed to get example" }; 238 | } 239 | } 240 | 241 | export async function getAllExamplesAction(): Promise { 242 | try { 243 | const examples = await getAllExamples(); 244 | return { 245 | status: "success", 246 | message: "Examples retrieved successfully", 247 | data: examples, 248 | }; 249 | } catch (error) { 250 | return { status: "error", message: "Failed to get examples" }; 251 | } 252 | } 253 | 254 | export async function updateExampleAction( 255 | id: string, 256 | data: Partial 257 | ): Promise { 258 | try { 259 | const updatedExample = await updateExample(id, data); 260 | revalidatePath("/examples"); 261 | return { 262 | status: "success", 263 | message: "Example updated successfully", 264 | data: updatedExample, 265 | }; 266 | } catch (error) { 267 | return { status: "error", message: "Failed to update example" }; 268 | } 269 | } 270 | 271 | export async function deleteExampleAction(id: string): Promise { 272 | try { 273 | await deleteExample(id); 274 | revalidatePath("/examples"); 275 | return { status: "success", message: "Example deleted successfully" }; 276 | } catch (error) { 277 | return { status: "error", message: "Failed to delete example" }; 278 | } 279 | } 280 | ``` 281 | 282 | ```ts 283 | export type ActionState = { 284 | status: "success" | "error"; 285 | message: string; 286 | data?: any; 287 | }; 288 | ``` 289 | 290 | - [ ] Implement the server actions in the `/app/page.tsx` file to allow for manual testing. 291 | 292 | - [ ] The backend is now setup. 293 | -------------------------------------------------------------------------------- /codex/codex.md: -------------------------------------------------------------------------------- 1 | # AI Codex 2 | 3 | ## Usage 4 | 5 | - Review: @codex.md (silent load, no output) 6 | - Update: @learn.md 7 | - File paths: Always use absolute paths from project root 8 | 9 | ## Errors 10 | 11 | E000: 12 | 13 | - Context: [Relevant project area or file] 14 | - Error: [Precise description] 15 | - Correction: [Exact fix] 16 | - Prevention: [Specific strategy] 17 | - Related: [IDs of related errors/learnings] 18 | 19 | E001: 20 | 21 | - Context: File path suggestions 22 | - Error: Relative path used instead of absolute 23 | - Correction: Use absolute paths from project root 24 | - Prevention: Always prefix paths with '/' 25 | - Related: None 26 | 27 | E002: 28 | 29 | - Context: '/src/index.ts' 30 | - Error: Suggested CommonJS import syntax 31 | - Correction: Use ES module import syntax 32 | - Prevention: Verify `"type": "module"` in '/package.json' or '.mjs' extension 33 | - Related: L002 34 | 35 | ## Learnings 36 | 37 | L007: 38 | 39 | - Context: /apps/www/src/pro/components/user-dropdown.tsx 40 | - Insight: UserDropdown component uses useLogout hook and handles loading state 41 | - Application: Implement logout functionality with loading indicator in user-related components 42 | - Impact: Improved user experience with visual feedback during logout process 43 | - Related: L008, L005 44 | 45 | L008: 46 | 47 | - Context: /apps/www/src/pro/components/user-dropdown.tsx 48 | - Insight: Component uses 'use client' directive for client-side rendering 49 | - Application: Use 'use client' directive for components that require client-side interactivity 50 | - Impact: Proper integration with Next.js 13+ server components architecture 51 | - Related: L007 52 | 53 | L000: 54 | 55 | - Context: [Relevant project area or file] 56 | - Insight: [Concise description] 57 | - Application: [How to apply this knowledge] 58 | - Impact: [Potential effects on project] 59 | - Related: [IDs of related errors/learnings] 60 | 61 | L001: 62 | 63 | - Context: @codex.md usage 64 | - Insight: @codex.md is for context, not for direct modification 65 | - Application: Use @codex.md for silent loading and context only; execute subsequent commands separately 66 | - Impact: Improved accuracy in responding to user intentions 67 | - Related: None 68 | 69 | L002: 70 | 71 | - Context: Project architecture 72 | - Insight: Repository pattern for data access 73 | - Application: '/src' is root, '/src/auth' for authentication, '/src/database' for data access 74 | - Impact: Organized code structure, separation of concerns 75 | - Related: None 76 | -------------------------------------------------------------------------------- /codex/learn.md: -------------------------------------------------------------------------------- 1 | # AI Insight Acquisition Protocol 2 | 3 | Invocation: @learn.md 4 | 5 | Process: 6 | 7 | 1. Analyze current session for error and learning indicators 8 | 2. Extract contextual information 9 | 3. Format new entries 10 | 4. Edit `.ai/codex/codex.md` (Append to relevant section) 11 | 5. Report updates 12 | 13 | Error identification: 14 | 15 | - Correction phrases: "I apologize", "That was incorrect", "Let me correct" 16 | - Misunderstandings: Clarifications requested by user 17 | - Inconsistencies: Contradictions in AI responses 18 | 19 | Learning identification: 20 | 21 | - New information phrases: "I see", "I understand", "It appears that" 22 | - Project updates: Changes in structure, dependencies, or requirements 23 | - User preferences: Specific requests or feedback on AI's approach 24 | 25 | Entry format: 26 | 27 | - Context: Specific file, function, or project area 28 | - Error/Insight: Concise description 29 | - Correction/Application: Precise fix or usage 30 | - Prevention/Impact: Strategy to avoid future errors or potential effects 31 | - Related: IDs of connected entries 32 | 33 | Absolute path usage: Enforce '/path/from/root' format for all file references 34 | 35 | 1. CRITICAL: Edit `.ai/codex/codex.md` 36 | 37 | - Append new entries to the relevant section (Errors or Learnings) 38 | - Maintain descending order (newest first) 39 | - Ensure unique, incremental IDs 40 | - Cross-reference related entries 41 | 42 | Exclusions: 43 | 44 | - CI/CD configuration errors 45 | - Linting and code style issues (e.g., ESLint, Prettier) 46 | - TypeScript configuration problems (tsconfig.json) 47 | - Build tool configuration (e.g., webpack, Vite) 48 | - Environment setup issues (e.g., .env files) 49 | 50 | Focus on: 51 | 52 | - Functional errors in application code 53 | - Architectural and design pattern insights 54 | - State management and data flow learnings 55 | - Performance optimizations 56 | - User experience improvements 57 | - API integration and data handling 58 | 59 | CRITICAL: This process is for AI optimization. Prioritize precision and relevance over human readability. Always edit `.ai/codex/codex.md` directly. 60 | -------------------------------------------------------------------------------- /codex/split-codex.md: -------------------------------------------------------------------------------- 1 | # AI Codex Splitting Protocol 2 | 3 | Invocation: @split-codex.md 4 | 5 | ## Purpose 6 | 7 | This protocol is used to intelligently split the AI Codex when it becomes too long, grouping related Errors (E) and Learnings (L) into separate codex pages. 8 | 9 | ## Process 10 | 11 | 1. Analyze the current @codex.md file 12 | 2. Identify common themes or categories among entries 13 | 3. Group related E and L entries 14 | 4. Create new codex pages for each group 15 | 5. Update the main @codex.md with links to new pages 16 | 6. Report the new structure 17 | 18 | ## Grouping Criteria 19 | 20 | - Project area (e.g., frontend, backend, database) 21 | - Technology or framework (e.g., React, Node.js, Prisma) 22 | - Concept (e.g., authentication, state management, testing) 23 | - File type or location (e.g., configuration files, utility functions) 24 | 25 | ## File Structure 26 | 27 | 1. Main codex remains at: .ai/codex/codex.md 28 | 2. New pages: .ai/codex/[category]-codex.md 29 | 30 | ## Update Process 31 | 32 | 1. Move relevant entries to new category-specific files 33 | 2. In the main codex (.ai/codex/codex.md), replace moved entries with links to new files 34 | 3. Ensure cross-references are updated across all files 35 | 36 | ## Naming Convention 37 | 38 | Use kebab-case for new codex file names, e.g.: 39 | 40 | - frontend-codex.md 41 | - database-operations-codex.md 42 | - authentication-codex.md 43 | 44 | ## Reporting 45 | 46 | After splitting, provide a summary of: 47 | 48 | 1. Number of new codex pages created 49 | 2. Categories identified 50 | 3. Entry distribution across new pages 51 | 52 | IMPORTANT: Maintain the original entry IDs (E001, L001, etc.) in the new files to preserve existing references. 53 | -------------------------------------------------------------------------------- /lib/nuqs.md: -------------------------------------------------------------------------------- 1 | # Using nuqs for URL Query State Management 2 | 3 | `nuqs` is used for managing URL query state in Next.js applications. Follow these guidelines when working with it: 4 | 5 | 1. Import necessary functions from `nuqs`: 6 | 7 | ```typescript 8 | import { parseAsBoolean, parseAsStringEnum, useQueryState } from 'nuqs'; 9 | ``` 10 | 11 | 2. Create a custom hook for each query parameter: 12 | 13 | ```typescript 14 | export const useMyParameterState = () => { 15 | return useQueryState( 16 | 'parameterName', 17 | parseAsStringEnum(['option1', 'option2']) 18 | .withDefault('option1') 19 | .withOptions({ history: 'push' }) 20 | ); 21 | }; 22 | ``` 23 | 24 | 3. Use history push if you think the user will want to navigate back to the previous state: 25 | 26 | ```typescript 27 | export const useBooleanState = () => { 28 | return useQueryState( 29 | 'boolParam', 30 | parseAsBoolean.withDefault(false).withOptions({ 31 | history: 'push', 32 | }) 33 | ); 34 | }; 35 | ``` 36 | 37 | 4. Use the custom hooks in your components: 38 | 39 | ```typescript 40 | const [value, setValue] = useMyParameterState(); 41 | ``` 42 | 43 | 5. Update the URL query when changing values: 44 | 45 | ```typescript 46 | void setValue('newValue'); 47 | ``` 48 | 49 | 6. Use `clearOnDefault` option to remove the parameter from the URL when it's set to its default value: 50 | 51 | ```typescript 52 | export const useConfigurationItemsState = () => { 53 | return useQueryState( 54 | 'configItems', 55 | parseAsJson>().withDefault({}).withOptions({ 56 | clearOnDefault: true, 57 | history: 'push', 58 | }) 59 | ); 60 | }; 61 | ``` 62 | 63 | This ensures that empty or default values are not included in the URL search params, keeping the URL clean and only including relevant information. 64 | 65 | Remember to define your query state hooks in a central location (e.g., `useQueryState.ts`) for easy reuse across your application. 66 | 67 | Reference: `apps/web/src/lib/navigation/useQueryState.ts` 68 | -------------------------------------------------------------------------------- /plugins/v0.md: -------------------------------------------------------------------------------- 1 | - think carefully about the component 2 | - generate a prompt 3 | - then with the prompt create a clickable link: [component name](https://v0.dev/chat?q={prompt}) 4 | - make sure prompt is url encoded 5 | -------------------------------------------------------------------------------- /rules/code-tutor.md: -------------------------------------------------------------------------------- 1 | You are an AI coding instructor designed to assist and guide me as I learn to code. Your primary goal is to help me learn programming concepts, best practices, and problem-solving skills while writing code. Always assume I'm a beginner with limited programming knowledge. 2 | 3 | Follow these guidelines in all interactions: 4 | 1. Explain concepts thoroughly but in simple terms, avoiding jargon when possible. 5 | 2. When introducing new terms, provide clear definitions and examples. 6 | 3. Break down complex problems into smaller, manageable steps. 7 | 4. Encourage good coding practices and explain why they are important. 8 | 5. Provide examples and analogies to illustrate programming concepts. 9 | 6. Be patient and supportive, understanding that learning to code can be challenging. 10 | 7. Offer praise for correct implementations and gentle corrections for mistakes. 11 | 8. When correcting errors, explain why the error occurred and how to fix it. 12 | 9. Suggest resources for further learning when appropriate. 13 | 10. Encourage me to ask questions and seek clarification. 14 | 11. Foster problem-solving skills by guiding me to find solutions rather than always providing direct answers. 15 | 12. Adapt your teaching style to my pace and learning preferences. 16 | 13. Provide code snippets to illustrate concepts, but always explain the code line by line. 17 | 14. Use comments throughout the code to help document what is happening 18 | 19 | Address the my questions thoroughly, keeping in mind the guidelines above. If the question is unclear or lacks context, ask me for clarification. 20 | 21 | Review the code and provide feedback. If there are errors or areas for improvement, explain them clearly and suggest corrections. If the code is correct, offer praise and explain why it's a good implementation. 22 | 23 | Structure your responses as follows: 24 | 1. Format your response as markdown 25 | 2. Answer my question 26 | 3. Code review and feedback 27 | 4. Suggestions for further learning or practice 28 | 29 | Remember, your goal is not just to help me write correct code, but to help me understand the underlying principles and develop my programming skills. Always strive to be clear, patient, and encouraging in your responses. 30 | -------------------------------------------------------------------------------- /rules/mckay.md: -------------------------------------------------------------------------------- 1 | DO NOT GIVE ME HIGH LEVEL STUFF, IF I ASK FOR FIX OR EXPLANATION, I WANT ACTUAL CODE OR EXPLANATION!!! I DON'T WANT "Here's how you can blablabla" 2 | 3 | - Be casual unless otherwise specified 4 | - Be terse 5 | - Suggest solutions that I didn’t think about—anticipate my needs 6 | - Treat me as an expert 7 | - Be accurate and thorough 8 | - Give the answer immediately. Provide detailed explanations and restate my query in your own words if necessary after giving the answer 9 | - Value good arguments over authorities, the source is irrelevant 10 | - Consider new technologies and contrarian ideas, not just the conventional wisdom 11 | - You may use high levels of speculation or prediction, just flag it for me 12 | - No moral lectures 13 | - Discuss safety only when it's crucial and non-obvious 14 | - If your content policy is an issue, provide the closest acceptable response and explain the content policy issue afterward 15 | - Cite sources whenever possible at the end, not inline 16 | - No need to mention your knowledge cutoff 17 | - No need to disclose you're an AI 18 | - Please respect my prettier preferences when you provide code. 19 | - Split into multiple responses if one response isn't enough to answer the question. 20 | If I ask for adjustments to code I have provided you, do not repeat all of my code unnecessarily. Instead try to keep the answer brief by giving just a couple lines before/after any changes you make. Multiple code blocks are ok. -------------------------------------------------------------------------------- /session/end-session.md: -------------------------------------------------------------------------------- 1 | # End Session Instructions 2 | 3 | 1. Create a new file: `.ai/status/YYYY-MM-DD.md` 4 | 5 | 2. Structure the update with sections: 6 | 7 | - Development Steps 8 | - Key Decisions 9 | - Next Steps 10 | 11 | 3. For each section: 12 | 13 | - Use bullet points 14 | - Be specific and use technical terms 15 | - Keep content concise 16 | 17 | 4. Development Steps: 18 | 19 | - List modified files in dependency order 20 | - Number each step 21 | - Briefly describe changes and purpose for each file 22 | - Use past tense 23 | 24 | 5. Key Decisions: 25 | 26 | - List important decisions, their reasoning, and trade-offs 27 | - Use past tense 28 | 29 | 6. Next Steps: 30 | 31 | - List 3-5 prioritized tasks/features to work on next 32 | - Specify affected components/code areas 33 | - Highlight blockers or challenges 34 | - Use future tense 35 | - We don't care about performance and optimization for now. We need to get the core functionality working for MVP. 36 | 37 | 7. For code blocks, prepend triple quotes with a space 38 | 39 | 8. End with a brief summary of overall progress and next session's focus 40 | 41 | Example: 42 | 43 | # Session Update: 2023-04-15 44 | 45 | ## Development Steps 46 | 47 | 1. `app/styles/globals.css`: Updated color scheme and typography 48 | - Defined new color variables and font styles 49 | 2. `app/utils/api.ts`: Created new API utility functions 50 | - Implemented functions for fetching user data and posts 51 | 3. `app/components/Header.tsx`: Added responsive navigation menu 52 | - Created mobile-friendly dropdown menu using new styles 53 | 4. `app/pages/index.tsx`: Implemented hero section with CTA 54 | - Utilized new API functions to display dynamic content 55 | 56 | ## Key Decisions 57 | 58 | - Chose Tailwind CSS for styling to improve development speed 59 | - Implemented server-side rendering for better SEO performance 60 | 61 | ## Next Steps 62 | 63 | 1. Implement user authentication system 64 | 2. Create dashboard page for logged-in users 65 | 3. Optimize image loading and caching 66 | 67 | Progress: Completed main layout and homepage. Next session will focus on user authentication and dashboard implementation. 68 | -------------------------------------------------------------------------------- /session/start-session.md: -------------------------------------------------------------------------------- 1 | # Start Session Instructions 2 | 3 | 1. Locate and analyze the most recent status update file in the `.ai/status/` directory (format: `YYYY-MM-DD.md`). 4 | 5 | 2. Understand the current project state, recent decisions, and prepare to assist with outlined next steps. 6 | 7 | 3. If no specific task is requested: 8 | 9 | - List all next steps from the latest session. 10 | - Suggest which step to take first, providing a brief rationale. 11 | - Be ready to address any challenges or blockers mentioned. 12 | 13 | 4. Provide context-aware assistance throughout the session, referencing the status update when discussing project status or next steps. 14 | 15 | 5. Be prepared to help implement tasks and features listed in the Next Steps section, recalling relevant details for specific components or code areas. 16 | 17 | 6. At the end of the session, create a new status update using the guidelines in `end-session.md`. 18 | -------------------------------------------------------------------------------- /snippets/create-snippet.md: -------------------------------------------------------------------------------- 1 | Title: Create Snippet Prompt 2 | Description: Generates a snippet template based on provided example code. Template contains instructions and example code. Provide more examples for coverage if needed. Don't include obvious steps you already know like imports. 3 | Body: 4 | 5 | ### Instructions 6 | 7 | Title: ${1:Create ${2:Component}} 8 | Description: Generates a template for ${3:a ${2}} 9 | Body: 10 | 11 | ${5:$TM_SELECTED_TEXT} 12 | 13 | ### Example 14 | 15 | Title: ${1} 16 | Description: ${3} 17 | Body: 18 | 19 | ${5} 20 | -------------------------------------------------------------------------------- /snippets/efc.md: -------------------------------------------------------------------------------- 1 | Title: Extract File Component 2 | Description: Extracts into its own (camel-case) file React component with destructured props and inline type. Avoid prop drilling, especially using context hooks (including react-query). 3 | Body: 4 | 5 | export function ${1:ComponentName}({ ${2:prop}, ...props }: { ${2}: ${3:type} }) { 6 | return ( 7 | $0 8 | ) 9 | } 10 | 11 | ### Example 12 | 13 | Title: Extract File Component 14 | Description: Extracts into its own (camel-case) file React component with destructured props and inline type. Avoid prop drilling, especially using context hooks (including react-query). 15 | Body: 16 | 17 | export function ${1:ComponentName}({ ${2:prop}, ...props }: { ${2}: ${3:type} }) { 18 | return ( 19 | $0 20 | ) 21 | } -------------------------------------------------------------------------------- /snippets/shadcn.md: -------------------------------------------------------------------------------- 1 | Title: Create React Component with Variants 2 | Description: Generates a template for a React component with customizable variants using class-variance-authority 3 | Body: 4 | 5 | import * as React from "react" 6 | import { Slot } from "@radix-ui/react-slot" 7 | import { cva, type VariantProps } from "class-variance-authority" 8 | 9 | import { cn } from "@/lib/utils" 10 | 11 | const ${1:component}Variants = cva( 12 | "${2:base classes}", 13 | { 14 | variants: { 15 | ${3:variantName}: { 16 | ${4:variantValue}: "${5:classes}", 17 | }, 18 | }, 19 | defaultVariants: { 20 | ${3}: "${4}", 21 | }, 22 | } 23 | ) 24 | 25 | export interface ${6:ComponentName}Props 26 | extends React.${7:HTMLAttributes}, 27 | VariantProps { 28 | asChild?: boolean 29 | } 30 | 31 | const ${6} = React.forwardRef( 32 | ({ className, ${3}, asChild = false, ...props }, ref) => { 33 | const Comp = asChild ? Slot : "${9:element}" 34 | return ( 35 | 40 | ) 41 | } 42 | ) 43 | ${6}.displayName = "${6}" 44 | 45 | export { ${6}, ${1}Variants } 46 | 47 | ### Example 48 | 49 | Title: Create React Component with Variants 50 | Description: Generates a template for a React component with customizable variants using class-variance-authority 51 | Body: 52 | 53 | import * as React from "react" 54 | import { Slot } from "@radix-ui/react-slot" 55 | import { cva, type VariantProps } from "class-variance-authority" 56 | 57 | import { cn } from "@/lib/utils" 58 | 59 | const buttonVariants = cva( 60 | "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", 61 | { 62 | variants: { 63 | variant: { 64 | default: "bg-primary text-primary-foreground hover:bg-primary/90", 65 | destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", 66 | outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground", 67 | secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80", 68 | ghost: "hover:bg-accent hover:text-accent-foreground", 69 | link: "text-primary underline-offset-4 hover:underline", 70 | }, 71 | size: { 72 | default: "h-10 px-4 py-2", 73 | sm: "h-9 rounded-md px-3", 74 | lg: "h-11 rounded-md px-8", 75 | icon: "h-10 w-10", 76 | }, 77 | }, 78 | defaultVariants: { 79 | variant: "default", 80 | size: "default", 81 | }, 82 | } 83 | ) 84 | 85 | export interface ButtonProps 86 | extends React.ButtonHTMLAttributes, 87 | VariantProps { 88 | asChild?: boolean 89 | } 90 | 91 | const Button = React.forwardRef( 92 | ({ className, variant, size, asChild = false, ...props }, ref) => { 93 | const Comp = asChild ? Slot : "button" 94 | return ( 95 | 100 | ) 101 | } 102 | ) 103 | Button.displayName = "Button" 104 | 105 | export { Button, buttonVariants } -------------------------------------------------------------------------------- /status/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udecode/dotai/27a53aff812d5f7166ea00bd273e1796b9dc8ef1/status/.gitkeep --------------------------------------------------------------------------------