Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra Félagi Agents as teammates on one board Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra Sjá SEO & GEO workspace for macOS Elyra DataGrid Server-driven data grid for Laravel
Elyra integration
Elyra agent
Release notes
Changelog
Elyra
Database browser

Database browser

Conductor includes a lightweight database browser so you can connect to a project's database, look around the schema, and run queries without leaving the cockpit.

Supports MySQL/MariaDB, PostgreSQL, ClickHouse, SQLite, and remote SQL Anywhere / libsql (a sqld server over HTTP). Conductor stays secret-free: it reads the connection details from the project's existing .env, or you supply them for the session. Nothing new is persisted, and it never calls a model — it's a tool, not an agent. See Architecture & boundaries.

Conductor is a native (Rust) app, so it talks to each database with a Rust client directly — it does not (and cannot) load the project's PHP/Laravel drivers. It only reads the connection values from .env. ClickHouse uses its native TCP protocol (port 9000), the same one clickhouse-client uses — not the HTTP interface.

Opening it

Toggle the DB panel from the toolbar (top right) or the command palette (⌘KShow database panel). It appears on the right, like the file sidebar.

Multiple connections per project

The panel is a tree of connections, so a project can have several databases open at once — for example MySQL for app data and ClickHouse for BI/reports. Click to add a connection (from .env or manually); each one expands to its own table list and has per-connection actions on hover: new query (), refresh (), disconnect (), and remove ().

Saved connections — including passwords — are stored in the OS keychain (macOS Keychain), keyed per project. Nothing is written into the project folder, so nothing can be committed; the connections simply reappear (collapsed) when you reopen the project, ready to connect with a click.

Hover a connection and use to edit it (host/port/credentials/TLS) — it reconnects and re-saves. Give a connection a Group to organise the list into collapsible folders, and use Test connection in the form to verify the settings before saving.

TLS (remote PostgreSQL / ClickHouse)

When adding a PostgreSQL or ClickHouse connection, tick Use TLS to connect over an encrypted channel; tick Skip certificate verification for self-signed/internal hosts. TLS uses the system stack (macOS Secure Transport). ClickHouse keeps its native protocol over the encrypted stream.

SSH tunnels (remote databases)

For a database that's only reachable through a jump host, tick Use SSH tunnel in the connection form and fill in:

  • SSH host / port / user
  • Auth methodPublic key (with a Private key path like ~/.ssh/id_ed25519 and an optional Passphrase) or Password.

The Host and Port above are the database address as seen from the SSH server (often 127.0.0.1 and the default port). Conductor opens a local port-forward with the system ssh and connects the driver to it; the tunnel lives as long as the connection. Secrets are passed to ssh via a one-shot askpass helper (deleted right after auth) and stored in the Keychain with the rest of the connection. TLS is skipped for tunneled connections — the SSH channel is the encryption.

Connecting

  • Connect from .env — with a project selected, Conductor reads the Laravel-style keys from its .env:

    Key Used for
    DB_CONNECTION mysql / mariadb / pgsql / clickhouse / sqlite
    DB_HOST, DB_PORT host/port (MySQL 3306, PostgreSQL 5432, ClickHouse 9000)
    DB_DATABASE database name (MySQL/PostgreSQL/ClickHouse) or file path (SQLite)
    DB_USERNAME, DB_PASSWORD credentials (MySQL/PostgreSQL/ClickHouse)

    PostgreSQL and ClickHouse connect without TLS in this phase (local/dev); remote TLS is a later addition. ClickHouse is most often set up via manual connection.

    For SQLite, a relative DB_DATABASE resolves against the project, and an empty value falls back to database/database.sqlite.

  • Manual connection — pick the engine and fill in the details yourself. Manual credentials are kept in memory for the session only; they are not written anywhere.

SQL Anywhere (remote)

