Dev Tools // // 9 min read

Ditching the Clutter: A Practical Guide to Managing Cursor/Windsurf with Just Two Files

balakumar Senior Software Engineer

Let's talk about getting AI assistants in your IDE (like Cursor, Windsurf, or others) to actually do what you want without wrestling with complex configs or endless repetition. Managing context – telling the AI what your project is about, how it should behave, and what it should do next – is key, but can feel messy.

I've found a pattern using just two core Markdown files that significantly simplifies this. It helps keep the AI focused, makes its process transparent, and allows for more automation. This guide provides enough detail for you to try implementing this pattern yourself.

The Core Setup: ai_project_context.md and ai_dynamic_task.md

The foundation is two files within your project, perhaps in a dedicated .ai/ folder:

  1. ai_project_context.md: The Project Rulebook (Your Stable Context)

    • Purpose: Holds the long-term, unchanging information about your project environment. The AI should consult this for foundational knowledge.

    • Example Structure & Content:

      # AI Project Context: MyWebApp
      
      ## 1. Project Goal
      Build a web application for managing personal tasks, focusing on simplicity and offline-first capabilities.
      
      ## 2. Tech Stack
      - Frontend: React (using functional components and Hooks), TypeScript, CSS Modules
      - Backend: Node.js with Express, TypeScript
      - Database: PostgreSQL
      - State Management: Zustand (React)
      - Testing: Jest, React Testing Library (Frontend); Jest (Backend)
      - Package Manager: npm
      
      ## 3. Critical Coding Standards & Patterns
      - **TypeScript:** Use strict mode. Prefer interfaces over type aliases for defining object shapes. Use utility types where appropriate.
      - **React:** Adhere to Rules of Hooks. Keep components small and focused. Use descriptive prop names. Avoid default exports.
      - **Node.js/Express:** Use async/await for all asynchronous operations. Implement robust error handling middleware. Use dependency injection for services.
      - **Naming:** Use camelCase for variables/functions, PascalCase for components/classes/interfaces. Be descriptive.
      - **Formatting:** Adhere to Prettier configuration (.prettierrc). Run npm run format before committing.
      - **Error Handling:** Log errors clearly on the backend. Provide user-friendly feedback on the frontend. Never expose raw backend errors to the user.
      
      ## 4. Key Limitations & Boundaries
      - Do not add new major dependencies without explicit approval.
      - Do not change the existing database schema without a migration plan discussed first.
      - Focus on the core task management features; avoid scope creep into calendar/collaboration features unless requested.
    • How to Use: Create this once per project. The AI should be instructed to treat this as its primary source for project-wide standards and tech stack info.

  2. ai_dynamic_task.md: The AI's Live Scratchpad & Playbook (Your Task Context)

    • Purpose: Manages the state, plan, rules, and log for the current specific task. The AI reads and updates this file continuously.
    • Example Structure & Content (Illustrative - AI populates most of this):

      # AI Dynamic Task State
      
      ## 1. Current Task Goal
      
      Implement a function addTask(taskName: string) on the backend service that adds a new task to the PostgreSQL database. Include basic validation (taskName cannot be empty).
      
      ## 2. Current State
      - Phase: Blueprint
      - Status: Generating Plan
      - Current Step: N/A
      - Blocked: No
      
      ## 3. The Plan
      
      1. Define the SQL query to insert a new task into the tasks table.
      2. Create a new function addTask(taskName: string) in src/services/taskService.ts.
      3. Inside addTask, validate that taskName is not empty or just whitespace. Throw an error if invalid.
      4. Execute the SQL INSERT query using the database connection pool.
      5. Return the newly created task ID or the task object.
      6. Add a corresponding route handler in src/controllers/taskController.ts that calls taskService.addTask.
      7. Write basic unit tests for addTask in src/services/taskService.test.ts.
      
      ## 4. Task-Specific Rules & Operations
      - **Validation:** Before implementing plan step 4 (database query), run npm run lint and fix any reported errors in the changed files.
      - **Testing:** After implementing plan step 7 (unit tests), run npm test src/services/taskService.test.ts and ensure tests pass.
      - **Error Handling:** If npm run lint or npm test fails, log the error output here and set Status to 'Blocked - Tooling Error'. Do not proceed until resolved or instructed.
      - **Completion:** Once all plan steps are done and validation/testing rules pass, set Phase to 'Validate' and Status to 'Completed'.
      
      ## 5. Log
      
      - [2025-04-18 14:30:05] Phase: Blueprint, Status: Generating Plan. Analyzing request.
      - [2025-04-18 14:31:10] Phase: Blueprint, Status: Needs Plan Approval. Generated plan above. Requesting user confirmation.
      - [2025-04-18 14:35:00] User approved plan. Phase: Construct, Status: Implementing Step 1. Defined SQL query...
      - [2025-04-18 14:38:22] Phase: Construct, Status: Implementing Step 2 & 3. Created function, added validation...
      - [2025-04-18 14:45:15] Phase: Construct, Status: Implementing Step 4. Ran npm run lint. No errors. Executing DB query...
      - ...
    • How to Use: You might create a template, but the AI populates/updates most sections during its work cycle. You monitor this file.

How the AI Uses These Files: The Read-Think-Act-Update Loop

This setup enables a more autonomous workflow:

  1. Read: AI checks ai_dynamic_task.md (current state, plan step, rules) and references ai_project_context.md for standards.
  2. Think (Interpret): Determines the next action based on the plan and rules (e.g., "Need to implement plan step 3," or "Rule says run linter now").
  3. Act: Executes the action (writes code, runs npm run lint in the terminal).
  4. Update: Records the action, outcome, and new state in ai_dynamic_task.md (updates Status, Phase, Log).
  5. Repeat: Continues the cycle.

