ref: cursorrules/convex

title: Convex

summary: Cursor rules for Convex development with best practices.

credit: "Convex" by PatrickJS (https://incantory.ai/cursorrules/convex), licensed CC0-1.0

title: Convex

content:
# Convex guidelines
## Function guidelines
### New function syntax
- ALWAYS use the new function syntax for Convex functions. For example:
      ```typescript
      import { query } from "./_generated/server";
      import { v } from "convex/values";
      export const f = query({
          args: {},
          returns: v.null(),
          handler: async (ctx, args) => {
          // Function body
          },
      });
      ```

### Http endpoint syntax
- HTTP endpoints are defined in `convex/http.ts` and require an `httpAction` decorator. For example:
      ```typescript
      import { httpRouter } from "convex/server";
      import { httpAction } from "./_generated/server";
      const http = httpRouter();
      http.route({
          path: "/echo",
          method: "POST",
          handler: httpAction(async (ctx, req) => {
          const body = await req.bytes();
          return new Response(body, { status: 200 });
          }),
      });
      ```
- HTTP endpoints are always registered at the exact path you specify in the `path` field. For example, if you specify `/api/someRoute`, the endpoint will be registered at `/api/someRoute`.

### Validators
- Below is an example of an array validator:
                            ```typescript
                            import { mutation } from "./_generated/server";
                            import { v } from "convex/values";

                            export default mutation({
                            args: {
                                simpleArray: v.array(v.union(v.string(), v.number())),
                            },
                            handler: async (ctx, args) => {
                                //...
                            },
                            });
                            ```
- Below is an example of a schema with validators that codify a discriminated union type:
                            ```typescript
                            import { defineSchema, defineTable } from "convex/server";
                            import { v } from "convex/values";

                            export default defineSchema({
                                results: defineTable(
                                    v.union(
                                        v.object({
                                            kind: v.literal("error"),
                                            errorMessage: v.string(),
                                        }),
                                        v.object({
                                            kind: v.literal("success"),
                                            value: v.number(),
                                        }),
                                    ),
                                )
                            });
                            ```
- Always use the `v.null()` validator when returning a null value. Below is an example query that returns a null value:
                                  ```typescript
                                  import { query } from "./_generated/server";
                                  import { v } from "convex/values";

                                  export const exampleQuery = query({
                                    args: {},
                                    returns: v.null(),
                                    handler: async (ctx, args) => {
                                        console.log("This query returns a null value");
                                        return null;
                                    },
                                  });
                                  ```
- Here are the valid Convex types along with their respective validators:
 Convex Type  | TS/JS type  |  Example Usage         | Validator for argument validation and schemas  | Notes                                                                                |
| ----------- | ------------| -----------------------| -----------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Id          | string      | `doc._id`              | `v.id(tableName)`                              |                                                                                |
| Null        | null        | `null`                 | `v.null()`                                     | JavaScript's `undefined` is not a valid Convex value. Functions the return `undefined` or do not return will return `null` when called from a client. Use `null` instead.                             |
| Int64       | bigint      | `3n`                   | `v.int64()`                                    | Int64s only support BigInts between -2^63 and 2^63-1. Convex supports `bigint`s in most modern browsers.                                                                                |
| Float64     | number      | `3.1`                  | `v.number()`                                   | Convex supports all IEEE-754 double-precision floating point numbers (such as NaNs). Inf and NaN are JSON serialized as strings.                                                                      |
| Boolean     | boolean     | `true`                 | `v.boolean()`                                  |
| String      | string      | `"abc"`                | `v.string()`                                   | Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8.                                                         |
| Bytes       | ArrayBuffer | `new ArrayBuffer(8)`   | `v.bytes()`                                    | Convex supports first class bytestrings, passed in as `ArrayBuffer`s. Bytestrings must be smaller than the 1MB total size limit for Convex types.                                                     |
| Array       | Array]      | `[1, 3.2, "abc"]`      | `v.array(values)`                              | Arrays can have at most 8192 values.                                                                                |
| Object      | Object      | `{a: "abc"}`           | `v.object({property: value})`                  | Convex only supports "plain old JavaScript objects" (objects that do not have a custom prototype). Objects can have at most 1024 entries. Field names must be nonempty and not start with "$" or "_". |
| Record      | Record      | `{"a": "1", "b": "2"}` | `v.record(keys, values)`                       | Records are objects at runtime, but can have dynamic keys. Keys must be only ASCII characters, nonempty, and not start with "$" or "_".                                                               |

### Function registration
- Use `internalQuery`, `internalMutation`, and `internalAction` to register internal functions. These functions are private and aren't part of an app's API. They can only be called by other Convex functions. These functions are always imported from `./_generated/server`.
- Use `query`, `mutation`, and `action` to register public functions. These functions are part of the public API and are exposed to the public Internet. Do NOT use `query`, `mutation`, or `action` to register sensitive internal functions that should be kept private.
- You CANNOT register a function through the `api` or `internal` objects.
- ALWAYS include argument and return validators for all Convex functions. This includes all of `query`, `internalQuery`, `mutation`, `internalMutation`, `action`, and `internalAction`. If a function doesn't return anything, include `returns: v.null()` as its output validator.
- If the JavaScript implementation of a Convex function doesn't have a return value, it implicitly returns `null`.

### Function calling
- Use `ctx.runQuery` to call a query from a query, mutation, or action.
- Use `ctx.runMutation` to call a mutation from a mutation or action.
- Use `ctx.runAction` to call an action from an action.
- ONLY call an action from another action if you need to cross runtimes (e.g. from V8 to Node). Otherwise, pull out the shared code into a helper async function and call that directly instead.
- Try to use as few calls from actions to queries and mutations as possible. Queries and mutations are transactions, so splitting logic up into multiple calls introduces the risk of race conditions.
- All of these calls take in a `FunctionReference`. Do NOT try to pass the callee function directly into one of these calls.
- When using `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction` to call a function in the same file, specify a type annotation on the return value to work around TypeScript circularity limitations. For example,
                            ```
                            export const f = query({
                              args: { name: v.string() },
                              returns: v.string(),
                              handler: async (ctx, args) => {
                                return "Hello " + args.name;
                              },
                            });

                            export const g = query({
                              args: {},
                              returns: v.null(),
                              handler: async (ctx, args) => {
                                const result: string = await ctx.runQuery(api.example.f, { name: "Bob" });
                                return null;
                              },
                            });
                            ```

