The Codebase Index CLI Journey: A Human Story
Leer en Español | Read in English
The Codebase Index CLI Journey: A Human Story
Video Overview (Early Preview)
Disclaimer: This recording walks through the earliest versions of the project and runs for quite a while. I recommend opening it on YouTube so you can use timestamps and jump straight to the sections that matter most to you.
The Birth: Spotting a Real Need
This project started from direct observation while working with AI tools like Claude Code, Cline, and Codex. Unlike Cursor, which has built-in semantic search, these tools struggle with large codebases. They miss relevant code scattered across multiple files, can't understand the broader context of a project. The need was clear: I needed a semantic context engine that any AI assistant could use.
I started in mid-October with a simple idea: a CLI tool for semantic code indexing outside of VS Code, reusing some concepts from Roo Code's semantic index infrastructure. At that moment, I already understood the core architecture needed: directory scanning, code chunking, embedding generation, and storage in vector stores.
Early Steps: Configuration and Usability
The first days were about basic setup. The initial version was functional but hard to use. It required manual JSON configuration, no environment variables, no installer.
The first big learning came quickly: people don't want to configure complex JSONs. I learned that: - Configuration via .env is much more accessible - Users need automatic installers - Legacy data migration must be transparent - Real-time feedback is crucial (watchers, detailed logging)
This massive refactor completely transformed the user experience. Suddenly, the CLI was a tool anyone could install and use.

The CLI in action: codebase start . configuring workspace, embedder, and starting the initial scan
Identity Shift: From "roo-index-cli" to "codebase-index-cli"
An important learning about branding came early: the name "roo-index-cli" tied the project to "Roo Code", limiting adoption. I learned that generalization is power. Changing to "codebase-index-cli" made the project more generic and accessible, while maintaining legacy name compatibility.
SQLite-vec: Discovering Flexibility
A few days in, I hit a realization. Until then, I only supported Qdrant, which requires a running server. I learned that not all users want or can run external services.
That day I did three things: 1. Made a backup before implementing SQLite-vec - caution learned from past experiences 2. Integrated SQLite-vec - now users could choose between local (SQLite) or scalable (Qdrant) 3. Created testing scripts - I learned the importance of debugging tools
This change revealed something crucial: users need options. Small projects want SQLite, large projects Qdrant. Giving them the choice with the same CLI was powerful.
Tree-sitter: The Semantic Quality Jump
The tree-sitter integration was a moment of technical maturation. I learned that regex-based chunking was limited. Tree-sitter enables: - Real semantic parsing of 29+ languages - Exact extraction of definitions (functions, classes) - AST understanding of code
But I also learned about WASM memory fragmentation the hard way. Parsers would crash after processing many files. The solution: parser cache + reset every 100 files. Key learning: WASM memory isn't automatically managed, you have to be proactive.
Internationalization and Documentation
A few days into the project, I focused on accessibility: - Complete translation to English - Emoji removal (professionalism) - Shields.io badges (open source standards) - Exhaustive troubleshooting documentation
I learned that code without good documentation is inaccessible code. The troubleshooting sections I added weren't just documentation, they were the result of seeing real users encountering problems: - Dimension mismatches - Embedder requirements (OpenAI-compatible only) - Git tracking only in Qdrant - Performance tuning
Git Commit Tracking: The Experimental Feature
Commit tracking became the most ambitious learning experiment:
The problem: Commit history is lost institutional knowledge. Why was this change made? What decisions led to this code?
The solution: 1. A .git watcher that detects new commits 2. Metadata extraction, diffs, statistics 3. LLM analysis of the commit (the key conceptual leap) 4. Qdrant indexing for semantic search
Technical learnings: - Batch processing is crucial - processing commits one by one was inefficient - LLM analysis caching - don't reanalyze already processed commits - Retroactive indexing - users want to index past history, not just future commits
This feature did something unique: turn commit history into searchable knowledge.