Workflow Example (Simplified)

  1. You: "Add a backend function getTaskById(id)." (Provide initial prompt instructing use of the two files).
  2. AI: (Reads ai_project_context.md for DB/language info). Writes to ai_dynamic_task.md:
    • Task Goal: "Implement getTaskById(id)..."
    • State: Phase: Blueprint, Status: Generating Plan
    • Log: "Analyzing request..."
  3. AI: Writes to ai_dynamic_task.md:
    • Plan: (Steps like define SQL, create function, add route, write test...)
    • State: Phase: Blueprint, Status: Needs Plan Approval
    • Log: "Generated plan, requesting approval."
  4. You: "Plan approved."
  5. AI: Writes to ai_dynamic_task.md:
    • State: Phase: Construct, Status: Implementing Step 1
    • Log: "User approved. Implementing step 1..."
  6. AI: (Writes code for step 1). Writes to ai_dynamic_task.md:
    • State: Phase: Construct, Status: Implementing Step 2
    • Log: "Completed step 1. Starting step 2..."
  7. AI: (After writing tests for Step N, according to rules in ai_dynamic_task.md): Runs npm test ... via terminal.
  8. AI: Writes to ai_dynamic_task.md:
    • Log: "Ran tests. Output: [Test results]. Status: [Completed / Blocked]"
    • State: (Updates based on test results and rules).
  9. ...and so on until task completion.

Getting Started: Crucial Steps

  1. Create the Files: Make ai_project_context.md and ai_dynamic_task.md (or similar names) in your project, likely within an .ai/ directory.

  2. Define Project Context: Fill ai_project_context.md thoroughly. The better this is, the better the AI performs.

  3. Craft Your Initial Prompt: This is vital! When starting a new chat/task, you need to instruct the AI how to use these files. Example:

    "You are an expert AI programming assistant. Operate using the two-file system:

    1. ai_project_context.md: Contains stable project info (stack, standards). Refer to it always.
    2. ai_dynamic_task.md: Your dynamic workspace. You MUST read and update this file constantly. Use it to manage your State (Phase: Analyze, Blueprint, Construct, Validate; Status: Running, Blocked, Needs Plan Approval, Completed etc.), maintain the step-by-step Plan, follow Task-Specific Rules, and keep a detailed Log.

    Your workflow:

    • Analyze the request.
    • Enter Blueprint phase: Create a detailed Plan in ai_dynamic_task.md. Set Status to 'Needs Plan Approval' and wait for my confirmation before proceeding.
    • Enter Construct phase (after approval): Implement the Plan step-by-step, updating the State and Log in ai_dynamic_task.md. Follow any Rules defined there (e.g., running linters/tests).
    • Enter Validate phase: Perform final checks as defined by Rules. Set Status to 'Completed' when done.

    My first task: [Your actual task request here]"

  4. Assign Task & Monitor: Give the task and watch ai_dynamic_task.md to see the process unfold. Provide feedback or approval when the AI sets its status accordingly.

Tooling & Capabilities Check

Important: This pattern relies on your AI assistant's ability to:

  • Reliably read specific files in your workspace (ai_project_context.md, ai_dynamic_task.md).
  • Reliably edit or overwrite ai_dynamic_task.md to update its state, plan, and log.
  • Execute terminal commands if your rules require using tools like linters, testers, or formatters.

Verify if your specific tool (Cursor, Windsurf, etc.) supports these actions robustly. The effectiveness of the automation part (like running linters automatically) depends heavily on these capabilities. Even without full automation, using the files for structured context and planning is beneficial.

For Precision Control: Layering the PRECIS Protocol

If the autonomous loop feels too loose for critical code, enforce the PRECIS protocol (Phased Rigorous Execution & Controlled Interaction System) via your chat instructions:

  • [MODE: RESEARCH]: AI only reads files, asks questions.
  • [MODE: INNOVATE]: AI brainstorms ideas, pros/cons.
  • [MODE: PLAN]: AI creates the detailed checklist plan in ai_dynamic_task.md. Requires your "Plan Approved" signal.
  • [MODE: EXECUTE]: AI implements the plan from ai_dynamic_task.md exactly. Must stop and revert to PLAN mode if any deviation is needed. Requires your "ENTER EXECUTE MODE" command.
  • [MODE: REVIEW]: AI compares implementation against the plan in ai_dynamic_task.md, flags all differences.

How to Integrate:

  • During the AI's Blueprint phase (as per ai_dynamic_task.md), interact using [MODE: PLAN] prompts until the plan section is complete and approved by you.
  • Give the "ENTER EXECUTE MODE" command. The AI enters its Construct phase but operates under the strict [MODE: EXECUTE] rules, using the plan in ai_dynamic_task.md.
  • After the AI finishes construction, you might initiate [MODE: REVIEW] before allowing it to proceed to the Validate phase.

Wrapping Up

This two-file pattern (ai_project_context.md + ai_dynamic_task.md) provides a structured way to manage AI assistants in your coding workflow. It improves clarity, offers transparency through the dynamic task file, and opens the door for more reliable automation by embedding rules and state. By providing detailed context and clear operational instructions (especially the initial prompt), you can significantly improve the consistency and usefulness of your AI coding partner.

Experiment with this structure, tailor the file contents and rules to your needs, and see if it helps you collaborate more effectively with AI on your projects. Remember to check your specific tool's capabilities for file interaction and command execution. Good luck!