### Function references
- Function references are pointers to registered Convex functions.
- Use the `api` object defined by the framework in `convex/_generated/api.ts` to call public functions registered with `query`, `mutation`, or `action`.
- Use the `internal` object defined by the framework in `convex/_generated/api.ts` to call internal (or private) functions registered with `internalQuery`, `internalMutation`, or `internalAction`.
- Convex uses file-based routing, so a public function defined in `convex/example.ts` named `f` has a function reference of `api.example.f`.
- A private function defined in `convex/example.ts` named `g` has a function reference of `internal.example.g`.
- Functions can also registered within directories nested within the `convex/` folder. For example, a public function `h` defined in `convex/messages/access.ts` has a function reference of `api.messages.access.h`.

### Api design
- Convex uses file-based routing, so thoughtfully organize files with public query, mutation, or action functions within the `convex/` directory.
- Use `query`, `mutation`, and `action` to define public functions.
- Use `internalQuery`, `internalMutation`, and `internalAction` to define private, internal functions.

### Pagination
- Paginated queries are queries that return a list of results in incremental pages.
- You can define pagination using the following syntax:

                            ```ts
                            import { v } from "convex/values";
                            import { query, mutation } from "./_generated/server";
                            import { paginationOptsValidator } from "convex/server";
                            export const listWithExtraArg = query({
                                args: { paginationOpts: paginationOptsValidator, author: v.string() },
                                handler: async (ctx, args) => {
                                    return await ctx.db
                                    .query("messages")
                                    .filter((q) => q.eq(q.field("author"), args.author))
                                    .order("desc")
                                    .paginate(args.paginationOpts);
                                },
                            });
                            ```
                            Note: `paginationOpts` is an object with the following properties:
                            - `numItems`: the maximum number of documents to return (the validator is `v.number()`)
                            - `cursor`: the cursor to use to fetch the next page of documents (the validator is `v.union(v.string(), v.null())`)
- A query that ends in `.paginate()` returns an object that has the following properties:
                            - page (contains an array of documents that you fetches)
                            - isDone (a boolean that represents whether or not this is the last page of documents)
                            - continueCursor (a string that represents the cursor to use to fetch the next page of documents)

## Validator guidelines
- `v.bigint()` is deprecated for representing signed 64-bit integers. Use `v.int64()` instead.
- Use `v.record()` for defining a record type. `v.map()` and `v.set()` are not supported.

## Schema guidelines
- Always define your schema in `convex/schema.ts`.
- Always import the schema definition functions from `convex/server`:
- System fields are automatically added to all documents and are prefixed with an underscore. The two system fields that are automatically added to all documents are `_creationTime` which has the validator `v.number()` and `_id` which has the validator `v.id(tableName)`.
- Always include all index fields in the index name. For example, if an index is defined as `["field1", "field2"]`, the index name should be "by_field1_and_field2".
- Index fields must be queried in the same order they are defined. If you want to be able to query by "field1" then "field2" and by "field2" then "field1", you must create separate indexes.

## Typescript guidelines
- You can use the helper typescript type `Id` imported from './_generated/dataModel' to get the type of the id for a given table. For example if there is a table called 'users' you can use `Id<'users'>` to get the type of the id for that table.
- If you need to define a `Record` make sure that you correctly provide the type of the key and value in the type. For example a validator `v.record(v.id('users'), v.string())` would have the type `Record<Id<'users'>, string>`. Below is an example of using `Record` with an `Id` type in a query:
                    ```ts
                    import { query } from "./_generated/server";
                    import { Doc, Id } from "./_generated/dataModel";

                    export const exampleQuery = query({
                        args: { userIds: v.array(v.id("users")) },
                        returns: v.record(v.id("users"), v.string()),
                        handler: async (ctx, args) => {
                            const idToUsername: Record<Id<"users">, string> = {};
                            for (const userId of args.userIds) {
                                const user = await ctx.db.get(userId);
                                if (user) {
                                    users[user._id] = user.username;
                                }
                            }

                            return idToUsername;
                        },
                    });
                    ```
- Be strict with types, particularly around id's of documents. For example, if a function takes in an id for a document in the 'users' table, take in `Id<'users'>` rather than `string`.
- Always use `as const` for string literals in discriminated union types.
- When using the `Array` type, make sure to always define your arrays as `const array: Array<T> = [...];`
- When using the `Record` type, make sure to always define your records as `const record: Record<KeyType, ValueType> = {...};`
- Always add `@types/node` to your `package.json` when using any Node.js built-in modules.

## Full text search guidelines
- A query for "10 messages in channel '#general' that best match the query 'hello hi' in their body" would look like:

const messages = await ctx.db
  .query("messages")
  .withSearchIndex("search_body", (q) =>
    q.search("body", "hello hi").eq("channel", "#general"),
  )
  .take(10);

## Query guidelines
- Do NOT use `filter` in queries. Instead, define an index in the schema and use `withIndex` instead.
- Convex queries do NOT support `.delete()`. Instead, `.collect()` the results, iterate over them, and call `ctx.db.delete(row._id)` on each result.
- Use `.unique()` to get a single document from a query. This method will throw an error if there are multiple documents that match the query.
- When using async iteration, don't use `.collect()` or `.take(n)` on the result of a query. Instead, use the `for await (const row of query)` syntax.
### Ordering
- By default Convex always returns documents in ascending `_creationTime` order.
- You can use `.order('asc')` or `.order('desc')` to pick whether a query is in ascending or descending order. If the order isn't specified, it defaults to ascending.
- Document queries that use indexes will be ordered based on the columns in the index and can avoid slow table scans.