Retroactive commit indexing: codebase -index-history 100 analyzing 100 historical commits with LLM
Vector Store-Specific Configuration: The Flexibility Insight
A mature learning emerged: different vector stores have different needs. Why use the same embedder for local SQLite and production Qdrant?
The solution: store-specific configuration:
# SQLite uses small/cheap model
SQLITE_EMBED_MODEL=text-embedding-3-small
# Qdrant uses large/precise model
QDRANT_EMBED_MODEL=Qwen/Qwen3-Embedding-8B
I learned that well-designed flexibility multiplies a tool's value.
Claude Code Integration: Closing the Circle
The Claude Code integration closed the circle: - Auto-start with SessionStart hook - Real-time status line - Zero-config experience
I learned that tools must integrate seamlessly into the user's workflow. It's not enough for them to work, they must be invisible until needed.
Cross-Platform: Thinking About Community
The multiplatform installers were a learning about community: if you want broad adoption, reduce setup friction to the maximum. Although macOS/Windows aren't tested, providing the scripts invites contribution.
Semantic Search CLI: The Complete Tool
Adding a dedicated semantic search command with Voyage AI reranking was learning that ad-hoc queries are valuable. You don't always want a UI, sometimes you just want:
Final Lessons: Observation and Continuous Improvement
Recent refinements show how real usage teaches you: - Process locks to prevent multiple instances - Duration reporting in minutes (not seconds) - Memory fragmentation fixes
I learned that software is never "finished". Every real use reveals something new to improve.
Why CLI + MCP Instead of Native Integration?
This is an experimental project, but one that each user can perfectly adapt to their needs. It's not like they're retraining a model, but they can adjust it as much as they want. That's why it's open source - you can use the models you prefer and tweak it to your taste.
Embedding it in a system didn't make much sense. Codex or Claude CLI are proprietary systems, but beyond that, there are many other CLIs that don't have an integrated contextual database. Even Cline itself, which is excellent, still works without semantic search for reasons its creators understand are better. But with this, there's the possibility to experiment a bit more, without needing to break what already exists - simply test, adjust, use, and see results.
I'm not writing this with the intention of saying this will change the world or the way you program, but it can help you customize things and learn about AI agents, because along the way you learn many things about the entire environment.
The project has been tested on agents like Gemini CLI, Aider, OpenCode, Codex, Qwen Code, Cline, Droid with good results, and it will work with all agents. Just in some, it may not be as relevant since they have their own context engine, but it's worth trying. It's important to mention that tool adoption depends a lot on the prompt, as that's important for the agent to take the tool as a natural part of its processes and you don't have to keep reminding it to use it.
Part 3: The Extension That Closes the Cycle
Here's the story of when I found claude-code-chat by André Pimenta, which I modified to use the indexer directly integrated into the extension. My enhanced version is available at claude-code-chat-ui, compatible with the Codebase Index CLI. Since it's a particular use case, I preferred to fork and modify it for CLI use, but it's a great extension everyone should try from its original author.
Fork Objective
Integrate the local indexer (codebase-index-cli) directly into the extension, with UI control, visible state, and clear flow documentation. Also, prepare ground for subagent parallelization and improve repo hygiene for indexer artifacts.
Key Integration Changes
Indexer controls in UI: Start, Stats, History, Full reset; live status badge; tooltips and disabled logic based on state.
Periodic reading of .codebase/state.json to reflect state (watching/indexing/idle/error) and update badge/warnings.
"Indexing" warning prioritized over YOLO mode for clearer UX while indexer works.
CLI configuration: new setting for codebase CLI path (claudeCodeChat.codebase.path).
Session safety: block "New Chat" while agents are processing to avoid "poison" from overlap.
Parallelization toggle (Subagents) for next message (prepared/documented and wired in UI).
Repository Hygiene for the Indexer
Ignore local and sensitive artifacts: .codebase/, .env, agents_messaging.db; add env.example.
Documentation and Fork Purpose
README/CHANGELOG/TEST_SETTINGS updated with: indexer integration, badge UX, parallelization toggle, and message prepend notes.
Fork notice with credits and link to codebase-index-cli README, explaining this fork supports that flow and customizations.
How the Fork Makes the Ecosystem More Complete
- End-to-end indexer control from the extension (without leaving VS Code)
- Real-time indexing state visibility and safe UX during operations (badge + warnings)
- Consistent onboarding via env.example and .gitignore that avoids garbage/sensitives in git
- Prepared for parallel subagent work, aligned with indexer-supported flows
- Explicit indexer + fork flow documentation, facilitating adoption and contribution
My Setup
VSCodium + customized Claude Code to consume GPT-5 and Codex in addition to native Claude-Sonnet-4 and Claude-Sonnet-4.5, Codebase Index CLI, Semantic Search MCP, claude.md or agents.md prompt in Codex, and extension to use Claude Code and better view indexing stats in VSCodium.
Final Reflections
This project taught me:
- Start simple, iterate fast: The initial commit was basic, but it worked. Complexity came later, when I understood it better.
- Users teach you: Each feature (SQLite-vec, tree-sitter, git tracking) came from observing real needs.
- Configuration is UX: Moving from JSON to .env, creating installers, allowing per-vector-store configuration - all this was learning that configuration is part of user experience.
- Documentation is development: The 200+ troubleshooting lines aren't "extra documentation", they're knowledge distilled from real problems.
- Code without context is lost code: Git commit tracking with LLM isn't just a cool feature, it's preserving the "why" of code.
- Well-designed flexibility wins: SQLite vs Qdrant, different embedders, optional tree-sitter - giving users options is respecting them.
This project started as a personal need and evolved into a tool any developer using AI assistants can leverage. It's not perfect, but it's useful, and that's the metric that matters.
La Historia de Codebase Index CLI: Un Viaje Humano
Video resumen (versiones iniciales)
Aviso: Este video muestra las primeras versiones del proyecto y es bastante extenso. Te recomiendo abrirlo directamente en YouTube para aprovechar las marcas de tiempo y revisar solo los apartados que necesites.
El Nacimiento: Detectando una Necesidad Real
Este proyecto nació de una observación directa mientras trabajaba con herramientas de IA como Claude Code, Cline y Codex. A diferencia de Cursor, que tiene búsqueda semántica integrada, estas herramientas luchan con codebases grandes. Se pierden código relevante disperso en múltiples archivos, no pueden entender el contexto más amplio de un proyecto. La necesidad era clara: necesitaba un motor de contexto semántico que cualquier asistente de IA pudiera usar.
Empecé a mediados de octubre con una idea simple: una herramienta CLI para indexación semántica de código fuera de VS Code, reutilizando algunos conceptos de la infraestructura de índice semántico de Roo Code. En ese momento, ya entendía la arquitectura core que necesitaba: escaneo de directorios, chunking de código, generación de embeddings, y almacenamiento en vector stores.
Primeros Pasos: Configuración y Usabilidad
Los primeros días fueron de configuración básica. La versión inicial era funcional pero difícil de usar. Requería configuración manual via JSON, sin variables de entorno, sin instalador.
El primer gran aprendizaje llegó rápido: la gente no quiere configurar JSONs complejos. Aprendí que: - La configuración via .env es mucho más accesible - Los usuarios necesitan instaladores automáticos - La migración de datos legacy debe ser transparente - El feedback en tiempo real es crucial (watchers, logging detallado)
Este refactor masivo transformó completamente la experiencia de usuario. De repente, el CLI era una herramienta que cualquiera podía instalar y usar.

