Skip to content

VirtusLab/cellar

Repository files navigation

Cellar

Cellar

Look up the public API of any JVM dependency from the terminal.


When a coding agent needs to call an unfamiliar library method, its options are bad: parse HTML docs (expensive, unreliable), find source on GitHub (requires knowing the URL), or hallucinate the API.

Cellar gives agents — and humans — a single shell command that returns exactly the type signatures, members, and docs needed to write correct code. Output is plain Markdown on stdout, ready to be injected into an LLM prompt with zero post-processing.

Supported artifacts

Format Support
Scala 3 (TASTy) Full — signatures, flags, companions, sealed hierarchies, givens, extensions, docstrings
Scala 2 (pickles) Best-effort — type information may be incomplete
Java (.class) Good — signatures, members

Installation

Coursier (recommended)

If you have Coursier installed:

cs install --contrib cellar

This pulls the GraalVM native binary for your platform from the latest GitHub Release. Update with cs update cellar.

Nix

Run without installing:

nix run github:VirtusLab/cellar -- get-external org.typelevel:cats-core_3:2.10.0 cats.Monad

Install into your profile:

nix profile install github:VirtusLab/cellar

A Nix overlay is also available at github:VirtusLab/cellar#overlays.default.

Manual

Download the native binary for your platform from https://github.com/VirtusLab/cellar/releases/latest, then extract and install:

tar xz -f cellar-*.tar.gz
sudo mv cellar /usr/local/bin/

To verify checksums and signatures, see RELEASING.md.

Development snapshots

Unstable builds of the latest development code are published as snapshot-<sha>-<run> prereleases. Each run publishes a fresh, immutable prerelease and prunes the previous one, so there is always exactly one snapshot. Because immutable releases require a unique tag per build, download URLs are no longer static — resolve the newest snapshot with gh:

# Latest snapshot tag (requires the GitHub CLI, `gh`)
TAG=$(gh release list --repo VirtusLab/cellar --limit 100 --json tagName \
  --jq 'map(.tagName | select(startswith("snapshot-"))) | first')

# Linux x86_64 (also: linux-aarch64, macos-arm64, macos-x86_64)
gh release download "$TAG" --repo VirtusLab/cellar --pattern 'cellar-linux-x86_64.tar.gz' --output - | tar xz
sudo mv cellar /usr/local/bin/

Snapshots are not published to Maven Central and are not picked up by cs install. See RELEASING.md for how they are produced.

Quick start

# Look up a trait from cats
cellar get-external org.typelevel:cats-core_3:2.10.0 cats.Monad

# Look up a symbol from the current project
cellar get --module core cats.Monad

# List top-level symbols in a package
cellar list-external org.typelevel:cats-core_3:2.10.0 cats

# Search for a method name
cellar search-external org.typelevel:cats-core_3:2.10.0 flatMap

# View source code
cellar get-source org.typelevel:cats-core_3:2.10.0 cats.Monad

# Dependency tree
cellar deps org.typelevel:cats-effect_3:3.5.4

Commands

Cellar has two modes: project-aware commands that work against your current project's classpath, and external commands that query arbitrary Maven coordinates.

Project-aware commands

Run from your project root. Cellar auto-detects the build tool (Mill, sbt, or scala-cli), extracts the classpath, and queries your project's code and all its dependencies.

cellar get [--module <name>] <fqn>
cellar list [--module <name>] <package>
cellar search [--module <name>] <query>
  • Mill / sbt: --module is required (e.g. --module lib, --module core)
  • scala-cli: --module is not supported — omit it

The classpath is cached after the first run. Use --no-cache to force re-extraction.

External commands

Query any published Maven artifact by explicit coordinate:

cellar get-external <coordinate> <fqn>
cellar list-external <coordinate> <package>
cellar search-external <coordinate> <query>
cellar get-source <coordinate> <fqn>
cellar deps <coordinate>

Command reference

Command Description
get Symbol info from the current project (signature, flags, members, docs)
get-external Symbol info from a Maven coordinate
get-source Source code from a published -sources.jar
list List public symbols in a package/class from the current project
list-external List public symbols from a Maven coordinate
search Case-insensitive substring search in the current project
search-external Case-insensitive substring search from a Maven coordinate
deps Print the transitive dependency list

Maven coordinates

Coordinates use the format group:artifact:version. The :: shorthand is not supported — use the full artifact name.

org.typelevel:cats-core_3:2.10.0        # Scala 3
org.typelevel:cats-core_2.13:2.10.0     # Scala 2
org.apache.commons:commons-lang3:3.14.0 # Java

Use latest as the version to automatically resolve the most recent release:

cellar get-external org.typelevel:cats-core_3:latest cats.Monad

Options

Flag Applies to Description
--module <name>, -m project commands Build module name (required for Mill/sbt)
--no-cache project commands Skip classpath cache, re-extract from build tool
--java-home <path> all Use a specific JDK for JRE classpath
-r, --repository <url> external commands Extra Maven repository URL (repeatable)
-l, --limit <N> list, list-external, search, search-external Max results (default: 50)
-l, --limit <N> get, get-external Max members to display (no default)
--hide-inherited get, get-external Show only members declared on the type itself
--group-inherited get, get-external Group members by declaring type with section headers

Configuration

Cellar loads configuration from HOCON files and environment variables. Files are loaded in order, with later values overriding earlier ones:

  1. Built-in defaults
  2. ~/.cellar/cellar.conf (user-level, optional)
  3. .cellar/cellar.conf (project-level, optional)

Default config

mill {
  # Binary to invoke when extracting Mill classpaths
  binary = "./mill"           # env: CELLAR_MILL_BINARY
}

sbt {
  # Binary to invoke when extracting sbt classpaths (e.g. "sbt", "sbtn")
  binary = "sbt"              # env: CELLAR_SBT_BINARY
  # Extra arguments passed to sbt, space-separated (e.g. "--client")
  extra-args = ""             # env: CELLAR_SBT_EXTRA_ARGS
}

starvation-checks {
  # Enable Cats Effect CPU starvation warnings (default: false).
  # Set to true during development or CI to surface warnings.
  enabled = false             # env: CELLAR_STARVATION_CHECKS_ENABLED
}

otel {
  enabled = false             # env: CELLAR_OTEL_ENABLED
  endpoint = "http://localhost:4318/v1/traces"  # env: CELLAR_OTEL_ENDPOINT
}

profiling {
  enabled = false                                 # env: CELLAR_PROFILING_ENABLED
  pyroscope-endpoint = "http://localhost:4040"    # env: CELLAR_PYROSCOPE_ENDPOINT
}

Examples

Use sbtn instead of sbt:

sbt { binary = "sbtn" }

Use sbt in --client mode:

sbt { extra-args = "--client" }

Use a custom Mill wrapper:

mill { binary = "./millw" }

Or via environment: CELLAR_SBT_BINARY=sbtn cellar get --module core cats.Monad

Telemetry

Cellar collects anonymous usage telemetry to help improve the tool. It is opt-in. On first use cellar asks you to choose before running:

  • In an interactive terminal you're prompted inline ([1] enable [2] enable globally [3] disable (default) [4] disable globally); once you answer, the requested command continues in the same run.
  • Non-interactively (output piped, CI, or an AI agent) cellar withholds the command and prints a machine-readable consent request instead. The command stays withheld on every run until a choice is recorded (e.g. with cellar telemetry disable).

Either way, telemetry stays disabled until you explicitly enable it.

The formal data-protection terms covering this telemetry are in the Privacy Policy.

What is collected

Each command sends an OpenTelemetry trace with a root cellar.command span (plus child spans for hot-path operations). These are the only attributes emitted — nothing else:

Attribute Example Span
command.name get-external root
cellar.version 0.4.0 root
os.type Mac OS X root
command.success true root
error.category user or system (only on failure) root
error.type CoordinateNotFound (only on failure) root
installation.id anonymous UUID (see below) root
build.tool mill, sbt, etc. build.classpath

What is never sent: Maven coordinates, fully-qualified symbol names, search queries, error messages, stack traces, or any other user data.

Installation ID

The installation ID is a randomly-generated UUID stored in ~/.cellar/installation_id. It identifies your installation, not you: there is no account, no email, and no way to link it to a person. You can reset it at any time with cellar telemetry reset-id.

Managing telemetry

cellar telemetry enable            # opt in for the current project
cellar telemetry enable --global   # opt in for all projects
cellar telemetry disable           # opt out for the current project
cellar telemetry disable --global  # opt out everywhere and stop prompting
cellar telemetry status            # show current status and installation ID
cellar telemetry reset-id          # generate a new anonymous installation ID

enable/disable write to .cellar/cellar.conf in the current project by default; --global writes to ~/.cellar/cellar.conf instead. A project-level setting overrides the global one.

Configuration

Telemetry can also be controlled via ~/.cellar/cellar.conf or environment variables:

otel {
  enabled = true                        # env: CELLAR_OTEL_ENABLED
  endpoint = "http://localhost:4318/v1/traces"  # env: CELLAR_OTEL_ENDPOINT
}

