<p><strong>Elyra's </strong><code>@elyracode/semantic-index</code><strong> — local semantic code search</strong></p><p><code>grep</code> is great until it isn't. It finds text, not meaning. Search for "authentication" and you miss the file that calls it "login flow." Search for "retry" and you miss the exponential-backoff loop that never uses the word. In a large or unfamiliar codebase, the thing you're looking for is often named something you wouldn't guess.</p><p>Semantic search fixes this: find code by <em>what it does</em>, not what it's called. The new <code>@elyracode/semantic-index</code> extension brings it to Elyra — and, true to Elyra's character, it can run entirely on your own machine.</p><h2>How it works</h2><p>Two tools. First, build the index:</p><pre><code class="language-text">semantic_index_build
</code></pre><p>This walks your tracked source files (via <code>git ls-files</code>, so it respects <code>.gitignore</code> and skips <code>node_modules</code>), splits each into overlapping chunks, embeds them, and stores the vectors locally:</p><pre><code class="language-typescript">for (let i = 0; i &lt; chunks.length; i += BATCH) {
    const batch = chunks.slice(i, i + BATCH);
    const vectors = await embed(config, batch.map((c) =&gt; c.text));
    // ... store { file, startLine, endLine, text, vector } ...
}
// saved to .elyra/semantic-index.json
</code></pre><p>Then search by meaning:</p><pre><code class="language-text">&gt; Where do we handle session timeout?

  Calling semantic_search({ query: "session timeout handling" })

  Top 8 matches:
  ── src/auth/session.ts:40-79  (score 0.834)
  ── src/middleware/expiry.ts:12-48  (score 0.791)
  ...
</code></pre><p>Under the hood it embeds your query and ranks every stored chunk by cosine similarity:</p><pre><code class="language-typescript">const scored = index.chunks
    .map((chunk) =&gt; ({ chunk, score: cosineSimilarity(queryVector, chunk.vector) }))
    .sort((a, b) =&gt; b.score - a.score)
    .slice(0, limit);
</code></pre><p>The match on <code>expiry.ts</code> — which might never contain the word "timeout" — is exactly what grep would have missed.</p><h2>The part that's actually different: it stays on your machine</h2><p>Semantic code search isn't new. What's different here is <em>where the data goes</em>.</p><p>The embeddings endpoint is configurable. Point it at OpenAI if you want, but you don't have to:</p><pre><code class="language-bash">export ELYRA_EMBED_BASE_URL=http://localhost:11434/v1   # Ollama
export ELYRA_EMBED_MODEL=nomic-embed-text
</code></pre><p>With that one change, your entire codebase is indexed by a model running on your own laptop. Nothing — not a single chunk of your source — leaves the machine. The index file lives at <code>.elyra/semantic-index.json</code>, local and yours.</p><p>For a freelancer working on a client's proprietary code, or a team under a strict data-handling policy, that's the difference between "can't use it" and "ship it." Most hosted semantic-search tools require sending your code to their servers. This one asks where <em>you</em> want the embeddings to come from, and local is a first-class answer.</p><h2>How the agent uses it</h2><p>With the index built, the agent reaches for <code>semantic_search</code> when it needs to <em>find</em> something conceptual, and <code>grep</code> when it needs an exact symbol. The two complement each other: grep for "where is <code>validateToken</code> defined," semantic search for "where do we deal with expired credentials."</p><p>The skill that ships with the extension teaches the agent exactly this division of labor, so it picks the right tool for the question.</p><h2>The honest limitations</h2><p>This is an MVP, and I'd rather you know its edges:</p><ul><li><p><strong>Re-indexing is full, not incremental.</strong> After big changes, you rebuild from scratch. (Incremental updates are the obvious next step.)</p></li><li><p><strong>Search is a linear scan.</strong> Fine for thousands of chunks; you'd want a real vector store at hundreds of thousands.</p></li><li><p><strong>The index is JSON.</strong> Simple and inspectable, but not the most compact format for large repos.</p></li></ul><p>None of these stop it from being genuinely useful today — and the design leaves room to grow without changing how you use it.</p><h2>Why it matters</h2><p>An agent that can only find code by keyword is an agent that misses things — and acts on incomplete context. Semantic search lets it find the <em>relevant</em> code, named whatever it happens to be named, before it makes a change.</p><p>And doing it locally means you don't have to choose between that capability and keeping your code private. With Elyra, you get both.</p><pre><code class="language-bash">elyra install npm:@elyracode/semantic-index
</code></pre>