Your first connection
Connections follow psql. Flags, a URL, the libpq environment and ~/.pgpass all work from the command line, and inside the app the connection editor takes the same parameters. A project you open may already carry its connection in a config file, and PlumeSQL lists it under Discovered without running any project code.
From the command line
sh
plumesql -d mydb # localhost, the OS user, ~/.pgpass
plumesql -h db.example.com -p 5433 -U app -d mydb
plumesql postgres://app@db.example.com:5433/mydb
PGDATABASE=mydb plumesql-h, -p, -U and -d mean what they mean in psql; -d also takes a postgres:// URI or a key=value conninfo string. PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE and the PGSSL* paths are read, with flags beating -d beating the environment. A password left empty is looked up in ~/.pgpass.
In the app
Open the Connections side tab (Ctrl+Shift+C, Cmd+Shift+C on macOS), press the plus button, fill in the parameters, Test, Save. Every tab connects lazily on its first run: a tab whose connection is assigned but not dialed yet shows a grey dot and reads "not connected", a calm state. "Disconnected" is the broken one, a dial that failed, and its verbatim error is in the Log.
A Pick button lists the databases on the server; Open Database saves a copy of a connection bound to another database, and Duplicate copies one outright. Each connection keeps its own statistics (last connect, server version, counts, failures) on the row.
Discovery
PlumeSQL scans the workspace for the connection your project already declares: the .env families, .NET appsettings*.json and user secrets, docker-compose, devcontainer, Prisma, Rails database.yml, Django, Laravel, Spring, Alembic, TypeORM, knex, cargo [env] and generic config files, understanding JDBC, PDO and SQLAlchemy URIs, libpq key=value strings and DB_* / POSTGRES_* splits. The scan is static, it never executes project code, it skips node_modules and friends, and it goes discover.depth levels deep (2 by default).
Found connections appear under Discovered and can be used as they are or promoted into the vault.
The two kinds
- Vault: connections you saved, sealed in an encrypted vault whose key lives in the OS keyring.
- Discovered: what the workspace's files declare, plus the connection given on the command line.
Whatever the kind, every connection has a permanent internal id, and everything about it (statistics, checks, the snapshot cache) keys on that id, never on its name or parameters.
Groups
Connections belong to groups with a color, guards and setting overrides. Four ship seeded: Production (red), Staging (amber), Development (green) and Local (blue). Settings resolve connection over group over workspace over global, the most specific explicit value winning; the safety flags can only escalate along that chain, never loosen. The Production group silences every parser that would contact the server while you type. See Safety and production.
SSH tunnels and SSL
A connection can dial through an SSH tunnel with a password, a key file (with passphrase) or the agent; no local port is opened. SSL takes sslmode, a CA certificate and a client certificate and key.
SSH host keys
SSH tunnels accept the server's host key without verification, the usual trade-off in GUI database clients: traffic is encrypted, but first-contact spoofing is not detected. Use a bastion you trust.
The Session section
Each connection's editor has a Session section: the application_name template (connection.applicationName, default plumesql {owner}@{workspace}), connect timeout, statement_timeout, idle_in_transaction_session_timeout, search_path, time zone and free-form startup parameters, each with a link to the documentation of the connected version.
Every tab is its own dedicated backend, never pooled: SET, temporary tables and an interactive BEGIN persist between runs like in psql, Cancel stops one statement and keeps the backend, and the status bar shows when a tab is in a transaction (amber) or when its transaction failed (red).
Availability checks
Off by default (connection.checkAutomatically), because each check is one throwaway backend on the server. Switched on, PlumeSQL dials the checked connections on startup and when the window regains focus, backs off on failure and tries again on its own. Any real contact with a database (a tab's dial, a snapshot build, a Test) updates every dot at once.