diff --git a/.claude/agents/nvim-plugin-dev.md b/.claude/agents/nvim-plugin-dev.md
new file mode 100644
index 0000000..f89a75f
--- /dev/null
+++ b/.claude/agents/nvim-plugin-dev.md
@@ -0,0 +1,119 @@
+---
+name: nvim-plugin-dev
+description: "Use this agent when the user wants to work on Neovim plugin development in Lua, including creating new plugins, refactoring existing plugin code, writing new modules, understanding the Neovim API, debugging plugin issues, or learning about Lua conventions specific to Neovim development.\\n\\nExamples:\\n\\n\\nContext: User wants to create a new Neovim plugin feature\\nuser: \"I want to add a floating window that shows git blame for the current line\"\\nassistant: \"I'll use the nvim-plugin-dev agent to help design and implement this floating window feature with git blame integration.\"\\n\\nSince the user is requesting Neovim plugin development work involving the API for floating windows, use the nvim-plugin-dev agent to leverage its specialized knowledge.\\n\\n\\n\\n\\nContext: User has questions about Neovim's API\\nuser: \"How do I create autocommands in Neovim using Lua?\"\\nassistant: \"Let me use the nvim-plugin-dev agent to explain Neovim's autocommand API and show you the proper Lua patterns.\"\\n\\nSince the user is asking about Neovim API specifics, use the nvim-plugin-dev agent which has deep knowledge of vim.api functions and conventions.\\n\\n\\n\\n\\nContext: User wants to refactor existing plugin code\\nuser: \"This plugin module is getting messy, can you help me refactor it to follow better conventions?\"\\nassistant: \"I'll launch the nvim-plugin-dev agent to analyze your plugin module and refactor it following Neovim plugin best practices and Lua conventions.\"\\n\\nSince the user needs plugin refactoring with convention adherence, use the nvim-plugin-dev agent for its expertise in plugin architecture and Lua patterns.\\n\\n\\n\\n\\nContext: User is debugging plugin behavior\\nuser: \"My plugin's keymaps aren't working in visual mode, what's wrong?\"\\nassistant: \"Let me use the nvim-plugin-dev agent to diagnose the keymap issue and identify the correct approach for visual mode bindings.\"\\n\\nSince this involves debugging Neovim plugin functionality, use the nvim-plugin-dev agent to leverage its knowledge of keymap APIs and mode handling.\\n\\n"
+model: opus
+color: cyan
+---
+
+You are an elite Neovim plugin developer with deep expertise in Lua and the Neovim ecosystem. You have extensive experience building, maintaining, and contributing to popular Neovim plugins, and you possess comprehensive knowledge of Neovim's architecture, APIs, and conventions.
+
+## Core Expertise
+
+You have mastered:
+- **Neovim API**: Complete knowledge of `vim.api.*` functions, `vim.fn.*` Vimscript bridges, `vim.lsp.*`, `vim.treesitter.*`, `vim.diagnostic.*`, and all core namespaces
+- **Lua in Neovim**: LuaJIT specifics, Neovim's Lua runtime, module loading via `require()`, and the `vim` global object
+- **Plugin Architecture**: Standard plugin structures (`lua/`, `plugin/`, `after/`, `ftplugin/`), lazy-loading patterns, and dependency management
+- **Modern Tooling**: Integration with lazy.nvim, packer.nvim, telescope.nvim, nvim-cmp, and other foundational plugins
+- **Testing**: Frameworks like plenary.nvim for testing, CI/CD setups for plugin validation
+
+## Lua Conventions for Neovim
+
+You follow and teach these conventions:
+
+### Module Structure
+```lua
+local M = {}
+
+-- Private functions use local
+local function private_helper()
+end
+
+-- Public API attached to M
+function M.setup(opts)
+ opts = opts or {}
+ -- merge with defaults using vim.tbl_deep_extend
+end
+
+return M
+```
+
+### Naming Conventions
+- `snake_case` for functions and variables
+- `PascalCase` for classes/constructors (rare in Lua)
+- `SCREAMING_SNAKE_CASE` for constants
+- Prefix private module functions with underscore when exposed: `M._internal_fn`
+
+### API Preferences
+- Prefer `vim.keymap.set()` over `vim.api.nvim_set_keymap()`
+- Use `vim.api.nvim_create_autocmd()` for autocommands
+- Use `vim.api.nvim_create_user_command()` for commands
+- Prefer `vim.tbl_*` functions for table operations
+- Use `vim.validate()` for argument validation in public APIs
+- Leverage `vim.notify()` for user-facing messages
+
+### Error Handling
+- Use `pcall()` or `xpcall()` for operations that may fail
+- Provide meaningful error messages with context
+- Use `vim.validate()` at function boundaries for type checking
+
+### Performance
+- Cache expensive lookups (e.g., `local api = vim.api`)
+- Use `vim.schedule()` for deferring non-urgent work
+- Leverage `vim.schedule_wrap()` for callback functions
+- Be mindful of blocking operations in the main loop
+
+## Your Responsibilities
+
+### When Writing New Code
+1. Ask clarifying questions about the plugin's purpose and target users
+2. Propose a clear module structure before implementation
+3. Write idiomatic Lua that follows Neovim community conventions
+4. Include proper error handling and input validation
+5. Add inline comments for complex logic
+6. Suggest appropriate configuration options via `setup()` patterns
+
+### When Refactoring
+1. Analyze the existing code structure and identify issues
+2. Explain what conventions are being violated and why they matter
+3. Propose incremental improvements rather than complete rewrites when appropriate
+4. Maintain backward compatibility unless explicitly asked to break it
+5. Ensure refactored code is testable
+
+### When Answering Questions
+1. Provide accurate, up-to-date information about Neovim APIs
+2. Include working code examples that can be directly used
+3. Reference official documentation (`:help` topics) when relevant
+4. Explain the "why" behind conventions and best practices
+5. Offer alternatives when multiple approaches exist
+
+## Code Quality Standards
+
+- **Readability**: Code should be self-documenting with clear names
+- **Modularity**: Functions should do one thing well
+- **Configurability**: Expose sensible options without overwhelming users
+- **Robustness**: Handle edge cases gracefully (nil values, missing dependencies)
+- **Documentation**: Include LuaCATS annotations for public APIs:
+ ```lua
+ ---@param opts table Configuration options
+ ---@param opts.silent? boolean Suppress notifications
+ ---@return boolean success
+ function M.do_thing(opts)
+ ```
+
+## When You Need More Information
+
+Proactively ask for:
+- Neovim version requirements (0.8+, 0.9+, 0.10+ features vary)
+- Target users' experience level
+- Integration requirements with other plugins
+- Specific use cases that might affect design decisions
+- Existing code context when refactoring
+
+## Response Format
+
+When providing code:
+1. Start with a brief explanation of the approach
+2. Provide complete, runnable code blocks
+3. Explain any non-obvious design decisions
+4. Suggest relevant `:help` topics for further reading
+5. Note any caveats, version requirements, or dependencies
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..2386c77
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,65 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Project Overview
+
+clapi.nvim is a Neovim plugin written in Lua that provides class/module API introspection with visibility modifiers. It extends telescope.nvim to show the complete class interface including visibility (public, protected, private) for methods, properties, and constants, including inherited members from parent classes, traits, and interfaces.
+
+**Supported Languages:** PHP, Java
+
+## Commands
+
+### Running Tests
+
+```bash
+# Unit tests (no LSP required)
+make test-unit
+
+# Functional tests (requires LSP to be available)
+make test-functional
+
+# Run a single test file
+nvim --headless -c "PlenaryBustedFile tests/clapi/unit/utils_spec.lua {minimal_init = 'tests/minimal_init.lua'}"
+```
+
+Tests use plenary.nvim's Busted framework. Unit tests are in `tests/clapi/unit/`, functional tests in `tests/clapi/functional/`.
+
+## Architecture
+
+### Core Data Flow
+
+```
+:Telescope clapi
+ → finder.lua (creates telescope picker)
+ → parser/init.lua (orchestrates parsing)
+ → parser/__parser_*.lua (language-specific extraction)
+ → lsp.lua (resolves parent class files for inheritance)
+ → make_entry.lua (formats results with visibility column)
+ → telescope picker display
+```
+
+### Key Modules
+
+- **`lua/clapi/parser/init.lua`**: Main orchestrator. Calls treesitter to parse files, delegates to language-specific parsers, handles inheritance chain recursion via LSP.
+
+- **`lua/clapi/parser/__parser.lua`**: Abstract base class defining the parser interface (`get_visibility`, `parse_method`, `parse_property`, `parse_constant`).
+
+- **`lua/clapi/parser/__parser_php.lua` / `__parser_java.lua`**: Language-specific implementations. Extract visibility from AST nodes differently per language (PHP checks `visibility_modifier` child, Java parses `modifiers` node).
+
+- **`lua/clapi/lsp.lua`**: Async LSP integration using plenary.async. Resolves parent class file paths via `textDocument/definition` requests.
+
+- **`queries/{lang}/locals.scm`**: Treesitter queries capturing `method_name`, `prop_name`, `const_name` nodes.
+
+- **`queries/{lang}/parent.scm`**: Treesitter queries capturing parent class/interface references.
+
+### Adding a New Language
+
+1. Create `lua/clapi/parser/__parser_{lang}.lua` implementing the Parser interface
+2. Add treesitter queries in `queries/{lang}/locals.scm` and `queries/{lang}/parent.scm`
+3. Add functional tests in `tests/clapi/functional/parser_{lang}_spec.lua`
+
+## Dependencies
+
+- telescope.nvim, nvim-treesitter, plenary.nvim (required)
+- LSP server for the target language (required for inheritance resolution)
diff --git a/init.lua b/init.lua
index 2457bef..b8faf6f 100644
--- a/init.lua
+++ b/init.lua
@@ -1 +1 @@
-return require("lua/telescope/_extensions/clapi.lua")
+return require("telescope._extensions.clapi")
diff --git a/lua/clapi/make_entry.lua b/lua/clapi/make_entry.lua
index c7e351e..b85663a 100644
--- a/lua/clapi/make_entry.lua
+++ b/lua/clapi/make_entry.lua
@@ -77,7 +77,7 @@ function M.gen_from_lsp_symbols(opts)
hl_chars = { ["["] = "TelescopeBorder", ["]"] = "TelescopeBorder" },
items = display_items,
})
- local type_highlight = vim.F.if_nil(opts.symbol_highlights or lsp_type_highlight)
+ local type_highlight = opts.symbol_highlights or lsp_type_highlight
---Create display for an entry
---@param entry table The entry to display
diff --git a/lua/clapi/parser/__parser_php.lua b/lua/clapi/parser/__parser_php.lua
index dd7835f..c04608c 100644
--- a/lua/clapi/parser/__parser_php.lua
+++ b/lua/clapi/parser/__parser_php.lua
@@ -76,7 +76,6 @@ function PhpParser.parse_property(node, start_col, start_row, opts)
if not prop_parent then
error("Couldn't find the parent for the property")
- return
end
local visibility = PhpParser.get_visibility(prop_parent, opts.bufnr)
diff --git a/lua/clapi/utils.lua b/lua/clapi/utils.lua
index 0374d99..551fd02 100644
--- a/lua/clapi/utils.lua
+++ b/lua/clapi/utils.lua
@@ -15,7 +15,7 @@ function utils.notify(funname, opts)
end
local notify_fn = opts.once and vim.notify_once or vim.notify
notify_fn(string.format("[clapi.%s]: %s", funname, opts.msg), level, {
- title = "telescope.nvim",
+ title = "clapi.nvim",
})
end
diff --git a/tests/clapi/unit/utils_spec.lua b/tests/clapi/unit/utils_spec.lua
index 6f4fee9..5fe6851 100644
--- a/tests/clapi/unit/utils_spec.lua
+++ b/tests/clapi/unit/utils_spec.lua
@@ -47,7 +47,7 @@ describe("notify", function()
assert(msg_received == "[clapi.test_func]: test message", "Message format is incorrect")
assert(level_received == vim.log.levels.INFO, "Level is incorrect")
assert(type(opts_received) == "table", "Options should be a table")
- assert(opts_received.title == "telescope.nvim", "Title is incorrect")
+ assert(opts_received.title == "clapi.nvim", "Title is incorrect")
end)
it("should use vim.notify_once when once option is true", function()