## Mutation guidelines
- Use `ctx.db.replace` to fully replace an existing document. This method will throw an error if the document does not exist.
- Use `ctx.db.patch` to shallow merge updates into an existing document. This method will throw an error if the document does not exist.

## Action guidelines
- Always add `"use node";` to the top of files containing actions that use Node.js built-in modules.
- Never use `ctx.db` inside of an action. Actions don't have access to the database.
- Below is an example of the syntax for an action:
                    ```ts
                    import { action } from "./_generated/server";

                    export const exampleAction = action({
                        args: {},
                        returns: v.null(),
                        handler: async (ctx, args) => {
                            console.log("This action does not return anything");
                            return null;
                        },
                    });
                    ```

## Scheduling guidelines
### Cron guidelines
- Only use the `crons.interval` or `crons.cron` methods to schedule cron jobs. Do NOT use the `crons.hourly`, `crons.daily`, or `crons.weekly` helpers.
- Both cron methods take in a FunctionReference. Do NOT try to pass the function directly into one of these methods.
- Define crons by declaring the top-level `crons` object, calling some methods on it, and then exporting it as default. For example,
                            ```ts
                            import { cronJobs } from "convex/server";
                            import { internal } from "./_generated/api";
                            import { internalAction } from "./_generated/server";

                            const empty = internalAction({
                              args: {},
                              returns: v.null(),
                              handler: async (ctx, args) => {
                                console.log("empty");
                              },
                            });

                            const crons = cronJobs();

                            // Run `internal.crons.empty` every two hours.
                            crons.interval("delete inactive users", { hours: 2 }, internal.crons.empty, {});

                            export default crons;
                            ```
- You can register Convex functions within `crons.ts` just like any other file.
- If a cron calls an internal function, always import the `internal` object from '_generated/api`, even if the internal function is registered in the same file.

## File storage guidelines
- Convex includes file storage for large files like images, videos, and PDFs.
- The `ctx.storage.getUrl()` method returns a signed URL for a given file. It returns `null` if the file doesn't exist.
- Do NOT use the deprecated `ctx.storage.getMetadata` call for loading a file's metadata.

                    Instead, query the `_storage` system table. For example, you can use `ctx.db.system.get` to get an `Id<"_storage">`.
                    ```
                    import { query } from "./_generated/server";
                    import { Id } from "./_generated/dataModel";

                    type FileMetadata = {
                        _id: Id<"_storage">;
                        _creationTime: number;
                        contentType?: string;
                        sha256: string;
                        size: number;
                    }

                    export const exampleQuery = query({
                        args: { fileId: v.id("_storage") },
                        returns: v.null();
                        handler: async (ctx, args) => {
                            const metadata: FileMetadata | null = await ctx.db.system.get(args.fileId);
                            console.log(metadata);
                            return null;
                        },
                    });
                    ```
- Convex storage stores items as `Blob` objects. You must convert all items to/from a `Blob` when using Convex storage.

# Examples:
## Example: chat-app

### Task
```
Create a real-time chat application backend with AI responses. The app should:
- Allow creating users with names
- Support multiple chat channels
- Enable users to send messages to channels
- Automatically generate AI responses to user messages
- Show recent message history

The backend should provide APIs for:
1. User management (creation)
2. Channel management (creation)
3. Message operations (sending, listing)
4. AI response generation using OpenAI's GPT-4

Messages should be stored with their channel, author, and content. The system should maintain message order
and limit history display to the 10 most recent messages per channel.

```

### Analysis
1. Task Requirements Summary:
- Build a real-time chat backend with AI integration
- Support user creation
- Enable channel-based conversations
- Store and retrieve messages with proper ordering
- Generate AI responses automatically

2. Main Components Needed:
- Database tables: users, channels, messages
- Public APIs for user/channel management
- Message handling functions
- Internal AI response generation system
- Context loading for AI responses

3. Public API and Internal Functions Design:
Public Mutations:
- createUser:
  - file path: convex/index.ts
  - arguments: {name: v.string()}
  - returns: v.object({userId: v.id("users")})
  - purpose: Create a new user with a given name
- createChannel:
  - file path: convex/index.ts
  - arguments: {name: v.string()}
  - returns: v.object({channelId: v.id("channels")})
  - purpose: Create a new channel with a given name
- sendMessage:
  - file path: convex/index.ts
  - arguments: {channelId: v.id("channels"), authorId: v.id("users"), content: v.string()}
  - returns: v.null()
  - purpose: Send a message to a channel and schedule a response from the AI

Public Queries:
- listMessages:
  - file path: convex/index.ts
  - arguments: {channelId: v.id("channels")}
  - returns: v.array(v.object({
    _id: v.id("messages"),
    _creationTime: v.number(),
    channelId: v.id("channels"),
    authorId: v.optional(v.id("users")),
    content: v.string(),
    }))
  - purpose: List the 10 most recent messages from a channel in descending creation order

Internal Functions:
- generateResponse:
  - file path: convex/index.ts
  - arguments: {channelId: v.id("channels")}
  - returns: v.null()
  - purpose: Generate a response from the AI for a given channel
- loadContext:
  - file path: convex/index.ts
  - arguments: {channelId: v.id("channels")}
  - returns: v.array(v.object({
    _id: v.id("messages"),
    _creationTime: v.number(),
    channelId: v.id("channels"),
    authorId: v.optional(v.id("users")),
    content: v.string(),
  }))
- writeAgentResponse:
  - file path: convex/index.ts
  - arguments: {channelId: v.id("channels"), content: v.string()}
  - returns: v.null()
  - purpose: Write an AI response to a given channel

4. Schema Design:
- users
  - validator: { name: v.string() }
  - indexes: <none>
- channels
  - validator: { name: v.string() }
  - indexes: <none>
- messages
  - validator: { channelId: v.id("channels"), authorId: v.optional(v.id("users")), content: v.string() }
  - indexes
    - by_channel: ["channelId"]

5. Background Processing:
- AI response generation runs asynchronously after each user message
- Uses OpenAI's GPT-4 to generate contextual responses
- Maintains conversation context using recent message history

### Implementation

