Graver

Help

Graver is a native Mac workbench for Looker and Dataform. This page covers installing it, pointing it at a project, and the parts that aren't obvious from the menus.

Install

Graver installs with Homebrew. Three commands, in this order:

brew tap graver-app/tap
brew trust graver-app/tap
brew install --cask graver

The middle step is required rather than advisory. Homebrew refuses to load casks from taps outside its own repositories, and without it the install stops with "Refusing to load cask … from untrusted tap".

Graver is signed with a Developer ID certificate and notarized by Apple, so it opens without a Gatekeeper warning.

Without Homebrew

Download the DMG and drag Graver to Applications. That link always points at the newest release.

The trade is updates: there's no updater inside the app, so a copy installed this way stays on the version you downloaded until you fetch another one. Homebrew is the better choice if you expect to use Graver regularly.

Updating

brew upgrade --cask graver

Uninstalling

brew uninstall --cask graver          # the app
brew uninstall --zap --cask graver    # and its settings

What it needs

  • macOS 13 (Ventura) or later. Universal — Apple Silicon and Intel.
  • Node, for Dataform projects — brew install node. Graver shells out to the Dataform CLI rather than reimplementing compilation, so what it compiles is what Dataform compiles, but it doesn't need the CLI installed globally: it runs npx @dataform/cli, pinned to the dataformCoreVersion in your workflow_settings.yaml. A legacy dataform.json project uses its own node_modules/.bin/dataform instead, because that's where the CLI lives by design in v2.
  • gcloud, authenticated, for anything that touches BigQuery: gcloud auth application-default login. Graver uses your local application-default credentials and stores none of its own.

Worth knowing: BigQuery work runs as you. Looker queries as the service account on its connection, so a table your account can't read shows up as missing even when Looker can see it perfectly well. Reports say which identity produced them for that reason.

Opening a project

Use File ▸ Open Folder… (⇧⌘O) and choose the repository root — the folder holding workflow_settings.yaml for Dataform, or manifest.lkml for Looker. Graver detects which it is and lights up the matching panel.

A folder that is neither still opens as an ordinary editor workspace; the workbench panels simply say there's no project.

The Dataform workbench

View ▸ Dataform (⌃⌘D) opens the panel under the editor. It works on the object in the active .sqlx tab.

  • Compile runs the Dataform CLI over the whole project and builds the graph everything else reads.
  • Validate dry-runs the object's SQL against BigQuery. Nothing executes and nothing is billed; you get the schema the query would produce, plus the bytes it would scan.
  • Run executes it for real — tables, views, incrementals and assertions all run natively against BigQuery.
  • Run + Stale Deps runs it after first rebuilding the upstream objects that are out of date.
  • Preview reads rows from the object's existing table without rebuilding it.

Results land in the grid under the code. The other tabs show the Compiled SQL, Diagnostics (click one to jump to the line), and an Activity log of what actually ran.

The dots in the file tree

A dot next to a .sqlx file means its table is older than the code that defines it — you've edited the definition since the table was last built. It's Graver's own idea, not something Dataform reports.

Run profiles

A profile is the set of compilation overrides Dataform accepts: schema suffix, table prefix, default database, and variables. The selector sits in the panel's toolbar, and the active profile applies to compile, validate and run alike — so what you validate is what you'd run.

The guard that matters: a profile can be marked so it refuses to create datasets. Running an object whose dataset doesn't exist then stops and asks, and if the profile forbids creation you have to type the dataset name to continue. That's deliberate friction — it's what catches a mistyped suffix before it conjures a schema in production.

The Looker panel

View ▸ Looker (⌃⌘L) validates the whole LookML project in the open folder and lists what it found. Press Return or double-click a finding to open the file with the cursor on the line.

It checks things Looker itself only discovers when someone happens to open the right explore:

  • every ${view.field} resolves, after includes, extends, refinements and @{constants};
  • every explore actually joins the views its fields reference;
  • with Check field SQL ticked, every field's SQL is dry-run against BigQuery — so a dimension naming a column that no longer exists is caught before a dashboard finds it.

It also reports what it didn't check and why. Fields using Liquid are skipped rather than guessed at, and they're counted so the coverage is visible.

Settings

Two things Graver can't work out for itself, per project:

  • BigQuery project — the billing project for dry runs. Leave it blank to use whatever gcloud config get-value project returns.
  • Connection defaultproject.dataset as configured in Looker Admin ▸ Connections. Views with no sql_table_name follow Looker's convention against it, and can't be checked without it.

Edit ▸ Validate LookML Project… does the same checks on any folder you pick and opens the result as a Markdown document you can keep.

SQLFluff for .sqlx

Format Document (⌥⇧⌘F) formats .sqlx with SQLFluff. That needs one thing most SQLFluff installs don't have: the Dataform templater, which understands ${ref()} and the config {} block. Without it SQLFluff sees broken SQL and refuses the file.

Setting it up

Edit ▸ Set Up SQLFluff for Dataform… checks the sqlfluff you already have first. If it carries the templater, Graver uses it and installs nothing. If it doesn't, Graver builds a private Python environment in Application Support and leaves your own installation untouched. It takes about a minute.

The separation is deliberate: sqlfluff-templater-dataform pins an exact SQLFluff version, so installing it into a shared environment would change the sqlfluff your other projects use.

Rules

Graver honours your configuration exactly as the SQLFluff CLI would — a .sqlfluff in the project, then the usual parent directories, then ~/.sqlfluff. If you have none, Edit ▸ Create .sqlfluff for Project writes a starting point (BigQuery dialect, Dataform templater) that you then own and edit. It won't overwrite an existing file.

The graver command

The cask installs a graver command for opening things from a terminal:

graver .                          # the current folder, as a workspace
graver views/orders.view.lkml     # a file, with its folder in the tree

Connecting an agent

Every capability in the workbench is also a tool an agent can call. Nothing is agent-only, and nothing is human-only.

  • View ▸ Enable Claude Code Integration serves the tools over the /ide WebSocket protocol, which Claude Code discovers on its own.
  • View ▸ Enable Agent Integration (MCP) opens an HTTP MCP endpoint for any other agent. Settings ▸ Agents has the URL and the config to paste.

The agent gets the same compile, validate, run, preview and LookML validation you do — and you watch the results arrive in the same panel.

Where Graver keeps things

  • Log~/Library/Logs/Graver/graver.log, or Help ▸ Show Log in Finder.
  • Settings — the dev.graver.app preferences domain.
  • Per-file state and the SQLFluff environment~/Library/Application Support/Graver.

brew uninstall --zap --cask graver removes all of it.

When something goes wrong

"Refusing to load cask … from untrusted tap"

Run brew trust graver-app/tap, then install again.

Validation says a table can't be read

Graver checks as your gcloud identity. Confirm with gcloud auth application-default login and check the project shown in the panel's status line — Looker's own service account may have access where your account doesn't.

Views reported as unvalidatable

A view with no sql_table_name gets its table from Looker's connection, which isn't in the repository. Set the connection default in the Looker panel's settings and they become checkable.

Formatting does nothing on a .sqlx file

The SQLFluff on your PATH probably lacks the Dataform templater. Run Edit ▸ Set Up SQLFluff for Dataform….

"Could not find the dataform CLI"

Graver reaches the CLI through npx, so this means Node isn't on the PATH it can see: brew install node. Note that a GUI app doesn't inherit your shell's PATH, so a Node installed somewhere unusual can be invisible to Graver even when it works in your terminal.

Anything else

The log records what Graver ran and what came back, which is usually enough to see the cause: Help ▸ Show Log in Finder.