SQL Anywhere is a replication-ready, SQLite-compatible engine; Conductor connects to a remote sqld server over HTTP via the thin libsql client (no second bundled SQLite).

  • Manual: pick SQL Anywhere (remote) and enter the Server URL (libsql://host or https://…) and an optional auth token (sent as a bearer token). The token is stored in the OS keychain like any other secret.
  • From .env: detected via DB_CONNECTION=libsql (or sqlanywhere) reading DB_URL / SQLANYWHERE_URL / LIBSQL_URL / DATABASE_URL and a matching *_AUTH_TOKEN; also inferred from an unambiguous SQLANYWHERE_URL / LIBSQL_URL or a libsql:// URL even without DB_CONNECTION. Schema and queries use the SQLite- compatible surface (sqlite_master, PRAGMA table_info).

Browsing tables

The panel lists the database's tables (with a filter box). Click a table to open it in the main window as its own tab — a data grid with a toolbar:

  • Sort — click a column header (click again to reverse). Primary-key columns are marked with 🔑.
  • Filter — type a WHERE condition (e.g. city = 'Oslo') in the box, and/or use the per-column filter row under the headers (each box matches that column, combined with AND). The leading WHERE is optional.
  • Order — type a full ORDER BY clause (e.g. created_at DESC, id) in the ORDER BY box. Clicking a column header also sorts; an explicit ORDER BY wins. clears filters and order.
  • Page — results load 100 rows at a time; use / .
  • Edit a cell — double-click it to open a small editor (a multi-line field for long values, plus a Set to NULL option); ⌘↵ saves via an UPDATE … WHERE <primary key>. Requires the table to have a primary key. Single-click still copies the value.
  • Structure — flip the Data / Structure toggle to see the table's columns with their type, nullability, and key, plus the table's approximate row count and on-disk size.
  • Export⤓ Excel (.xlsx) or ⤓ CSV.
  • Refresh, a row count and query time, NULL shown in muted italics.

Up to 1000 rows are returned per query (a truncated note appears if there are more).

Running queries

Click + New query for a SQL editor tab. Write SQL and run it with ⌘↵. SELECT (and SHOW / PRAGMA / EXPLAIN / WITH) show a result grid; other statements report the number of rows affected. A query tab keeps a per-project history of what you've run — pick one from the History… dropdown to load it back (last 50).

Export to Excel / CSV

Any table or query result can be exported with ⤓ Excel (a real .xlsx) or ⤓ CSV. Values are exported as text so identifiers and zip codes with leading zeros (e.g. 0484) are preserved exactly.

In a table's Data view the export covers the whole table (not just the visible page), with the database field names as the header row, and it respects any active WHERE / column filters and ordering. In a query tab, the current result is exported.

Ask Elyra about your data

When the Elyra CLI is installed, a 🤖 Elyra button appears on results. It hands structured context to a fresh agent (pre-filled in its composer, so you add the question) — Conductor only formats and sends text; the reasoning happens in Elyra:

  • On a result / query — sends the columns and first rows (and the SQL, in query mode). Good for “explain this result” or “optimise this query”.
  • Structure view — sends the table schema. Good for “write a migration that…”.
  • Per row — hover a row and click the small 🤖 in the # column to send that single row as a column | value table. Good for “explain this row”.

Data Transfer (copy a database, or just some tables)

Tools ▸ Data Transfer… in the menu bar (also in the command palette) opens a dialog to copy tables from one saved connection straight to another — e.g. cloning a whole database from a remote host down to localhost, or moving a handful of tables between a MySQL and a PostgreSQL connection.

  1. Pick a Source and a Target from the project's saved connections (each is connected on demand if it isn't already).
  2. The source's tables load with checkboxes — tick individual tables, or use "Select all".
  3. Choose what to copy:
    • Create/replace table structure — recreates the table on the target from the source's columns (same-engine transfers reuse the exact column types; cross-engine transfers use a best-effort type mapping).
    • Copy data — copies rows in batches.
    • Drop existing table on target first (when recreating structure), or Empty target table before copying (when not).
  4. Start Transfer runs table by table with a live progress readout (rows copied so far) and a final ✓/✗ per table when it's done.

Works across engines (MySQL, PostgreSQL, ClickHouse, SQLite, SQL Anywhere) because rows round-trip as quoted SQL text, which every supported engine coerces to the destination column's real type on INSERT. Same-engine transfers (the common case) get full-fidelity structure via the source's own column definitions.

Data masking (safe prod → dev copies)

When Copy data is on, each table row in the list gets a 🔒 button — click it to load that table's columns and choose a masking rule per column:

  • Don't mask — copy the value as-is (default).
  • Set to NULL — the column is always written as NULL on the target.
  • Fixed value — every row gets the same literal (e.g. redacted@example.com).
  • Hash (irreversible) — a stable digest of the original value. The same input always hashes to the same output within one transfer run, so joins/grouping on the masked column still work on the target — but the original value can't be recovered.
  • Redact (keep length) — replaces each non-whitespace character with *, so the shape of the data (e.g. a phone number's length) is preserved without exposing it.

Masking only changes what gets written to the target — the source is never touched. A small 🔒 N columns will be masked note appears above the table list once any rule is set, and the 🔒 button glows on tables with active rules so it's obvious before you hit Start Transfer.

Compare Schemas (schema diff + migration script)

Tools ▸ Compare Schemas… (also in the command palette) diffs two saved connections table-by-table and column-by-column — handy for "did staging's schema drift from prod?" or "what does this environment need before I can copy data into it?".

  1. Pick two connections and click Compare.
  2. Each table is marked same, columns differ, missing on target, or missing on source; tick Only show differences (on by default) to skip the noise. Differing tables list the columns that don't match, with the source and target type side by side.
  3. A suggested migration script is generated underneath — CREATE TABLE for tables missing on the target, ALTER TABLE … ADD COLUMN for missing columns (using the source's exact type when both connections are the same engine, or a best-effort mapping across engines). Copy SQL puts it on the clipboard.

It's read-only and never runs anything — review the script yourself before applying it. Type mismatches are reported but intentionally not auto-fixed (changing an existing column's type can lose data, so that stays a manual, deliberate decision).

Saved queries (private, per project)

In a query tab you can ⭐ Save the current SQL under a name and reload it later from the Saved queries… dropdown. Saved queries are:

  • Per project — scoped to the connected project.
  • Private — stored in <project>/.conductor/queries/queries.json, with an auto-generated .gitignore that ignores the whole folder. They are never committed and stay on your machine only.

(Runbooks in .conductor/notes/ remain versionable — only queries are kept private.)

Notes & limits

  • Engines: MySQL/MariaDB, PostgreSQL, ClickHouse (native protocol, port 9000), SQLite. PostgreSQL and ClickHouse are non-TLS for now (local/dev).
  • Editing requires a primary key on the table; results from arbitrary joins/queries are read-only. ClickHouse tabs are read-only (it isn't an OLTP row-update store) — browse, query, and export instead.
  • Database tabs are not restored across restarts (the connection is per session).

Related