{"id":47246693,"url":"https://github.com/nguyenyou/scalex","last_synced_at":"2026-04-01T16:50:34.726Z","repository":{"id":344332146,"uuid":"1181257790","full_name":"nguyenyou/scalex","owner":"nguyenyou","description":"Scala code intelligence for coding agents. Zero Build Server. Zero Compilation. Just answers.","archived":false,"fork":false,"pushed_at":"2026-03-22T03:49:43.000Z","size":43178,"stargazers_count":47,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-22T04:05:27.262Z","etag":null,"topics":["ai-agent","claude-code","code-intelligence","developer-tools","find-definition","find-references","graalvm","scala","scala3","scalameta"],"latest_commit_sha":null,"homepage":"https://nguyenyou.github.io/scalex/","language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nguyenyou.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-13T23:21:26.000Z","updated_at":"2026-03-21T14:50:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nguyenyou/scalex","commit_stats":null,"previous_names":["nguyenyou/scalex"],"tags_count":31,"template":false,"template_full_name":null,"purl":"pkg:github/nguyenyou/scalex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nguyenyou%2Fscalex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nguyenyou%2Fscalex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nguyenyou%2Fscalex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nguyenyou%2Fscalex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nguyenyou","download_url":"https://codeload.github.com/nguyenyou/scalex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nguyenyou%2Fscalex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31290538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","claude-code","code-intelligence","developer-tools","find-definition","find-references","graalvm","scala","scala3","scalameta"],"created_at":"2026-03-14T07:19:38.458Z","updated_at":"2026-04-01T16:50:34.719Z","avatar_url":"https://github.com/nguyenyou.png","language":"Scala","readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"site/readme-banner-dark.png\"\u003e\n    \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"site/readme-banner-light.png\"\u003e\n    \u003cimg src=\"site/readme-banner-dark.png\" alt=\"Scalex — Scala code intelligence for coding agents\" width=\"839\" height=\"440\"\u003e\n  \u003c/picture\u003e\n  \u003cbr\u003e\n  \u003cem\u003eGrep knows text. Scalex knows Scala.\u003c/em\u003e\n  \u003cbr\u003e\n  \u003csub\u003eThink grep, but it understands Scala's AST — so it finds symbols, not just strings.\u003c/sub\u003e\n\u003c/p\u003e\n\n---\n\n## Table of Contents\n\n- [Why Scalex?](#why-scalex)\n- [The Problem](#the-problem)\n- [Design Principles](#design-principles)\n- [How It Works](#how-it-works)\n- [Quick Start](#quick-start)\n- [Usage Examples](#usage-examples)\n- [Commands](#commands)\n- [What Makes It Coding-Agent-Friendly](#what-makes-it-coding-agent-friendly)\n- [Scalex vs Grep — Honest Comparison](#scalex-vs-grep--honest-comparison)\n- [Scalex vs Metals](#scalex-vs-metals)\n- [Credits](#credits)\n- [Name](#name)\n- [Mascot](#mascot)\n- [License](#license)\n\n---\n\n## Why Scalex?\n\n1. **No build server. Nothing to leak.** No daemon, no background process, no socket. No build server silently eating RAM, leaking threads, or grinding your CPU. The index is a single file in your repo — when scalex exits, nothing is left running. See [how it works](#how-it-works).\n\n2. **Zero setup. Just works.** Install the skill, point it at any git repo, start navigating. No build files, no config, no \"import build\" dialog, no \"connecting to build server\". Clone a repo you've never seen and explore it in seconds. See [quick start](#quick-start).\n\n3. **Smarter than grep.** Categorized references with confidence ranking. Wildcard import resolution (finds 1,205 importers where grep finds 17). Transitive inheritance trees. Structural AST search. Things grep fundamentally cannot do. See the [honest comparison](#scalex-vs-grep--honest-comparison) for real examples.\n\n4. **Composite commands.** `explain` returns definition + scaladoc + members + implementations + import count in one shot. `refs --count` triages impact in one line. Designed to minimize tool calls — the biggest cost for coding agents isn't latency, it's the number of round trips. See [what makes it coding-agent-friendly](#what-makes-it-coding-agent-friendly) for the full picture.\n\n---\n\nAfter [installing](#quick-start), clone a project and ask Claude to explore it:\n\n| Project | Clone | Prompt |\n|---|---|---|\n| **Scala 3 compiler** | `git clone --depth 1 https://github.com/scala/scala3.git` | *\"Use scalex to explore how the Scala 3 compiler turns source file into bytecode.\"* |\n| **Scala.js** | `git clone --depth 1 https://github.com/scala-js/scala-js.git` | *\"Use scalex to explore how Scala.js turns Scala code into JavaScript.\"* |\n\nScalex indexes the codebase in seconds, then navigates definitions, traces implementations, and explores the architecture — all without a build server or compilation.\n\nhttps://github.com/user-attachments/assets/09391648-1e3a-409c-ad52-19afa99ea81f\n\n---\n\n## The Problem\n\nCoding agents (Claude Code, Cursor, Codex) are powerful, but they're blind in large Scala codebases. When an agent needs to find where `PaymentService` is defined, it has two options:\n\n1. **Grep** — fast, but dumb. Returns raw text. Can't filter by symbol kind, doesn't know a trait from a usage. The agent has to construct regex patterns and parse raw output.\n\n2. **Metals LSP** — smart, but heavy. Requires a build server, full compilation, minutes of startup. Designed for humans in IDEs, not agents making quick tool calls.\n\n## Design Principles\n\nScalex takes only the source-level indexing layer of a language server — definitions, references, implementations, hierarchy — and parses it directly from source with Scalameta. No build, no classpath, no daemon. The tradeoff: when two packages both define a class called `Config`, scalex can't tell which one `extends Config` refers to — that requires type resolution. The upside: clone any repo, index 17k files in seconds, and start navigating immediately.\n\n- **One command = one answer.** No multi-step reasoning, no regex construction.\n- **Structured output.** Symbol kind, package, file path, line number. Not raw text.\n- **Scala 2 and 3.** Enums, givens, extensions, implicit classes, procedure syntax — auto-detected per file.\n- **Java files.** `.java` files are also indexed with lightweight regex extraction (class/interface/enum/record).\n- **Honest about limits.** When it can't find something, it tells the agent what to try next.\n\n## How It Works\n\nHere's the architecture (generated with `scalex graph --render`):\n\n\u003c!-- scalex graph --render \"scalex CLI-\u003eWorkspaceIndex, WorkspaceIndex-\u003egit ls-files, WorkspaceIndex-\u003eScalameta AST, WorkspaceIndex-\u003e.scalex/index.bin\" --\u003e\n```\n                   ┌──────────┐\n                   │scalex CLI│\n                   └─────┬────┘\n                         │\n                         v\n                 ┌──────────────┐\n                 │WorkspaceIndex│\n                 └───┬────┬──┬──┘\n                     │    │  │\n        ┌────────────┘    │  └──────────────┐\n        │                 │                 │\n        v                 v                 v\n ┌─────────────┐ ┌─────────────────┐ ┌────────────┐\n │Scalameta AST│ │.scalex/index.bin│ │git ls-files│\n └─────────────┘ └─────────────────┘ └────────────┘\n```\n\n- **scalex CLI** — 30 commands: search, def, impl, refs, imports, members, graph, ...\n- **WorkspaceIndex** — lazy indexes: symbolsByName, parentIndex, filesByPath, bloom filters\n- **git ls-files** — `--stage` returns path + OID per tracked file (change detection)\n- **Scalameta AST** — Source → AST → SymbolInfo, BloomFilter, imports, parents\n- **.scalex/index.bin** — binary cache with string interning (skip unchanged files)\n\n### Pipeline\n\n```\n  1. git ls-files --stage\n     │  Every tracked .scala file with its content hash (OID).\n     │  ~40ms for 18k files.\n     │\n  2. Compare OIDs against cached index\n     │  Unchanged files are skipped entirely.\n     │  0 changes = 0 parses.\n     │\n  3. Scalameta parse (parallel)\n     │  Source → AST → symbols, bloom filters, imports, parents.\n     │  All CPU cores via Java parallel streams.\n     │\n  4. Save to .scalex/index.bin\n     │  Binary format with string interning.\n     │  Loads in ~225ms for 144k+ symbols.\n     │\n  5. Answer the query\n     │  Maps build lazily — each query only pays for the indexes it needs.\n```\n\n### Performance\n\n| Project | Files | Symbols | Cold Index | Warm Index |\n|---|---|---|---|---|\n| Production monorepo | 14,219 | 170,094 | 5.3s | 445ms |\n| Scala 3 compiler | 18,485 | 144,211 | 2.7s | 349ms |\n\n## Quick Start\n\n### Claude Code (recommended)\n\nInstalls the binary + skill (teaches Claude when and how to use scalex) in one step:\n\n```bash\n/plugin marketplace add nguyenyou/scalex\n/plugin install scalex@scalex-marketplace\n```\n\nThen try:\n\n\u003e *\"use scalex to explore how authentication works in this codebase\"*\n\n### Other coding agents\n\nCopy the skill folder to wherever your agent reads skills — that's it. The included bootstrap script auto-downloads and caches the native binary on first run.\n\n```bash\n# Clone and copy the skill folder\ngit clone --depth 1 https://github.com/nguyenyou/scalex.git /tmp/scalex\ncp -r /tmp/scalex/plugins/scalex/skills/scalex /path/to/your/agent/skills/\n```\n\nThe skill folder contains everything: `SKILL.md` (teaches the agent when and how to use scalex), reference docs, and a bootstrap script that downloads the correct binary for your platform.\n\n### How the bootstrap script works\n\nYou don't install scalex manually — the skill includes a bootstrap script (`scripts/scalex-cli`) that handles everything:\n\n1. **Detects your platform** (macOS arm64, macOS x64, Linux x64)\n2. **Downloads the correct native binary** from GitHub Releases on first run\n3. **Verifies the SHA-256 checksum** against pinned hashes in the script\n4. **Caches the binary** at `~/.cache/scalex/` (follows XDG spec)\n5. **Auto-upgrades** when the skill version changes — old cached binaries are left in place, new version is downloaded alongside\n\nThe coding agent invokes scalex through this script on every call. After the first run (~2s download), subsequent calls go straight to the cached binary with zero overhead.\n\n### Advanced: customize or override\n\nIf you prefer to build from source or use your own binary, you have two options:\n\n**Option A: Put your binary on PATH and edit the skill.**\nBuild scalex, place it anywhere on your `PATH`, then update `SKILL.md` to invoke `scalex` directly instead of `bash \"/path/to/scripts/scalex-cli\"`.\n\n**Option B: Edit the bootstrap script to use a local binary.**\nSet the `BINARY` variable in `scripts/scalex-cli` to point to your local build — the script will skip the download and exec your binary directly.\n\n#### Build from source\n\nRequires [scala-cli](https://scala-cli.virtuslab.org/) + [GraalVM](https://www.graalvm.org/):\n\n```bash\ngit clone https://github.com/nguyenyou/scalex.git\ncd scalex\n./build-native.sh\n# Output: ~30MB standalone binary, no JVM needed\n```\n\n#### Run from source (no native image)\n\nIf you have [scala-cli](https://scala-cli.virtuslab.org/) installed, you can run directly from source without building a native image:\n\n```bash\ngit clone https://github.com/nguyenyou/scalex.git\nscala-cli run scalex/src/ -- search /path/to/project MyClass\n```\n\nDownloads dependencies on first run (~5s), then starts in ~1s. Useful for development or quick testing.\n\n## Usage Examples\n\n```bash\ncd /path/to/your/scala/project\n\n# Discover\nscalex search Service --kind trait         # Find traits by name\nscalex search hms                          # Fuzzy camelCase: finds HttpMessageService\nscalex search find --returns Boolean       # Filter by return type\nscalex file PaymentService                 # Find files by name (like IntelliJ)\nscalex packages                            # List all packages\nscalex package com.example                 # Explore a specific package\nscalex api com.example                     # What does this package export?\nscalex api com.example --used-by com.web   # Coupling: what does web use from example?\nscalex summary com.example                 # Sub-packages with symbol counts\nscalex entrypoints                         # Find @main, def main, extends App, test suites\nscalex overview --concise                  # Fixed-size ~60-line summary for large codebases\nscalex graph --render \"A-\u003eB, B-\u003eC, A-\u003eD\"   # Render directed graph as ASCII/Unicode art\nscalex graph --parse \u003c diagram.txt         # Parse ASCII diagram into boxes + edges\n\n# Understand\nscalex def UserService --verbose           # Definition with signature\nscalex def UserService.findUser            # Owner.member dotted syntax\nscalex explain UserService --verbose       # One-shot: def + doc + signatures + impls\nscalex explain UserService --inherited     # Include inherited members from parents\nscalex explain UserService --no-doc        # Skip Scaladoc section\nscalex explain UserService --brief         # Definition + top 3 members only\nscalex explain UserService --related       # Show related project types from signatures\nscalex package com.example --explain       # Brief explain per type in the package\nscalex members UserService --inherited     # Full API surface including parents\nscalex hierarchy UserService               # Inheritance tree (parents + children)\n\n# Navigate\nscalex refs UserService                    # Categorized references\nscalex refs UserService --count            # Summary: \"12 importers, 4 extensions, ...\"\nscalex refs UserService --top 10           # Top 10 files by reference count\nscalex impl UserService                    # Who extends this?\nscalex imports UserService                 # Who imports this?\nscalex grep \"def.*process\" --no-tests      # Regex content search\nscalex body findUser --in UserServiceLive  # Extract method body without Read\nscalex body findUser --in UserServiceLive -C 3  # Body with 3 context lines\nscalex body findUser --in UserServiceLive --imports  # Body with file imports\nscalex grep \"ctx.settings\" --in Run        # Grep within a class body\nscalex grep \"test(\" --in Suite --each-method  # Which methods call test()?\n\n# Refine\nscalex members Signal                      # Signatures by default + companion hint\nscalex members Signal --brief              # Names only\nscalex members Signal --body --max-lines 10  # Inline bodies ≤ 10 lines\nscalex refs Cache --strict                 # No underscore/dollar false positives\nscalex deps Phase --depth 2                # Transitive dependencies\n```\n\n## Commands\n\n```\nscalex search \u003cquery\u003e           Search symbols by name          (aka: find symbol)\nscalex def \u003csymbol\u003e             Where is this symbol defined?   (aka: find definition)\nscalex impl \u003ctrait\u003e             Who extends this trait/class?   (aka: find implementations)\nscalex refs \u003csymbol\u003e            Who uses this symbol?           (aka: find references)\nscalex imports \u003csymbol\u003e         Who imports this symbol?        (aka: import graph)\nscalex members \u003csymbol\u003e         What's inside this class/trait? (aka: list members)\nscalex doc \u003csymbol\u003e             Show scaladoc for a symbol      (aka: show docs)\nscalex overview                 Codebase summary (--concise for fixed-size ~60-line output)\nscalex symbols \u003cfile\u003e           What's defined in this file?    (aka: file symbols)\nscalex file \u003cquery\u003e             Search files by name            (aka: find file)\nscalex annotated \u003cannotation\u003e   Find symbols with annotation    (aka: find annotated)\nscalex grep \u003cpattern\u003e           Regex search in file contents   (aka: content search)\nscalex packages                 What packages exist?            (aka: list packages)\nscalex package \u003cpkg\u003e            Symbols in a package            (aka: explore package)\nscalex index                    Rebuild the index               (aka: reindex)\nscalex batch                    Run multiple queries at once    (aka: batch mode)\nscalex body \u003csymbol\u003e            Extract method/val/class body   (aka: show source)\nscalex hierarchy \u003csymbol\u003e       Full inheritance tree           (aka: type hierarchy)\nscalex overrides \u003cmethod\u003e       Find override implementations   (aka: find overrides)\nscalex explain \u003csymbol\u003e         Composite one-shot summary      (aka: explain symbol)\nscalex deps \u003csymbol\u003e            Show symbol dependencies        (aka: dependency graph)\nscalex context \u003cfile:line\u003e      Show enclosing scopes at line   (aka: scope chain)\nscalex diff \u003cgit-ref\u003e           Symbol-level diff vs git ref    (aka: symbol diff)\nscalex ast-pattern              Structural AST search           (aka: pattern search)\nscalex tests                    List test cases structurally    (aka: find tests)\nscalex coverage \u003csymbol\u003e        Is this symbol tested?          (aka: test coverage)\nscalex api \u003cpackage\u003e            Public API surface of a package (aka: exported symbols)\nscalex summary \u003cpackage\u003e        Sub-packages with symbol counts   (aka: package breakdown)\nscalex entrypoints              Find @main, def main, extends App, test suites\nscalex graph --render \"A-\u003eB\"   Render directed graph as ASCII/Unicode art\nscalex graph --parse           Parse ASCII diagram from stdin into boxes+edges\n```\n\nAll commands support `--json`, `--path PREFIX`, `--exclude-path PREFIX`, `--no-tests`, `--in-package PKG`, `--max-output N`, and `--limit N` (0 = unlimited). See the full [command reference and options](plugins/scalex/skills/scalex/SKILL.md) for detailed usage, examples, and all flags.\n\n## What Makes It Coding-Agent-Friendly\n\nThe biggest cost for a coding agent isn't latency — it's the number of tool calls. Each call costs tokens, reasoning, and context window space. Scalex is designed to maximize information per call.\n\n**One call, not five.** Most agent tasks require chaining grep → read → grep → read. Scalex collapses these chains:\n\n- `explain` replaces 4-5 calls — definition + scaladoc + members + companion + implementations + import count, all in one response. `--expand N` recursively shows each implementation's members. `--body` inlines source code. `--inherited` merges parent members\n- `body` extracts source directly — no follow-up Read call needed. `--in Owner` disambiguates, `-C N` adds context, `--imports` prepends the file's import block\n- `members --body` inlines method bodies into the member listing — replaces N separate `body` calls\n- `batch` amortizes the ~400ms index load across multiple queries — 5 queries in ~600ms instead of ~2.5s\n- `refs --count` gives category counts in one line — fast impact triage before committing to a full read\n- `refs --top N` ranks files by reference count — surfaces the heaviest users first\n- `--max-output N` hard-caps output at N characters on any command — prevents context window blowup on large codebases\n- `overview --concise` constrains architectural output to ~60 lines — fixed-size summary even on 10k+ file codebases\n\n**Semantic, not textual.** Scalex parses Scala ASTs, so it understands things grep fundamentally cannot:\n\n- `refs` **categorizes** results by relationship (Definition / ExtendedBy / ImportedBy / UsedAsType / Usage / Comment) and **ranks by confidence** — high (explicit import), medium (wildcard import), low (no matching import)\n- `imports` resolves **wildcard imports** — `import dotty.tools.dotc.*` counts as importing `Compiler`. On the scala3 compiler, this finds 1,205 importers vs grep's 17 explicit mentions\n- `hierarchy` shows the **transitive inheritance tree** — parents up, children down, with depth control. Grep can only find direct `extends` mentions\n- `impl` finds **parametric inheritance** — `impl Foo` matches `class Bar extends Mixin[Foo]` via type-param parent indexing\n- `overrides` finds every implementation of a method across the class hierarchy — `overrides run --of Phase --body` shows each override's source inline\n- `ast-pattern` does **structural search** — find types that extend a trait AND have a specific method AND whose body contains a pattern, in one query\n\n**Precision filters.** Large codebases produce hundreds of results. Every command supports filtering at the source:\n\n- `--kind class`, `--path compiler/src/`, `--exclude-path sbt-test/`, `--no-tests` — composable filters on all commands\n- `--in-package PKG` on refs/search/impl — scope results by package prefix; cheaper than `--path` when package ≠ directory\n- `--exact` / `--prefix` on search — `search Auth --prefix` returns ~20 results instead of 1300+\n- `--definitions-only` — only class/trait/object/enum, no val/def name collisions\n- `--category ExtendedBy` on refs — targeted impact analysis for a single relationship type\n\n**Self-correcting output.** Scalex is designed for agents that can't ask clarifying questions:\n\n- Every result includes **symbol kind, package name, file path, and line number** — no ambiguity about what was found\n- Disambiguation prints **ready-to-run commands** — when `explain Compiler` matches 8 types, stderr shows `scalex explain dotty.tools.Compiler`, `scalex explain scala.quoted.Compiler`, etc.\n- Package-qualified lookup — `def com.example.Cache` or partial `def cache.Cache` resolves without follow-up\n- Owner.member dotted syntax — `def MyService.findUser` navigates directly to the member\n- Fuzzy camelCase matching — `search hms` finds `HttpMessageService`\n- **Fallback hints** on \"not found\" — suggests `scalex grep` or Grep/Glob tools as alternatives\n- `--json` on all commands for programmatic parsing\n\n## Scalex vs Grep — Honest Comparison\n\nTested on the **Scala 3 compiler** (18.5k files, 39k symbols).\n\n### \"Where is `Compiler` defined?\"\n\n**Scalex** — 1 call, **2 results**:\n```\nscalex def Compiler --kind class\n  class  Compiler (dotty.tools)    — compiler/src/.../Compiler.scala:16\n  class  Compiler (dotty.tools.pc) — .../CompletionValue.scala:127\n```\n\n**Grep** — 1 call, **24 results**: `class Compiler|trait Compiler|object Compiler` matches `CompilerSearchVisitor`, `CompilerCachingSuite`, `CompilerTest`, `CompilerCommand` (substring noise). No package info, no kind filtering. Agent must write follow-up regex to exclude substrings.\n\n**Why scalex wins**: Exact name matching + `--kind` filter + package disambiguation. One call, done.\n\n### \"Show the full inheritance tree of `Compiler`\"\n\n**Scalex** — 1 call, **full tree with transitive children**:\n```\nscalex hierarchy Compiler\n  Children:\n    ├── ExpressionCompiler — .../ExpressionCompiler.scala:18\n    ├── residentCompiler   — .../Resident.scala:28\n    ├── TASTYCompiler      — .../TASTYCompiler.scala:9\n    │   └── TASTYDecompiler    — .../TASTYDecompiler.scala:11\n    │       └── PartialTASTYDecompiler — .../PartialTASTYDecompiler.scala:9\n    ├── InteractiveCompiler — .../InteractiveCompiler.scala:10\n    ├── ReplCompiler        — .../ReplCompiler.scala:34\n    └── QuoteCompiler       — .../QuoteCompiler.scala:35\n```\n\n**Grep** — **impossible**. `extends Compiler` returns 23 results — 17 are false positives (`extends CompilerTest`, `extends CompilerCommand`). Even after manual filtering, grep only finds *direct* subclasses. `TASTYDecompiler → PartialTASTYDecompiler` (extends `TASTYCompiler`, not `Compiler`) is invisible to grep. Agent needs 3+ follow-up calls to walk the tree manually.\n\n**Why scalex wins**: Transitive hierarchy from the AST. Grep cannot do this at any depth.\n\n### \"What's the impact of changing `Compiler`?\"\n\n**Scalex** — 1 call, **283 references**, auto-categorized and confidence-ranked:\n```\nscalex refs Compiler --limit 5\n  High confidence (import-matched):\n    Definition:  class Compiler {                          (107 total)\n    ExtendedBy:  class ExpressionCompiler extends Compiler (12 total)\n    ImportedBy:  import dotty.tools.dotc.Compiler          (17 total)\n    UsedAsType:  val compiler: Compiler                    (20 total)\n    Usage:       new Compiler                              (56 total)\n    Comment:     /** Compiler that takes...                (20 total)\n  Medium confidence (wildcard import):  ...\n  Low confidence (no matching import):  ...\n```\n\n**Grep** — 1 call, **1,135 lines**, flat and unsorted. Agent sees definitions, imports, type annotations, instantiations, and comments all mixed together. Needs multiple follow-up calls to classify.\n\n**Why scalex wins**: Categories tell the agent *how* a symbol is used (extended? imported? instantiated?), and confidence tiers surface the most relevant references first. An agent using grep needs 3-5 follow-up calls to achieve the same understanding.\n\n### \"Who imports `Compiler`?\"\n\n**Scalex** — 1 call, **1,206 files**:\n```\nscalex imports Compiler\n  .../ExpressionCompiler.scala:3 — import dotty.tools.dotc.Compiler       (explicit)\n  .../Run.scala:5                — import dotty.tools.dotc.{Driver, Run, Compiler}\n  .../WeakHashSet.scala:9        — import dotty.tools.*                    (wildcard)\n```\n\n**Grep** — 1 call, **17 files**: `import.*\\bCompiler\\b` only finds explicit imports. Files using `import dotty.tools.dotc.*` or `import scala.quoted.staging.*` are invisible — that's **98.6% of importers missed**.\n\n**Why scalex wins**: Wildcard import resolution. This is critical for impact analysis — you need to know *every* file that has `Compiler` in scope, not just the ones that spell it out.\n\n### When to use which\n\n| Task | Use | Why |\n|------|-----|-----|\n| \"Does this string exist?\" | **Grep** | Faster, no index needed |\n| \"Find this error message\" | **Grep** | Text search, not a symbol |\n| Config values, flag names | **Grep** | Not Scala symbols |\n| Non-`.scala` files | **Grep** | Scalex only indexes Scala |\n| \"Where is X defined?\" | **Scalex** | Exact match + kind + package |\n| \"Who implements trait X?\" | **Scalex** | AST parent matching, no substring noise |\n| \"Show the class hierarchy\" | **Scalex** | Transitive tree — grep can't do this |\n| \"What's the impact of changing X?\" | **Scalex** | Categorized refs with confidence tiers |\n| \"Who imports X?\" | **Scalex** | Wildcard import resolution |\n| \"What does this file/package export?\" | **Scalex** | `overview` and `members` commands |\n\n**Best approach: use both.** Scalex for Scala-aware navigation, Grep for text search. The skill's fallback hint even suggests this — when scalex can't find something, it tells the agent to try Grep.\n\n## Scalex vs Metals\n\nScalex complements Metals — AST-aware grep vs full LSP. Metals gives you type-checked navigation, rename refactoring, and completions. Scalex gives you instant exploration on any git repo without a build server or compilation.\n\n- **Zero-setup** — works on unfamiliar repos, broken builds, CI environments.\n- **Agent-optimized** — composite commands minimize tool-call round trips. No daemon to manage.\n- **Use both.**\n\n## Credits\n\nScalex is built on ideas from [Metals](https://scalameta.org/metals/) — the Scala language server by the [Scalameta](https://scalameta.org/) team. Specifically, the **MBT subsystem** in the `main-v2` branch (Databricks fork) pioneered git OIDs for cache invalidation, bloom filters for reference pre-screening, and parallel source-level indexing without a build server.\n\n- **From Metals v2 MBT**: git-based file discovery, OID caching, bloom filter search, parallel indexing\n- **From Scalameta**: the parser that makes source-level symbol extraction possible\n- **From Guava**: bloom filter implementation\n\nMetals is [Apache 2.0](https://github.com/scalameta/metals/blob/main/LICENSE). Scalex does not contain code copied from Metals — the ideas were reimplemented independently.\n\nThe `graph` command is ported from [**ascii-graphs**](https://github.com/scalameta/ascii-graphs) by Matt Russell — a Sugiyama-style layered graph layout engine. The original 45 Scala 2 files were consolidated into 11 Scala 3.8 files. Thanks to the ascii-graphs project for the excellent layout algorithm.\n\nBuilt with [Claude Code](https://claude.ai/code) powered by **Claude Opus 4.6** (1M context).\n\n## Name\n\n**Scalex** = **Scala** + **ex** (explore, extract, index).\n\n## Mascot\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"site/Kestrel.png\" alt=\"The Scalex Kestrel\" width=\"256\"\u003e\n\u003c/p\u003e\n\nA **kestrel** — the smallest falcon. Fast, sharp-eyed, lightweight, hovers before diving. See [MASCOT.md](site/MASCOT.md) for the full design brief.\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnguyenyou%2Fscalex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnguyenyou%2Fscalex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnguyenyou%2Fscalex/lists"}