CategoriesProjects

Java Code Navigator: Making Java Code Navigation Easier in VS Code

As we recently started transitioning from IntelliJ IDEA to VS Code and its derivatives like Cursor and Windsor, one thing became immediately apparent: navigating through Java code just wasn't as smooth as we were used to. The lack of quick access to implementations, references, and hierarchies was slowing us down.

So I decided to build a solution.

Introducing Java Code Navigator

Today I'm excited to share Java Code Navigator, a VS Code extension that brings familiar Java navigation capabilities right into your editor through convenient CodeLens actions.

Java Code Navigator in action

If you've ever found yourself missing the ease of jumping between interfaces and implementations or exploring call hierarchies in VS Code, this extension is for you.

The Problem: Navigation Friction

When our team started using VS Code for Java development, we immediately noticed the friction:

  • Right-clicking and selecting "Go to Implementation" felt clunky compared to IntelliJ's one-click navigation
  • Finding all references to a method required multiple steps
  • Exploring type hierarchies wasn't as accessible
  • Performing refactoring operations took more effort

These small frictions added up to a significant productivity hit, especially for those of us who were used to the fluid navigation experience in IntelliJ.

CategoriesAI

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

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.

CategoriesAISystem Design

Building a Semantic Code Intelligence Tool: RAG in Your IDE

As a senior developer working on large codebases, I've often found myself struggling with challenges that go beyond just finding specific files. Understanding how components interact, documenting complex systems, or onboarding new team members can be incredibly time-consuming tasks that pull me away from actual coding.

These challenges led me to explore how modern AI techniques could enhance developer workflows right where we spend most of our time - in the IDE. In this post, I'll share my journey building CodeCompass, a code intelligence tool that integrates Retrieval-Augmented Generation (RAG) directly into your development environment, using both cloud and local Large Language Models (LLMs) to provide semantic understanding of codebases.

VS Code Extension

Why We Need Better Code Intelligence Tools

Let me start with a common scenario: you join a new project with hundreds of thousands of lines of code spread across multiple modules. You need to understand:

  • How different components interact
  • Where specific business logic is implemented
  • How to properly extend the system with new features
  • What architectural patterns are used

Traditional approaches to these problems have significant limitations:

  • Documentation is often outdated or incomplete
  • You need to context-switch between your IDE and external tools
  • Understanding architectural decisions requires finding the right people to ask
  • Generating documentation is tedious and rarely prioritized

I wanted a tool that would understand the codebase at a conceptual level and provide insights directly within my development workflow.

From Search to Conversation: The Evolution of CodeCompass

CodeCompass began as a semantic code search tool for IntelliJ, but has evolved into a comprehensive code intelligence platform with:

  1. Semantic Code Search: Find relevant files based on natural language queries
  2. Interactive Chat: Have conversations about your codebase with context from previous questions
  3. Question Answering: Ask specific questions about code functionality and get detailed explanations
  4. Multi-IDE Support: Now available for both IntelliJ IDEA and Visual Studio Code
  5. Multiple AI Provider Options: Support for cloud-based services (OpenRouter, Google Gemini) and local models (Ollama)

The key insight driving this evolution was that developers need more than just search - they need a conversational interface that can maintain context and provide nuanced explanations about complex codebases.