El CLI en acción: codebase start . configurando workspace, embedder, e iniciando el escaneo inicial
El Cambio de Identidad: De "roo-index-cli" a "codebase-index-cli"
Un aprendizaje importante sobre branding llegó temprano: el nombre "roo-index-cli" ataba el proyecto a "Roo Code", limitando su adopción. Aprendí que la generalización es poder. Cambiar a "codebase-index-cli" hizo que el proyecto fuera más genérico y accesible, manteniendo compatibilidad con el nombre legacy.
SQLite-vec: El Descubrimiento de la Flexibilidad
A los pocos días, llegué a una realización. Hasta entonces, solo soportaba Qdrant, que requiere un servidor corriendo. Aprendí que no todos los usuarios quieren o pueden correr servicios externos.
Ese día hice tres cosas: 1. Hice un backup antes de implementar SQLite-vec - precaución aprendida de experiencias pasadas 2. Integré SQLite-vec - ahora los usuarios podían elegir entre local (SQLite) o escalable (Qdrant) 3. Creé scripts de testing - aprendí la importancia de herramientas de debugging
Este cambio reveló algo crucial: los usuarios necesitan opciones. Proyectos pequeños quieren SQLite, proyectos grandes Qdrant. Darles la elección con el mismo CLI era poderoso.
Tree-sitter: El Salto de Calidad Semántica
La integración de tree-sitter fue un momento de maduración técnica. Aprendí que el chunking basado en regex era limitado. Tree-sitter permite: - Parsing semántico real de 29+ lenguajes - Extracción de definiciones exactas (funciones, clases) - Comprensión del AST del código
Pero también aprendí sobre fragmentación de memoria WASM de la forma difícil. Los parsers crasheaban después de procesar muchos archivos. La solución: cache de parsers + reset cada 100 archivos. Aprendizaje clave: la memoria WASM no se gestiona automáticamente, hay que ser proactivo.
Internacionalización y Documentación
Unos días después del proyecto, me enfoqué en accesibilidad: - Traducción completa a inglés - Eliminación de emojis (profesionalismo) - Shields.io badges (estándares de open source) - Documentación exhaustiva de troubleshooting
Aprendí que el código sin buena documentación es código inaccesible. Las secciones de troubleshooting que agregué no fueron solo documentación, fueron el resultado de ver a usuarios reales encontrando problemas: - Dimension mismatches - Embedder requirements (solo OpenAI-compatible) - Git tracking solo en Qdrant - Performance tuning
Git Commit Tracking: La Característica Experimental
El tracking de commits se convirtió en el experimento de aprendizaje más ambicioso:
El problema: El historial de commits es conocimiento institucional perdido. ¿Por qué se hizo este cambio? ¿Qué decisiones llevaron a este código?
La solución: 1. Un watcher de .git que detecta nuevos commits 2. Extracción de metadata, diffs, estadísticas 3. Análisis LLM del commit (el salto conceptual clave) 4. Indexación en Qdrant para búsqueda semántica
Aprendizajes técnicos: - Batch processing es crucial - procesar commits uno por uno era ineficiente - Cache de análisis LLM - no reanalizar commits ya procesados - Indexación retroactiva - los usuarios quieren indexar historia pasada, no solo futuros commits
Este feature hizo algo único: convertir commit history en conocimiento búsqueda.