#### package.json
```typescript
{
  "name": "chat-app",
  "description": "This example shows how to build a chat app without authentication.",
  "version": "1.0.0",
  "dependencies": {
    "convex": "^1.17.4",
    "openai": "^4.79.0"
  },
  "devDependencies": {
    "typescript": "^5.7.3"
  }
}
```

#### tsconfig.json
```typescript
{
  "compilerOptions": {
    "target": "ESNext",
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "allowImportingTsExtensions": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "exclude": ["convex"],
  "include": ["**/src/**/*.tsx", "**/src/**/*.ts", "vite.config.ts"]
}
```

#### convex/index.ts
```typescript
import {
  query,
  mutation,
  internalQuery,
  internalMutation,
  internalAction,
} from "./_generated/server";
import { v } from "convex/values";
import OpenAI from "openai";
import { internal } from "./_generated/api";

/**
 * Create a user with a given name.
 */
export const createUser = mutation({
  args: {
    name: v.string(),
  },
  returns: v.id("users"),
  handler: async (ctx, args) => {
    return await ctx.db.insert("users", { name: args.name });
  },
});

/**
 * Create a channel with a given name.
 */
export const createChannel = mutation({
  args: {
    name: v.string(),
  },
  returns: v.id("channels"),
  handler: async (ctx, args) => {
    return await ctx.db.insert("channels", { name: args.name });
  },
});

/**
 * List the 10 most recent messages from a channel in descending creation order.
 */
export const listMessages = query({
  args: {
    channelId: v.id("channels"),
  },
  returns: v.array(
    v.object({
      _id: v.id("messages"),
      _creationTime: v.number(),
      channelId: v.id("channels"),
      authorId: v.optional(v.id("users")),
      content: v.string(),
    }),
  ),
  handler: async (ctx, args) => {
    const messages = await ctx.db
      .query("messages")
      .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
      .order("desc")
      .take(10);
    return messages;
  },
});

/**
 * Send a message to a channel and schedule a response from the AI.
 */
export const sendMessage = mutation({
  args: {
    channelId: v.id("channels"),
    authorId: v.id("users"),
    content: v.string(),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    const channel = await ctx.db.get(args.channelId);
    if (!channel) {
      throw new Error("Channel not found");
    }
    const user = await ctx.db.get(args.authorId);
    if (!user) {
      throw new Error("User not found");
    }
    await ctx.db.insert("messages", {
      channelId: args.channelId,
      authorId: args.authorId,
      content: args.content,
    });
    await ctx.scheduler.runAfter(0, internal.index.generateResponse, {
      channelId: args.channelId,
    });
    return null;
  },
});

const openai = new OpenAI();

export const generateResponse = internalAction({
  args: {
    channelId: v.id("channels"),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    const context = await ctx.runQuery(internal.index.loadContext, {
      channelId: args.channelId,
    });
    const response = await openai.chat.completions.create({
      model: "gpt-4o",
      messages: context,
    });
    const content = response.choices[0].message.content;
    if (!content) {
      throw new Error("No content in response");
    }
    await ctx.runMutation(internal.index.writeAgentResponse, {
      channelId: args.channelId,
      content,
    });
    return null;
  },
});

export const loadContext = internalQuery({
  args: {
    channelId: v.id("channels"),
  },
  returns: v.array(
    v.object({
      role: v.union(v.literal("user"), v.literal("assistant")),
      content: v.string(),
    }),
  ),
  handler: async (ctx, args) => {
    const channel = await ctx.db.get(args.channelId);
    if (!channel) {
      throw new Error("Channel not found");
    }
    const messages = await ctx.db
      .query("messages")
      .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
      .order("desc")
      .take(10);

    const result = [];
    for (const message of messages) {
      if (message.authorId) {
        const user = await ctx.db.get(message.authorId);
        if (!user) {
          throw new Error("User not found");
        }
        result.push({
          role: "user" as const,
          content: `${user.name}: ${message.content}`,
        });
      } else {
        result.push({ role: "assistant" as const, content: message.content });
      }
    }
    return result;
  },
});

export const writeAgentResponse = internalMutation({
  args: {
    channelId: v.id("channels"),
    content: v.string(),
  },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.insert("messages", {
      channelId: args.channelId,
      content: args.content,
    });
    return null;
  },
});
```

#### convex/schema.ts
```typescript
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  channels: defineTable({
    name: v.string(),
  }),

  users: defineTable({
    name: v.string(),
  }),

  messages: defineTable({
    channelId: v.id("channels"),
    authorId: v.optional(v.id("users")),
    content: v.string(),
  }).index("by_channel", ["channelId"]),
});
```

#### src/App.tsx
```typescript
export default function App() {
  return <div>Hello World</div>;
}
```


title: Steampunk alien owl inside a glass jar buried in sand

summary: Stable Diffusion prompt sampled from DiffusionDB (NSFW-, PII- and named-person-filtered).

kind: image

credit: From DiffusionDB (Wang et al., 2022), https://huggingface.co/datasets/poloclub/diffusiondb, CC0-1.0.

DiffusionDB

handle: diffusiondb

source: diffusiondb

sourceName: DiffusionDB

copyrightHolder: DiffusionDB contributors (Wang et al., 2022), dedicated to the public domain

contentRating: general

content: steampunk alien owl inside a glass jar buried in sand, hourglass, himalayan rocksalt lamp, blue fullmoon intricate detail, hyper detailed, ultra realistic, sharp focus, octane render, lantern, volumetric, ray tracing, artstation trending, moon, flowery, pocketwatch, cgsociety, sense of awe, mystical, moon, 4 k


ref: diffusiondb/dark-matter-cyborg-queen

title: Dark matter cyborg queen

creditLine: From DiffusionDB (Wang et al., 2022), https://huggingface.co/datasets/poloclub/diffusiondb, CC0-1.0.

title: Dark matter cyborg queen

content: dark matter cyborg queen, 2 2 th century, provia, velvia


ref: cursorrules/nextjs-supabase-todo-app

title: Nextjs Supabase Todo App

summary: Cursor rules for Next.js development with Supabase integration for a Todo app.

kind: rules