# Pyroscope JVM-agent profiles linked to traces (local-dev only; the production
# stack does not accept profiles). Only active when running from the JAR.
profiling {
  enabled = true                                  # env: CELLAR_PROFILING_ENABLED
  pyroscope-endpoint = "http://localhost:4040"    # env: CELLAR_PYROSCOPE_ENDPOINT
}

Output conventions

  • stdout — Markdown content (signatures, docs, source)
  • stderr — diagnostics (warnings, truncation notices)
  • Exit 0 — success
  • Exit 1 — error

Example output

cellar get-external org.typelevel:cats-core_3:2.10.0 cats.Monad
## cats.Monad
```scala
trait Monad[F] extends FlatMap[F] with Applicative[F]
```
Monad.
Allows composition of dependent effectful functions.

**Flags:** abstract
**Origin:** cats.Monad
**Members:**
```scala
def flatMap[A, B](fa: F[A])(f: Function1[A, F[B]]): F[B]
def pure[A](x: A): F[A]
def flatten[A](ffa: F[F[A]]): F[A]
def iterateWhile[A](f: F[A])(p: Function1[A, Boolean]): F[A]
...
```
cellar list-external org.typelevel:cats-core_3:2.10.0 cats --limit 5
object Eval$
trait ComposedContravariantCovariant[F, G] extends Contravariant[TypeLambda]
object Later$
object Show$
trait EvalSemigroup[A] extends Semigroup[Eval[A]]
Note: results truncated at 5. Use --limit to increase.
cellar search-external org.typelevel:cats-core_3:2.10.0 flatMap --limit 3
cats.FlatMap — object FlatMap$
cats.FlatMap — trait FlatMap[F] extends Apply[F] with FlatMapArityFunctions[F]
cats.FlatMap$ — object FlatMap$
Note: results truncated at 3. Use --limit to increase.

Using cellar with Claude Code

As a plugin (recommended)

Install cellar as a Claude Code plugin for auto-updates:

/plugin marketplace add virtuslab/cellar
/plugin install cellar@virtuslab-cellar

Claude will automatically have access to the /cellar:cellar skill and know when to use it.

Manual setup

Alternatively, add the following to your project's CLAUDE.md:

## Cellar

When you need the API of a JVM dependency, use cellar. Always prefer cellar over hallucinating API signatures.

### Telemetry notice

On first run in a project, cellar emits a `{"status":"needs_input",...}` JSON object on stderr. When you see it, pause and ask the user the question before continuing.

### Project-aware commands (run from project root)

For querying the current project's code and dependencies (auto-detects build tool):

    cellar get [--module <name>] <fqn>       # single symbol
    cellar list [--module <name>] <package>  # explore a package
    cellar search [--module <name>] <query>  # find by name

- Mill/sbt projects: `--module` is required (e.g. `--module lib`, `--module core`)
- scala-cli projects: `--module` is not supported (omit it)
- `--no-cache`: skip classpath cache, re-extract from build tool
- `--java-home`: override JRE classpath

### External commands (query arbitrary Maven coordinates)

For querying any published artifact by explicit coordinate:

    cellar get-external <coordinate> <fqn>       # single symbol
    cellar list-external <coordinate> <package>  # explore a package
    cellar search-external <coordinate> <query>  # find by name
    cellar get-source <coordinate> <fqn>         # source code
    cellar deps <coordinate>                     # dependency tree

Coordinates must be explicit: `group:artifact_3:version` (use `latest` for newest version).

### Workflow

1. **Don't know the package?**`cellar search <query>` or `cellar search-external <coordinate> <query>`
2. **Know the package, not the type?**`cellar list <package>` or `cellar list-external <coordinate> <package>`
3. **Know the type?**`cellar get <fqn>` or `cellar get-external <coordinate> <fqn>`
4. **Need the source?**`cellar get-source <coordinate> <fqn>`

Building from source

Requires JDK 17+ and Mill.

# Fat JAR
./mill cli.assembly
java -jar out/cli/assembly.dest/out.jar get-external org.typelevel:cats-core_3:2.10.0 cats.Monad

# Native image (GraalVM)
./mill cli.nativeImage

Running tests

# Publish test fixtures to local Maven first
./mill publishFixtures

# Run tests
./mill lib.test

Installing a local build with Nix

./mill cli.nativeImage && nix profile install --impure .#dev

Tech stack

Scala 3, Cats Effect, fs2, tasty-query, Coursier, decline, Mill.

License

MPL-2.0

About

CLI tool for coding agents and developers to query the public API of any Maven JVM dependency — get symbol signatures, list packages, search by name, and inspect dependency trees. Powered by Coursier and tasty-query.

Resources

License

Stars

75 stars

Watchers

2 watching

Forks

Packages

 
 
 

Contributors