Indexación retroactiva de commits: codebase -index-history 100 analizando 100 commits históricos con LLM
Configuración por Vector Store: El Insight de Flexibilidad
Emergió un aprendizaje maduro: diferentes vector stores tienen diferentes necesidades. ¿Por qué usar el mismo embedder para SQLite local y Qdrant production?
La solución: configuración específica por vector store:
# SQLite usa modelo pequeño/barato
SQLITE_EMBED_MODEL=text-embedding-3-small
# Qdrant usa modelo grande/preciso
QDRANT_EMBED_MODEL=Qwen/Qwen3-Embedding-8B
Aprendí que la flexibilidad bien diseñada multiplica el valor de una herramienta.
Integración con Claude Code: El Círculo Completo
La integración con Claude Code cerró el círculo: - Auto-start con SessionStart hook - Status line en tiempo real - Zero-config experience
Aprendí que las herramientas deben integrarse perfectamente en el flujo del usuario. No basta con que funcionen, deben ser invisibles hasta que se necesiten.
Cross-Platform: Pensando en Comunidad
Los instaladores multiplataforma fueron un aprendizaje sobre comunidad: si quieres adopción amplia, reduce fricción de setup al máximo. Aunque macOS/Windows no están testeados, proporcionar los scripts invita a la contribución.
Semantic Search CLI: La Herramienta Completa
Agregar un comando dedicado de búsqueda semántica con reranking de Voyage AI fue aprender que ad-hoc queries son valiosas. No siempre quieres una UI, a veces solo quieres:
Lecciones Finales: Observación y Mejora Continua
Los refinamientos recientes muestran cómo el uso real te enseña: - Process locks para prevenir múltiples instancias - Reporting de duración en minutos (no segundos) - Fixes de memory fragmentation
Aprendí que el software nunca está "terminado". Cada uso real revela algo nuevo que mejorar.
¿Por qué CLI + MCP en lugar de integración nativa?
Este es un proyecto experimental, pero que cada usuario puede adaptar perfectamente a sus necesidades. No es como que estén reentrenando un modelo, pero sí pueden ajustarlo tanto como quieran. Por eso es open source: pueden usar los modelos que prefieran y moldearlo a su gusto.
Hacerlo o embederlo en un sistema no tenía mucho sentido. Codex o Claude CLI son sistemas propietarios, pero más allá de eso, hay muchos otros CLI que no tienen una base de datos contextual integrada. Incluso el mismo Cline, que es excelente, aún funciona sin búsqueda semántica por cuestiones que sus creadores entienden que es mejor. Pero con esto está la posibilidad de probar un poco más, sin necesidad de romper lo que ya existe: simplemente testear, ajustar, usarse y ver resultados.
Yo no escribo esto con la intención de decir que esto va a cambiar el mundo o la forma en que programas, pero sí que puede ayudarte a personalizar cosas y aprender cosas sobre agentes de IA, pues en el camino uno aprende muchas cosas sobre todo el entorno.
El proyecto ha sido probado en agentes como Gemini CLI, Aider, OpenCode, Codex, Qwen Code, Cline, Droid con buenos resultados, y funcionará con todos los agentes. Solo que en algunos puede no ser tan relevante, pues tienen su propio engine de contexto, pero vale la pena probarlo. Es importante mencionar que la adopción de la herramienta depende muchísimo del prompt, ya que eso es importante para que el agente tome la herramienta como parte natural de sus procesos y no tengas que estarle recordando que la use.
Parte 3: La extensión que cierra el ciclo
Acá está la historia de cuando encontré claude-code-chat de André Pimenta, el cual modifiqué para utilizar el indexador directamente integrado en la extensión. Mi versión mejorada está disponible en claude-code-chat-ui, compatible con el Codebase Index CLI. Como es un uso particular, preferí forkear y modificarla para el uso con el CLI, pero es una gran extensión que todo mundo debe probar de su autor original.
Objetivo del fork
Integrar el indexador local (codebase-index-cli) directamente en la extensión, con control desde la UI, estado visible y documentación clara del flujo. Además, preparar terreno para paralelización de subagentes y mejorar higiene del repo para artefactos del indexador.
Cambios clave de integración con el indexador
Controles del indexador en la UI: Start, Stats, History, Full reset; badge de estado en vivo; tooltips y lógica de disabled según estado.
Lectura periódica de .codebase/state.json para reflejar el estado (watching/indexing/idle/error) y actualizar el badge/avisos.
Advertencia de "indexing" prioritaria sobre YOLO mode para UX más clara mientras el indexador trabaja.
Configuración del CLI: nueva setting para ruta del codebase CLI (claudeCodeChat.codebase.path).
Seguridad de sesiones: bloquear "New Chat" mientras agentes están procesando para evitar "poison" por solape.
Paralelización toggle (Subagents) para el siguiente mensaje (preparado/documentado y cableado en la UI).
Higiene del repositorio para el indexador
Ignorar artefactos locales y sensibles: .codebase/, .env, agents_messaging.db; añadir env.example.
Documentación y propósito del fork
README/CHANGELOG/TEST_SETTINGS actualizados con: integración del indexador, UX del badge, toggle de paralelización, y notas de prepend de mensaje.
Aviso de fork con créditos y link al README de codebase-index-cli, explicando que este fork soporta ese flujo y personalizaciones.
Cómo el fork vuelve el ecosistema más completo
- Control end-to-end del indexador desde la extensión (sin salir de VS Code)
- Visibilidad en tiempo real del estado de indexación y UX segura durante operaciones (badge + warnings)
- Onboarding consistente vía env.example y .gitignore que evita basura/sensibles en git
- Preparado para trabajo con subagentes en paralelo, alineado con flujos apoyados por el indexador
- Documentación explícita del flujo indexador + fork, facilitando adopción y contribución
Mi Setup
VSCodium + Claude Code customizado para poder consumir GPT-5 y Codex además de los nativos Claude-Sonnet-4 y Claude-Sonnet-4.5, Codebase Index CLI, Semantic Search MCP, prompt de claude.md o agents.md en Codex, y extensión para usar Claude Code y mirar mejor los stats de indexing en VSCodium.
Reflexiones Finales
Este proyecto me enseñó:
- Empieza simple, itera rápido: El commit inicial era básico, pero funcionaba. La complejidad vino después, cuando la entendía mejor.
- Los usuarios te enseñan: Cada feature (SQLite-vec, tree-sitter, git tracking) vino de observar necesidades reales.
- La configuración es UX: Pasar de JSON a .env, crear instaladores, permitir configuración por vector store - todo esto fue aprender que la configuración es parte de la experiencia de usuario.
- La documentación es desarrollo: Las 200+ líneas de troubleshooting no son "documentación extra", son conocimiento destilado de problemas reales.
- El código sin contexto es código perdido: Git commit tracking con LLM no es solo un feature cool, es preservar el "por qué" del código.
- La flexibilidad bien diseñada gana: SQLite vs Qdrant, diferentes embedders, tree-sitter opcional - darles opciones a los usuarios es respetarlos.
Este proyecto empezó como una necesidad personal y evolucionó en una herramienta que cualquier desarrollador que use AI assistants puede aprovechar. No es perfecto, pero es útil, y esa es la métrica que importa.
Contact / Contacto
GitHub: github.com/dudufcb1
Discord: duducoc
Telegram: @hardcodeddev