Prompt Context: The technique of the era

DongYoon KangDongYoon Kang
4 min read

I want to introduce an idea for utilizing AI for huge repositories. It’s a tool-agnostic technique.

  • The IDE you use does not matter.

  • The size of your code base can be huge; AI will still work with this technique.

tl;dr;

My .cursorrules:

 - First, look for glob `**/.AI.md`. Use terminal command `find . -name '.AI.md'` from the project root, if required.
 - Second, if you are going to read and/or write any file in a directory containing `.AI.md` files from the first step, read all of them and respect the instructions in them.
 - For example, if you are reading or writing a file at /a/b/c, you should check for `/a/.AI.md`, `/a/b/.AI.md` and `/a/b/c/.AI.md` in the order.

Did you get it? You can write this down and write down how you need to work on a folder-by-folder basis in a folder-specific context.md. This technique tells the AI what to do in which folders and how to do it on a folder-by-folder basis.

The idea is that the AI can call tools to read the files it needs, depending on what it needs to do. In my repository, I had a mix of next.js apps with different feelings, code for protobuf-based RPCs packaged in monorepo, and a lot of other things to do in other folders, and I was able to apply this technique to solve the problem.

Pros:

  • Context size is rarely an issue no matter how large your repository grows, because you're not flipping through action rules for every folder.

  • It's easier to manage because you can set action rules per folder.

  • The AI will adhere to your code style (and if it doesn't, you can write it down in context.md).

  • AI’s code will be of higher quality.

  • .cursorrules-style file works for any kind of complex repository, even though requirements are very different.

An example context.md files would be

/context.md:

(This is at the root of the repository)


# RPC

We use connect rpc to call RPC methods. The protobuf files are located at `${gitRoot}/rpc/*/v1.proto`.

## When to use RPC vs client-side code

- Basically, prefer client-side code over RPC.
- If you need to call a nodejs-only code, use RPC.
- If you need to call code that uses any secret, use RPC.

## Implementing RPC methods

- First, add the RPC method definitions and message definitions to the protobuf files.
- You should register the RPC method implementations in the `${gitRoot}/servers/*-api/connect.ts` file.
- You should not store all code in the `${gitRoot}/servers/*-api/connect.ts` file. Instead, define a service and put the implementation in another file in the same directory.

## Calling RPC methods

- Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.

From a react component, you can define a hook using the `useMutation` method.

```js
const detectFaces = webtoolsClient.detectFaces.useMutation();
```

After then, you can call the method with `mutateAsync` method.

```js
const result = await detectFaces.mutateAsync({
  imageData: new Uint8Array(buffer),
});
```

/apps/context.md:

1. This directory contains next.js apps. Follow the next.js app directory structure.
2. List all files before you start coding. Follow the file structure.
3. Do not fetch directly from the page component. Instead, define a hook to fetch the data and use it in the page component.
4. Prefer explicit path parameters in components over 'useParams'.
5. Do not generate shadcn ui components.
6. If you are trying to run the test script in package.json (e.g. `pnpm test:unit`), ensure you set environment variable `CI=1` to indicate it's running automatically.
7. Follow Toss Design guidelines.
8. Ignore route-related TypeScript type errors.
9. If you need to call mutating RPC methods, use the `useMutation` hook.

```ts
const createProject = coreClient.createProject.useMutation();
```

10. If you need to call query RPC methods, use the `useQuery` hook.

```ts
const projects = coreClient.listProjects.useQuery();
```

11. Include `locale: Locale` where `Locale` is `import { Locale } from "@/i18n";` in the params of the page components.
12. Define the params as `Promise<T>` in the page components.
13. Use `use(params)` to unwrap the params as `T` from `Promise<T>` in the page components.
14. Import RPC clients from `@dudykr/rpc-clients/src/XXX`. where `XXX` is the name of the RPC client.

e.g.

```ts
import { coreClient } from "@dudykr/rpc-clients/src/core";
```

15. Use `<Link>` from `next/link` instead of the `<a>` tag.

# Translation

For the next.js apps, modify only `./messages/en.json` and run `pnpm translate`.
This will translate the messages to all languages.

These are real context.md files I use. Give it a try if it sounds interesting.

1
Subscribe to my newsletter

Read articles from DongYoon Kang directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

DongYoon Kang
DongYoon Kang