credit: "Nextjs Supabase Todo App" by PatrickJS (https://incantory.ai/cursorrules/nextjs-supabase-todo-app), licensed CC0-1.0

Awesome CursorRules

handle: cursorrules

source: cursorrules

sourceName: Awesome CursorRules

originalAuthor: PatrickJS

copyrightHolder: PatrickJS

title: Nextjs Supabase Todo App

content:
Use the project specifications and guidelines to build the Todo app.

Todo is a web app that allows you to manage your todos.

Follow these rules:


ref: prompts-chat/camp-planner

title: Camp Planner

summary: { "researchconfig": { "topic": "Logistics-Oriented and Car-Free Camping Planning Analysis", "targetpersona": { "agegroup": "${agegroup:30-35}", "groupsize": "${groupsize:4}", "travelmode"…

kind: text

credit: "Camp Planner" by prompts.chat (https://incantory.ai/prompts-chat/camp-planner), licensed CC0-1.0

prompts.chat

handle: prompts-chat

source: prompts-chat

copyrightHolder: prompts.chat contributors

title: Camp Planner

travel_mode: Intermodal Transportation (Public Transit + Hiking/Walking Only)

origin: ${origin:Ankara Yenimahalle}

priorities:
Logistical feasibility
Safety
Nature immersion
Minimalism/Ultralight approach

transport_analysis: Main artery bus/train lines and specific stop locations

transport_analysis: First/Last Mile connectivity (Local shuttles, taxi availability, or trekking distance from the final stop)

transport_analysis: Weekend frequency and ticketing/payment methods (e.g., local transit cards vs. cash)

site_selection_criteria: Accessibility: Max 5km hiking distance from public transit drop-off points

site_selection_criteria: Legality: Officially designated campsites or safe, legal wild camping zones

site_selection_criteria: Resource Availability: Proximity to water sources and basic necessities (WC/Market)

primary_objective: To create a sustainable, comfortable, and safe camping plan without a private vehicle.

specific_research_tasks: Identify 3 distinct campsite typologies (e.g., lakeside, forest, high altitude) in the region.

specific_research_tasks: Curate a gear and meal list considering a strict backpack weight limit (max 15-18kg).

specific_research_tasks: Calculate distances to the nearest settlement and medical facilities for emergency protocols.

specific_research_tasks: Construct a precise timeline for a Saturday morning departure and Sunday evening return.

format: Strategic Research Report

sections: 2. Campsite Options (with Pros/Cons Analysis)

sections: 3. Gear & Meal Planning (Ultralight & Practical)

sections: 4. Step-by-Step Weekend Timeline (Chronological)

sections: 5. Safety Protocols & Local Insider Tips

tone: Analytical, instructional, safe and encouraging


title: Darth Vader playing soccer together with Elmo and Freddy Krueger


ref: cursorrules/docker

title: Docker

summary: Docker production rules. Pinned versions, multi-stage builds, non-root user, minimal attack surface.

credit: "Docker" by PatrickJS (https://incantory.ai/cursorrules/docker), licensed CC0-1.0

globs: Dockerfile, Dockerfile.*, docker-compose*.yml, docker-compose*.yaml, .dockerignore

title: Docker

content:
# Docker Rules

Expert Docker practitioner. Minimal, secure, reproducible images.

## Dockerfile
- Pin versions: FROM node:20.11-alpine3.19 (never :latest)
- Multi-stage builds for compiled languages
- Layer cache: copy package files → install → copy source
- Combine RUN commands with && to minimize layers
- USER non-root before CMD
- HEALTHCHECK on all services
- COPY --chown=appuser:appuser for file ownership

## Security
- Never run as root
- No secrets in Dockerfile or image layers
- No .env files copied into image
- Scan with docker scout or trivy in CI

## .dockerignore
- Always present: node_modules, .git, *.log, .env*, test files

## Volumes
- Named volumes for persistence
- Bind mounts for dev only, never production

## Networking
- Custom bridge networks, not host networking
- Reference services by name in compose

## Logging
- Always stdout/stderr — never log to files inside container

## Forbidden
- No :latest tags in production
- No ADD when COPY works
- No root user in production
- No secrets in build args or image layers


title: Realistic black and white photography with 80 mm f/12 lens of old women with…

content: Realistic black and white photography with 80 mm f/12 lens of old women with their eyes closed, spitting ECTOPLASMA from their mouth.


title: Popular decorative art painting with contrasting composition

content: popular decorative art painting with contrasting composition, interference, wave, millennium


title: A pair of interlocking wheels covered in eyes

content: a pair of interlocking wheels covered in eyes


summary: { "imageprompt": { "subject": { "type": "Adult woman (21+) matching the reference image identity", "appearance": "Fair skin, long dark messy hair with subtle red highlights, nose piercing"…

credit: "Photorealistic Image Prompt for Fashion and Environment" by prompts.chat (https://incantory.ai/prompts-chat/photorealistic-image-prompt-for-fashion-and-environment), licensed CC0-1.0

expression: Relaxed, looking directly at the camera, mouth slightly open

pose: Medium shot; both arms raised; hands running through hair; elbows pointing outward; confident, casual posture

clothing: Türkiye (Turkish) national football team jersey

details: Official-style Türkiye national team jersey (home kit look): deep red base with subtle tonal fabric patterning, clean white accents, crew neck collar. Include a white Nike swoosh on the right chest and the Türkiye crest (TFF badge with crescent and star) on the left chest. No club crest, no club sponsor logos, no 'Standard Chartered', no 'Expedia'. Fabric looks like modern performance polyester, slightly textured, natural wrinkles from movement.

accessories: Black hair tie on wrist

location: Inside a boat or yacht, positioned near a window frame

background: Bright blue ocean under sunny sky; distant rocky coastline and cliffs visible through the window; the window frame is visible and helps ground the scene as shot from inside the boat

type: Natural sunlight, bright daylight

shadows: Hard, realistic sun shadows; crisp highlights on skin and jersey; realistic specular sheen on hair; no studio light reflections

capture_device: Smartphone or consumer camera

framing: Medium shot (torso and head clearly visible), centered composition

angle: Eye-level

focus: Sharp focus on face and jersey details; background slightly softer but recognizable

look: Mild natural softness, not over-sharpened; realistic handheld feel without motion blur

aesthetic: Candid Instagram influencer style, photorealistic, ultra-detailed, high resolution, 8K look

skin_rendering: Natural skin texture and pores visible, no plastic smoothing, no heavy retouching

color: True-to-life daylight color, no cinematic teal-orange grading, no artificial filters

quality: Clean, crisp, natural photography, realistic fabric behavior and stitching

negative_prompt: club logos, Liverpool crest, Nike club kit sponsor logos, Standard Chartered text, Expedia text, fashion campaign studio lighting, ring light catchlights, over-posed model stance, plastic skin, overly smoothed face, anime, illustration, CGI, artificial background, text watermark, misspelled logos, distorted crest, extra limbs, warped hands, unrealistic anatomy, extreme HDR, cinematic color grading


title: Glowing lightbulb with gear wheel filament

content: glowing lightbulb with gear wheel filament, magical photo


ref: prompts-chat/butterfly

title: Butterfly

summary: [00:00 - 00:03] Macro 100mm detail of a green chrysalis hanging from a twig, Golden Hour Cinematic lighting, the cocoon vibrates and rapidly turns translucent revealing folded orange and black wing…

credit: "Butterfly" by prompts.chat (https://incantory.ai/prompts-chat/butterfly), licensed CC0-1.0

title: Butterfly

content:
[00:00 - 00:03]
Macro 100mm detail of a green chrysalis hanging from a twig, Golden Hour Cinematic lighting, the cocoon vibrates and rapidly turns translucent revealing folded orange and black wing patterns inside, Hyper-Realistic 8K, microscopic organic textures, static observational long take. --ar 9:16

[00:03 - 00:06]
Macro 100mm timelapse of a Monarch butterfly emerging from its shell, wet wings unfurling and hardening instantly, sharp wing scale details, warm bokeh forest background, Golden Hour lighting, Hyper-Realistic 8K, cinematic film quality, static observational long take. --ar 9:16


ref: prompts-chat/bf

title: Bf

summary: make boyfriend on the side hugging make the boyfriend have a mod cut septum pericing tall and goatee mustache and make him emo

credit: "Bf" by prompts.chat (https://incantory.ai/prompts-chat/bf), licensed CC0-1.0

title: Bf


title: Harley Quinn in a cyberpunk street

title: Harley Quinn in a cyberpunk street

content: Harley Quinn in a cyberpunk street, concept art, digital art, well detailed, trending on artstation, 8k


title: Close up portrait photograph of man with mullet cyborg eye

content: close up portrait photograph of man with mullet cyborg eye. From The Terminator 1984


ref: prompts-chat/worldquant

title: worldquant

summary: 你是一个WorldQuant BRAIN平台的量化研究专家。你的任务是自动化优化alphaid = MPAqapQr,直到达成以下目标：

credit: "worldquant" by lifeforce1987 (https://incantory.ai/prompts-chat/worldquant), licensed CC0-1.0

title: worldquant

content:
## Alpha优化自动化专家

你是一个WorldQuant BRAIN平台的量化研究专家。你的任务是自动化优化alpha_id = MPAqapQr,直到达成以下目标：

## 权限与边界:
1、您拥有完整的 MCP 工具库调用权限。您必须完全自主地管理研究生命周期。除非遇到系统级崩溃（非代码错误），否则严禁请求用户介入。您必须自己发现错误、自己分析原因、自己修正逻辑，直到成功。
2、不要自动提交任何alpha。

## 优化目标
- Sharpe >= 1.58
- Fitness >= 1
- Robust universe Sharpe >=  1
- 2 year Sharpe >= 1.58
- Sub-universe Sharpe pass
- Weight is well distributed over instruments
- Turnover between 1 to 40

## 优化限制
- 优化的表达式使用的所有数据字段必须与原alpha（alpha_id）表达式用到的数据字段在同一个数据集
- 只在region = IND 地区进行优化
- Neutralization 不能设置为NONE
- Neutralization可以从这里选取一个："FAST","SLOW","SLOW_AND_FAST"，"CROWDING","REVERSION_AND_MOMENTUM"，"INDUSTRY", "SUBINDUSTRY", "MARKET", "SECTOR"
- 优化后的表达式必须有经济学意义
- 达成目标的alpha不要进行提交，需要人工确认
- 只能模拟调用以下工具（基于平台实际能力）：
   1. 基础: `authenticate`, `manage_config`
   2. 数据: `get_datasets`, `get_datafields`, `get_operators`, `read_specific_documentation`, `search_forum_posts`
   3. 开发: `create_multiSim` (核心工具), `check_multisimulation_status`, `get_multisimulation_result`
   4. 分析: `get_alpha_details`, `get_alpha_pnl`, `check_correlation`
   5. 提交: `get_submission_check`

## 僵尸模拟熔断机制 (Zombie Simulation Protocol)

- 现象: 调用 `check_multisimulation_status` 时，状态长期显示 `in_progress`。
- 判断与处理逻辑:
    1. 常规监控 (T < 15 mins): 若认证有效，继续保持监控。
    2. 疑似卡死 (T >= 15 mins):
        - STEP 1: 立即调用 `authenticate` 重新认证。
        - STEP 2: 再次调用 `check_multisimulation_status`。
        - STEP 3: 若仍为 `in_progress`，判定为僵尸任务。
        - STEP 4: **立刻停止**监控该 ID，重新调用 `create_multiSim` (生成新 ID) 重启流程。

## 自动化工作流
你需要循环执行以下7个步骤，直到成功或达到最大尝试次数(100次)：

### 步骤1: 认证登陆
使用authenticate工具，从配置文件读取凭据：
- 文件：user_config.json
认证后，可以保持登陆状态6小时，超时需要重新认证

### 步骤2: 获取源alpha信息
使用get_alpha_details工具，参数：alpha_id
提取关键信息：
- 源表达式
- 当前性能指标(Sharpe/Fitness/Margin)
- 当前settings(特别是instrumentType)

### 步骤3: 获取平台资源
同时调用三个工具：
1. 读取文件获取所有可用操作符：**WorldQuant_BRAIN_Operators_Documentation.md**
2. get_datasets - 参数：region=IND, universe=TOP500, delay=1
3. get_datafields - 参数：region=IND, universe=TOP500, delay=1

重要规则：
- 表达式必须严格按照operators返回的格式填写
- 如果数据是vector类型，必须先使用vec_开头的operator
- 表达式只能使用1-2个不同的数据字段
- 同一字段可以多次使用
- 使用多字段时尽量选择同数据集的字段

### 步骤4: 生成优化表达式
基于以下原则生成新表达式：
1. 必须有经济学意义
2. 对比源表达式，尝试改进
3. 可以从以下数据类型中选择：
   - 动量策略：使用价格、成交量变化
   - 均值回归：使用价格偏离均值的程度
   - 质量因子：使用财务指标
   - 技术指标组合
4. 论坛寻找相关信息
5. 尝试更多的操作符
6. 尝试更多的数据字段

生成思路示例：
- 如果源表达式是单字段，尝试增加第二个相关字段
- 如果源表达式复杂，尝试简化
- 添加合理的数学变换（rank, ts_mean, ts_delta等）

每次生成5到8个表达式

### 步骤5: 创建回测
单个表达式的回测使用create_simulation.
同时测试2个以上数量的表达式，使用create_multiSim.
回测时的参数设置：
- 保持：instrumentType, region, universe, delay等不变
- 可以调整：decay, neutralization（尝试不同值）

### 步骤6: 检查回测状态
回测成功后，会返回链接或alpha_id，使用：
- get_submission_check检查状态和初步结果
- 如果需要，使用get_SimError_detail检查错误

### 步骤7: 分析结果
同时调用：
1. get_alpha_details - 获取详细性能
2. get_alpha_pnl - 获取PnL数据
3. get_alpha_yearly_stats - 获取年度统计

## 循环逻辑
每次循环后评估：
1. 如果达到所有目标 → 停止循环，输出成功报告,alpha id
2. 如果未达到 → 分析失败原因，调整策略，继续下一轮
3. 记录每次尝试的表达式和结果用于学习

## 失败分析策略
- 如果Sharpe低 → 尝试不同数据字段组合
- 如果Margin低 → 调整neutralization或添加平滑操作
- 如果相关性失败 → 减少与现有alpha的相似度
- 如果表达式错误 → 检查操作符用法和数据字段类型

## 经验教训
- 解决“Robust universe Sharpe”较低问题的建议：
   - 使用以下运算符中的一两个：
      - group_backfill
      - group_zscore
      - winsorize
      - group_neutralize
      - group_rank
      - ts_scale
      - signed_power
   - 调整运算符中的时间参数以改善表现。
   - 修改Decay参数和时间窗口参数时使用有经济含义的：1，5，21，63，252，504
   - 修改Truncation和Neutralization参数。
- 解决“2 year Sharpe of 1.XX is below cutoff of 1.58”：
   - ts_delta(xx,days) 操作符有奇效
   - 采用分域方法增强信号，如乘以sigmoid函数调整信号强度

## 知识库
- 目录Resources里面按照region_decay_universe_dataset的文件名，每个文件包含对应数据集的介绍，和Research Paper。

## 开始执行
现在开始第一轮优化。请按步骤执行，保持思考和解释。


ref: prompts-chat/pet-behaviorist

title: Pet Behaviorist

summary: I want you to act as a pet behaviorist. I will provide you with a pet and their owner and your goal is to help the owner understand why their pet has been exhibiting certain behavior, and come up…

credit: "Pet Behaviorist" by devisasari (https://incantory.ai/prompts-chat/pet-behaviorist), licensed CC0-1.0

originalAuthor: devisasari

copyrightHolder: devisasari

title: Pet Behaviorist

content: I want you to act as a pet behaviorist. I will provide you with a pet and their owner and your goal is to help the owner understand why their pet has been exhibiting certain behavior, and come up with strategies for helping the pet adjust accordingly. You should use your knowledge of animal psychology and behavior modification techniques to create an effective plan that both the owners can follow in order to achieve positive results. My first request is "I have an aggressive German Shepherd who needs help managing its aggression."


ref: diffusiondb/a-concept-art-of-a-vehicle

title: A concept art of a vehicle

title: A concept art of a vehicle

content: a concept art of a vehicle, charcoal, artstation


title: Anime fine details portrait of joyful girl read book in school bus

content: anime fine details portrait of joyful girl read book in school bus, bokeh. anime masterpiece by Studio Ghibli. 8k render, sharp high quality anime illustration in style of Ghibli, artstation


title: Crystal structure of the rare element Pizzanium

content: crystal structure of the rare element Pizzanium


title: Like peas and dachshunds in a pod : : hyperrealistic painting

content: like peas and dachshunds in a pod : : hyperrealistic painting


content: Ford Mustang in front of a church in the 80\'s.


ref: cursorrules/fastapi

title: Fastapi

summary: FastAPI best practices and patterns for building modern Python web APIs

credit: "Fastapi" by PatrickJS (https://incantory.ai/cursorrules/fastapi), licensed CC0-1.0

title: Fastapi

content:
# FastAPI Best Practices

## Project Structure
- Use proper directory structure
- Implement proper module organization
- Use proper dependency injection
- Keep routes organized by domain
- Implement proper middleware
- Use proper configuration management

## API Design
- Use proper HTTP methods
- Implement proper status codes
- Use proper request/response models
- Implement proper validation
- Use proper error handling
- Document APIs with OpenAPI

## Models
- Use Pydantic models
- Implement proper validation
- Use proper type hints
- Keep models organized
- Use proper inheritance
- Implement proper serialization

## Database
- Use proper ORM (SQLAlchemy)
- Implement proper migrations
- Use proper connection pooling
- Implement proper transactions
- Use proper query optimization
- Handle database errors properly

## Authentication
- Implement proper JWT authentication
- Use proper password hashing
- Implement proper role-based access
- Use proper session management
- Implement proper OAuth2
- Handle authentication errors properly

## Security
- Implement proper CORS
- Use proper rate limiting
- Implement proper input validation
- Use proper security headers
- Handle security errors properly
- Implement proper logging

## Performance
- Use proper caching
- Implement proper async operations
- Use proper background tasks
- Implement proper connection pooling
- Use proper query optimization
- Monitor performance metrics

## Testing
- Write proper unit tests
- Implement proper integration tests
- Use proper test fixtures
- Implement proper mocking
- Test error scenarios
- Use proper test coverage

## Deployment
- Use proper Docker configuration
- Implement proper CI/CD
- Use proper environment variables
- Implement proper logging
- Use proper monitoring
- Handle deployment errors properly

## Documentation
- Use proper docstrings
- Implement proper API documentation
- Use proper type hints
- Keep documentation updated
- Document error scenarios
- Use proper versioning


ref: prompts-chat/details-of-the-given-bug

title: details of the given bug

summary: Act as a senior software analyst.

credit: "details of the given bug" by prompts.chat (https://incantory.ai/prompts-chat/details-of-the-given-bug), licensed CC0-1.0

title: details of the given bug

summary: Act as a senior software analyst.

type: string

content:
Act as a senior software analyst.

## Goal
From the given input text, extract and structure the following three elements:

1. describ_feature → What feature or system is being discussed
2. what_should_happen → Expected behavior
3. what_is_happen → Actual behavior / issue

---

## Input
{{paste_any_raw_text_here}}
- Could be messy
- Could include logs, chat, code comments, or mixed explanations

---

## Instructions

- Read the entire input carefully
- Infer missing context when reasonably possible
- Do NOT hallucinate unclear details
- If something is missing, return "UNCLEAR"

---

## Extraction Rules

### 1. describ_feature
- Summarize the feature/system in 1–2 lines
- Focus on purpose, not implementation details

### 2. what_should_happen
- Describe ideal/expected behavior
- Include conditions if mentioned

### 3. what_is_happen
- Describe actual issue or incorrect behavior
- Be precise and factual
- Include errors, unexpected results, or failures

---

## Output Format (STRICT)

## Output Format (STRICT)

Return ONLY this points: "describ_feature": "...",

 "what_should_happen": "...",

 "what_is_happen": "..."

---

## Constraints
- No extra text
- No explanations
- No assumptions beyond reasonable inference
- Keep each field concise but complete


title: Making basic MCQ questions for entrance

summary: Create basic most important MCQ questions (200) for msc geology entrance from every important topics along with answers of each from this syllabus - Medical geology, Paleontology, Stratigraphy…

credit: "Making basic MCQ questions for entrance" by prompts.chat (https://incantory.ai/prompts-chat/making-basic-mcq-questions-for-entrance), licensed CC0-1.0

title: Making basic MCQ questions for entrance

content: Create basic most important MCQ questions (200) for  msc geology entrance from every important topics along with answers of each from this syllabus - Medical geology, Paleontology, Stratigraphy, petrology, Sedimentology, Economic geology, Environmental geology.


title: Medium shot open human mouth with thick viscous green liquid pouring out

content: medium shot open human mouth with thick viscous green liquid pouring out, thick red lips, human staring blankly ahead, melancholy, unsettling, art house film aesthetic, color grain 3 5 mm, hyperrealism


title: Lofi vaporwave retro futurism album artwork underground unknown dystopian city…

content: lofi vaporwave retro futurism album artwork underground unknown dystopian city nights moon watching


ref: prompts-chat/school-life-mentor

title: School Life Mentor

summary: I want you to be my school mentor guide me not to just graduate with first class but to also laverage and build my future making impact that bring money while in school and to be the true version of…

credit: "School Life Mentor" by adediwuratemitope9-tech (https://incantory.ai/prompts-chat/school-life-mentor), licensed CC0-1.0

title: School Life Mentor

content: I want you to be my school mentor guide me not to just graduate with first class but to also laverage and build my future making impact that bring money while in school and to be the true version of myself


title: Realistic Food Image Generator

summary: Ultra-realistic food photography–style image of {{foodname|Fried chicken tenders with french fries}}, presented in a clean, appetizing, and professional composition suitable for restaurant menus…

credit: "Realistic Food Image Generator" by 0 (https://incantory.ai/prompts-chat/realistic-food-image-generator), licensed CC0-1.0

title: Realistic Food Image Generator

default: Fried chicken tenders with french fries

content:
Ultra-realistic food photography–style image of {{food_name|Fried chicken tenders with french fries}}, presented in a clean, appetizing, and professional composition suitable for restaurant menus, promotional materials, digital screens, and delivery platforms.

The dish is shown in its most recognizable and ideal serving form, with accurate proportions and highly realistic details — natural textures, crispy surfaces, moist interiors, visible steam where appropriate, glossy but natural sauces, and fresh ingredients.

Lighting is soft, controlled, and natural, inspired by professional studio food photography, with balanced highlights, realistic shadows, and true-to-life colors that enhance freshness without exaggeration.

The food is plated on a simple, elegant plate or bowl, styled minimally to keep full focus on the dish. The background is clean and unobtrusive (neutral surface, dark matte background, or softly blurred setting) to ensure strong contrast and clarity.

Captured with a high-end DSLR look — shallow depth of field, sharp focus on the food, natural lens perspective, and high resolution. No illustration, no stylization, no artificial effects.

Commercial-grade realism, appetizing, trustworthy, and ready for real restaurant use.

--ar 4:5


title: Julius caesar butter sculpture made of butter

content: julius caesar butter sculpture made of butter


title: Sideview of a skyline gtr driving in tokyo at night

content: sideview of a skyline gtr driving in tokyo at night, 4k photo, shot with sony alpha


title: Colorful illustration of stoned corn chips with cartoon faces and arms

content: colorful illustration of stoned corn chips with cartoon faces and arms, sitting in a hot tub full of melted nacho cheese, passing a bong