plugins/odoo-doodba-dev/skills/odoo-indexer/SKILL.md
--- name: Odoo Indexer description: Fast indexer for Odoo codebases - 95% more token-efficient than reading files. USE AUTOMATICALLY AND PROACTIVELY before ANY Odoo code work. AUTO-TRIGGER when user mentions models (sale.order, res.partner, account.move, etc.), fields (partner_id, name, state, etc.), views (form, tree, kanban), XML IDs, or when you need to search/validate/explore Odoo code. USE BEFORE writing code to validate references exist, USE BEFORE reading files to locate elements, USE DUR
npx skillsauth add letzdoo/claude-marketplace plugins/odoo-doodba-dev/skills/odoo-indexerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
⚡ PROACTIVE USAGE: This skill should be used automatically when user asks questions about Odoo code structure, models, fields, views, or modules.
Fast indexing and search for Odoo codebase elements with sub-100ms query performance.
✅ User asks: "What is sale.order?"
→ AUTO-USE: uv run scripts/get_details.py model "sale.order"
✅ User asks: "What fields does res.partner have?"
→ AUTO-USE: uv run scripts/get_details.py model "res.partner"
✅ User asks: "Find all Many2one fields in sale module"
→ AUTO-USE: uv run scripts/search_by_attr.py field --filters '{"field_type":"Many2one"}' --module sale
✅ User asks: "Where is project.task defined?"
→ AUTO-USE: uv run scripts/search.py "project.task" --type model
✅ User asks: "Does sale.order have partner_id field?"
→ AUTO-USE: uv run scripts/search.py "partner_id" --type field --parent "sale.order"
✅ User asks: "Search for task views"
→ AUTO-USE: uv run scripts/search.py "%task%" --type view
✅ User asks: "List all modules"
→ AUTO-USE: uv run scripts/list_modules.py
✅ User asks: "Tell me about the sale module"
→ AUTO-USE: uv run scripts/module_stats.py sale
Automatically use this skill when user query contains:
This skill requires uv (Python package manager). Usually auto-installed by /odoo-setup.
Manual install (if needed):
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or via Homebrew (macOS)
brew install uv
Environment variables (optional - auto-detected by skill):
export ODOO_PATH="$HOME/letzdoo-sh/odoo/custom/src" # Auto-detected if not set
export SQLITE_DB_PATH="$HOME/.odoo-indexer/odoo_indexer.sqlite3" # Default location
The skill auto-detects common Odoo locations:
$ODOO_PATH (if set)/home/coder/letzdoo-sh/odoo/custom/src$HOME/odoo/custom/src./odoo/custom/srcAutomatic (via /odoo-setup command):
Manual (if index not built):
cd odoo-doodba-dev/skills/odoo-indexer
uv run scripts/update_index.py --full
Expected output:
Starting full index rebuild...
Scanning modules... Found 156 modules
Indexing: odoo (core) ████████████ 100%
Indexing: sale ████████████ 100%
...
✓ Indexing complete!
Summary:
- Modules: 156
- Models: 1,247
- Fields: 15,832
Database size: 42.3 MB
Indexing time:
All commands use uv run from the skills/odoo-indexer/ directory:
# Search models
uv run scripts/search.py "sale.order" --type model
# Search fields in a module
uv run scripts/search.py "partner_id" --type field --module sale
# Search with wildcards (supports SQL LIKE patterns)
uv run scripts/search.py "action_view_%" --type action
# Limit results for performance
uv run scripts/search.py "sale%" --type model --limit 10
Parameters:
query: Search term (supports % wildcards)--type: Element type (model/field/function/view/action/menu)--module: Filter by module name--parent: Filter by parent (e.g., model name for fields)--limit: Max results (default: 20)--offset: Pagination offset (default: 0)--json: Output as JSONPerformance: <50ms for exact match, <100ms for wildcard search
Get complete information about a specific element:
# Model details (all fields, methods, views, actions)
uv run scripts/get_details.py model "sale.order"
# Field details (type, attributes, usage)
uv run scripts/get_details.py field "partner_id" --parent "sale.order"
# View details (structure, inheritance)
uv run scripts/get_details.py view "sale_order_form_view" --module sale
Returns:
Performance: <30ms
# List all indexed modules
uv run scripts/list_modules.py
# Filter by pattern
uv run scripts/list_modules.py --pattern "sale*"
Returns:
# Detailed module info
uv run scripts/module_stats.py sale
Returns:
Find all locations where an element is used:
# Find all references to a model
uv run scripts/find_refs.py model "sale.order"
# Find field references
uv run scripts/find_refs.py field "partner_id" --ref-type definition
Reference types:
definition - Where element is definedinheritance - Where element is inheritedoverride - Where element is overriddenreference - Where element is referencedAdvanced search using element attributes:
# Find all Many2one fields
uv run scripts/search_by_attr.py field --filters '{"field_type": "Many2one"}'
# Find transient models
uv run scripts/search_by_attr.py model --filters '{"model_type": "transient"}' --module sale
# Find form views
uv run scripts/search_by_attr.py view --filters '{"view_type": "form"}'
# Combine filters
uv run scripts/search_by_attr.py field --filters '{"field_type": "Many2one", "required": true}' --module sale
Common filters:
field_type, required, readonly, compute, storemodel_type (model/transient/abstract), inheritview_type (form/list/search/kanban/calendar/pivot/graph)# Search XML IDs with wildcards
uv run scripts/search_xml_id.py "action_view_%"
# Exact XML ID in module
uv run scripts/search_xml_id.py "sale_order_form_view" --module sale
Returns:
Important: Always use the full XML ID returned (with module prefix) in ref() calls.
Keep the index up-to-date with code changes:
# Incremental update (fast - only changed files)
uv run scripts/update_index.py
# Full rebuild (slow - all files)
uv run scripts/update_index.py --full
# Index specific modules
uv run scripts/update_index.py --modules "sale,account,stock"
# Clear and rebuild
uv run scripts/update_index.py --clear --full
When to update:
Performance:
Check index health and statistics:
uv run scripts/index_status.py
Returns:
| Operation | Time | vs File Reading | |-----------|------|-----------------| | Exact model search | <20ms | 50x faster | | Field lookup | <30ms | 30x faster | | Wildcard search | <100ms | 20x faster | | Module stats | <50ms | 40x faster | | Reference search | <150ms | 15x faster |
Token efficiency: 95% fewer tokens than reading files
# Good - specific
uv run scripts/search.py "sale.order" --type model
# Also good - controlled wildcard
uv run scripts/search.py "sale.%" --type model --limit 10
# Avoid - too broad (slow)
uv run scripts/search.py "%" --type model # Returns thousands of results
Always use --limit for wildcard searches:
uv run scripts/search.py "%partner%" --type field --limit 20
Use specific filters to narrow results:
uv run scripts/search.py "partner_id" --type field --parent "sale.order" --limit 1
For frequently accessed info, mention you're using cached data:
I've already looked up sale.order (from indexer cache).
Exact searches are much faster:
# Fast
uv run scripts/get_details.py model "sale.order"
# Slower
uv run scripts/search.py "%sale.order%" --type model
Query: "What is sale.order?"
Command:
uv run scripts/get_details.py model "sale.order"
Response format:
Query: "What fields does res.partner have?"
Command:
uv run scripts/get_details.py model "res.partner"
Response format:
Query: "Find all Many2one fields pointing to res.partner"
Command:
uv run scripts/search_by_attr.py field --filters '{"field_type": "Many2one", "comodel_name": "res.partner"}' --limit 50
Response format:
Error: Database file not found
Solution:
cd odoo-doodba-dev/skills/odoo-indexer
uv run scripts/update_index.py --full
Or run /odoo-setup to rebuild everything.
Error: Odoo directory not found
Solution:
# Set correct path
export ODOO_PATH="/path/to/your/odoo/custom/src"
# Verify
ls $ODOO_PATH/odoo # Should show Odoo core files
# Rebuild index
uv run scripts/update_index.py --full
Issue: Search returns outdated information
Solution:
# Quick update (incremental)
uv run scripts/update_index.py
# Full rebuild if issues persist
uv run scripts/update_index.py --full
Issue: Searches taking >1 second
Causes:
--limit)--full)Solution:
# Add limit
uv run scripts/search.py "%" --type model --limit 10
# Or rebuild index
uv run scripts/update_index.py --clear --full
Error: ModuleNotFoundError: lxml
Solution:
cd odoo-doodba-dev/skills/odoo-indexer
uv sync # Auto-installs from pyproject.toml
/odoo-searchThe /odoo-search command is a user-friendly wrapper around this skill:
odoo-developer agent:
odoo-verifier agent:
Before using any model/field/XML ID in code:
# Verify model exists
uv run scripts/search.py "custom.model" --type model
# Verify field exists
uv run scripts/search.py "custom_field" --type field --parent "custom.model"
# Verify XML ID exists
uv run scripts/search_xml_id.py "custom_action" --module custom
Always use exact names from indexer (don't guess):
# Get exact field name
uv run scripts/get_details.py field "partner" --parent "sale.order"
# Returns: partner_id (not "partner")
Always use module prefix from indexer for XML IDs:
uv run scripts/search_xml_id.py "action_view_task"
# Returns: project.action_view_task
# Use: ref('project.action_view_task') # Correct
# NOT: ref('action_view_task') # Wrong
For multiple elements, batch searches:
# Instead of multiple calls, use one search
uv run scripts/search.py "partner_id|user_id|team_id" --type field --parent "sale.order"
Update index regularly:
# Daily incremental update
uv run scripts/update_index.py
# Weekly full update
uv run scripts/update_index.py --full
When agents use this skill:
get_details.py for comprehensive infosearch.py for finding elementssearch_by_attr.py for filtered searchesLocation: ~/.odoo-indexer/odoo_indexer.sqlite3 (default)
Size: 10-50 MB (varies with codebase size)
Schema:
modules - Module metadatamodels - Model definitionsfields - Field definitionsviews - View definitionsactions - Action definitionsmenus - Menu structurexml_ids - XML ID mappingsreferences - Cross-referencesIndexed data:
Remember: This skill should be your FIRST choice for any Odoo code exploration. It's 95% faster and more accurate than reading files!
tools
Core OTK engine: Rust CLI proxy, output filters, token tracking, and analytics. This skill provides the `otk` binary and all 12 filter strategies. AUTO-TRIGGER: Used automatically via PreToolUse hook - no manual invocation needed. Performance: <10ms startup, <5MB binary, <5MB memory. Written in Rust like RTK.
tools
OTK (Odoo Token Killer) - Reduce token consumption by 60-90% on Odoo development operations. Inspired by RTK (Rust Token Killer) by the rtk-ai team. AUTO-USE when running Bash commands during Odoo development. The PreToolUse hook handles transparent rewriting automatically. For manual use, prefix commands with `otk`: otk invoke test my_module → test failures only (90% savings) otk docker compose logs odoo → errors/warnings only (90% savings) otk git status → compact stats (80% savings) otk read models/sale.py → signatures + fields only (60% savings) otk read views/sale_view.xml → structure only (70% savings) otk gain → token savings dashboard Compatible with: odoo-doodba-dev, odoo-development, odoo-query plugins.
data-ai
Connect to Odoo instances via XML-RPC for read-only queries to investigate issues and explore data. Use when user asks to "query odoo", "connect to odoo", "investigate odoo data", "read odoo records", or needs to explore an Odoo instance.
development
MUST be loaded when ANY Odoo development task is detected. CRITICAL: Claude MUST use this skill for ALL tasks involving: - "odoo", "module", "model", "view", "field", "OWL", "manifest" - ANY mention of Odoo versions (14, 15, 16, 17, 18, 19) - "create odoo module", "generate odoo code", "review odoo module" - "upgrade odoo", "odoo best practices", "odoo security" ALWAYS trigger the odoo-context-gatherer agent BEFORE writing ANY Odoo code.