This guide outlines my approach to building software projects using Cursor IDE, leveraging Gemini (gemini-exp-1206, gemini-2.0-flash-exp) and Claude (3.5 sonnet and 3 opus) for effective development and maintaining code integrity.
1. Project Setup: Laying the Foundation for AI Collaboration
Think of your project as a well-organized workshop where you and your AI collaborators (Gemini and Claude) will build something amazing. The first step is to set up the workshop properly.
1.1. Define the Rules of Engagement with .cursorrules
Just like any workshop needs rules, your AI collaborators need guidelines. Create a .cursorrules
file at the root of your project. This file acts as a constitution, defining how the AI should interact with your code.
Why: This ensures everyone (you and the AI) is on the same page regarding priorities, coding standards, and how to approach tasks.
Example .cursorrules
:
{
"rules": {
"context_initialization": {
"description": "Starting point for each interaction",
"steps": [
"ALWAYS read `.notes/project_overview.md` and `.notes/task_list.md`"
]
},
"operational_protocol": {
"description": "How to approach tasks",
"before_action": [
"Create a MECE task breakdown"
],
"code_changes": [
"Read relevant code sections before editing",
"Preserve existing functionality",
"Maintain type safety"
]
},
"safety_requirements": [
"NEVER break type safety",
"ALWAYS maintain proper error handling",
"ALWAYS document new code"
],
"priorities": [
{
"source": ".notes/",
"weight": 1.0
}
],
"modes": {
"base": {
"description": "For routine tasks"
},
"enhanced": {
"description": "For complex problems"
}
},
"project_directives": {
"name": "my_project",
"ai_first": true
}
}
}
1.2. Control File Visibility with .cursorignore
Use .cursorignore
to tell your AI helpers what to ignore, similar to how youâd use a .gitignore
for version control.
Why: This keeps the AI focused on the essential parts of your project, reducing noise and improving efficiency.
Example .cursorignore
:
/node_modules
/build
/temp
.DS_Store
1.3. Establish a Central Hub with .notes
Every project needs a central hub for information. Create a .notes
directory to store all project-related documentation, meeting notes, architectural diagrams, and AI interaction logs. Think of it as your projectâs âbrainâ or âknowledge base.â
Why: This ensures that you and your AI collaborators have a shared understanding of the projectâs goals, status, and history.
Key Files in .notes
:
project_overview.md
: A high-level description of your project, its goals, and architecture.task_list.md
: A detailed list of tasks, their status (e.g., âTo Do,â âIn Progress,â âCompleteâ), priorities, and any relevant notes.directory_structure.md
: An automatically updated overview of your projectâs directory structure. This helps the AI understand where different code components live.meeting_notes.md
: A log of your interactions with the AI, including questions asked, answers received, and decisions made.
2. Managing .notes
and Shared Context
Imagine youâre working with a team of people. To collaborate effectively, you need to ensure everyone has a shared understanding of the project like scrum/kanban/project plan. This is where using markdown docs as shared notepads comes in.
2.1. Populate project_overview.md
This document is like your projectâs âelevator pitch.â It should provide a concise overview of what your project is, its goals, its high-level architecture, and (optionally, but highly recommended) some sample user journeys.
Example:
# Project Overview
## Goal
Build a web application that allows users to create and manage to-do lists.
## Architecture
- **Frontend:** React application using TypeScript.
- **Backend:** Serverless API using Node.js and a cloud database.
- **State Management:** Using a custom state management solution based on React hooks.
## Key Features
- User authentication
- Create, edit, and delete to-do lists
- Mark tasks as complete
- Real-time synchronization
2.2. Create task_list.md
This file is your projectâs âto-do list.â It should track all tasks, their status, priorities, and any relevant notes.
Example:
# Task List
## High Priority
- [ ] Implement user authentication flow. (**Status:** In Progress, **Assigned To:** Gemini, **Notes:** Currently working on the login component.)
- [ ] Design database schema. (**Status:** To Do, **Assigned To:** Claude, **Notes:** Need to consider scalability.)
## Medium Priority
- [ ] Create basic UI for to-do list creation. (**Status:** To Do, **Assigned To:** Gemini, **Notes:** Waiting for authentication to be completed.)
## Low Priority
- [ ] Add support for task categorization. (**Status:** To Do, **Assigned To:** None, **Notes:** Can be implemented later.)
## Completed
- [x] Set up project structure.
- [x] Create basic React components for header and footer.
2.3. Generate directory_structure.md
This file provides a map of your projectâs layout. You can create it manually or use a script to generate it automatically.
Example (Manual):
# Directory Structure
- **components/**: Reusable UI components (e.g., Button, Input, List)
- **hooks/**: Custom React hooks (e.g., useAuth, useData)
- **lib/**: Utility functions and API clients
- **pages/**: Top-level application pages (e.g., Home, Login, Register)
- **styles/**: Global styles and theme definitions
Example Script (PowerShell):
# Save as update_directory.ps1
$projectRoot = "."
$outputFile = "./.notes/directory_structure.md"
# Generate directory listing
function Get-FormattedDirectory {
param (
[string]$path,
[int]$indent = 0
)
$indentString = " " * $indent
$content = ""
foreach ($item in Get-ChildItem -Path $path -Force) {
if ($item.PSIsContainer) {
$content += "$indentString- **$($item.Name)/**`n"
$content += Get-FormattedDirectory -path $item.FullName -indent ($indent + 1)
} else {
$content += "$indentString- $($item.Name)`n"
}
}
return $content
}
# Generate content for markdown file
$markdownContent = @"
# Current Directory Structure
## Core Components
```
$(Get-FormattedDirectory -path $projectRoot)
```
"@
# Output to file
$markdownContent | Out-File -FilePath $outputFile -Encoding UTF8
Write-Host "Directory structure updated in $($outputFile)"
3. Prompt Mastery and Focusing Conversations
Now that you setup a digital âworkshopâ with you, Claude, and Gemini all on the same page through the docs created above, itâs time to start working with Composer in Normal mode with Gemini. This is where the art of prompting comes in.
3.1. Why is Context Crucial?
- Focus: Like a spotlight, context helps the AI focus on the relevant parts of your codebase, ignoring irrelevant details.
- Accuracy: A shared understanding of the projectâs goals, status, and architecture ensures responses are accurate and aligned with your intentions.
- Consistency: You can help the AI maintain the architectural integrity of your project, preventing it from making changes that might break existing functionality or introduce inconsistencies.
3.2. Using @
to Focus the AI
The @
symbol is your primary tool for providing context to Gemini and Claude within Cursor. Itâs like pointing to a specific document or code section during a conversation.
Examples:
@components/Button.tsx
: âHey Gemini, letâs focus on this specific component.â@.notes/task_list.md
: âClaude, check out the current task list and priorities.â@.notes/project_overview.md
: âGemini, remember the overall goals and architecture we discussed?â
3.3. Ground AI Answers with Accuracy and Consistency
-
Be Specific: Ask direct, specific questions. Avoid vague or ambiguous language.
- Instead of: âHow can I improve this code?â
- Try: âGemini, how can I make the
handleSubmit
function in@components/LoginForm.tsx
more efficient?â
-
Use MECE: MECE (Mutually Exclusive, Collectively Exhaustive) is a powerful problem-solving technique. Break down complex tasks into smaller, non-overlapping subtasks.
-
Example: "Claude, letâs break down the implementation of the user authentication flow using MECE:
- User Input: Handle username and password input.
- API Call: Send credentials to the authentication API.
- Response Handling: Process the API response (success or error).
- State Update: Update the application state based on the authentication result.
What are your thoughts on this breakdown? Any suggestions?"
-
-
Iterate and Refine: Donât expect perfect results on the first try. Engage in an iterative dialogue with the AI. Provide feedback on its suggestions, ask clarifying questions, and refine your prompts based on its responses.
- Example: âGemini, your suggestion for optimizing the
handleSubmit
function is good, but it doesnât address the potential for race conditions. How can we modify it to handle that scenario?â
- Example: âGemini, your suggestion for optimizing the
-
Ask âWhyâ: Encourage the AI to explain its reasoning. This helps you understand its thought process and identify potential misunderstandings.
- Example: âClaude, why did you recommend using this particular state management approach instead of the one outlined in
@.notes/project_overview.md
?â
- Example: âClaude, why did you recommend using this particular state management approach instead of the one outlined in
-
Explore Counterfactuals: Consider alternative approaches and discuss their pros and cons with the AI.
- Example: âGemini, what would be the downside of using a different API client library than the one currently used in
@lib/api.ts
?â
- Example: âGemini, what would be the downside of using a different API client library than the one currently used in
-
âWhat Ifâ Scenarios: Challenge the AI with hypothetical situations to assess its understanding and problem-solving abilities.
- Example: âClaude, what if the authentication API is temporarily unavailable? How should the application handle that scenario to provide a good user experience?â
-
Leverage âRemember Whenâ Prompts: Refer back to previous interactions or decisions to maintain continuity and build upon established knowledge.
- Example: âGemini, remember when we discussed the need for optimistic updates in the context of the to-do list creation? How can we apply that concept to the task editing functionality in
@components/TaskItem.tsx
?â
- Example: âGemini, remember when we discussed the need for optimistic updates in the context of the to-do list creation? How can we apply that concept to the task editing functionality in
4. Advanced Tips: Taking Your AI Collaboration to the Next Level
-
Maintain a âConsciousness Streamâ: Keep detailed logs of your interactions with Gemini and Claude in
.notes/meeting_notes.md
. Ask Gemini and Claude to keep these updated on a regular basis throughout your conversations. -
Set up different modes: Utilize the different modes defined in your
.cursorrules
(e.g., âbaseâ for routine tasks, âenhancedâ for more complex problems) to optimize the AIâs performance. -
Donât Be Afraid to Start Over: Sometimes, itâs more efficient to start a particular task or conversation from scratch than to try to fix a confused or misaligned AI.
5. Conclusion
By treating your AI collaborators like valuable human contributors, establishing clear rules of engagement, providing focused context, and prompting effectively, you can achieve significant success with large codebases.
Iâve used this approach for over 70 apps/projects in the last 6 months and have had several scenarios without a single hiccup. Remember to use AI to help AI help itself. Itâs the magic of Cursor and having the IDE as an extension (ie. digital body) for the AI.