perk-workbench

module
v0.10.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 19, 2026 License: MIT

README

Perk Workbench

A terminal UI for exploring databases. Built with Bubble Tea.

  ┌─────────────────────────────────────────────┐
  │  perk-workbench chinook-sqlite.db           │
  │                                             │
  │  ┌── Schema ─────┐ ┌── Workspace (tab) ───┐│
  │  │  artists       │ │ SELECT * FROM        ││
  │  │  albums        │ │ artists LIMIT 5;     ││
  │  │  tracks        │ │                      ││
  │  │  ...           │ │ ┌─ Results ────────┐││
  │  │                │ │ │ 1 | AC/DC        │││
  │  │                │ │ │ 2 | Accept       │││
  │  └────────────────┘ │ └──────────────────┘││
  │                      └─────────────────────┘│
  └─────────────────────────────────────────────┘

Quick start

npx perk-workbench path/to/database.db

Or install globally:

npm install -g perk-workbench
perk-workbench path/to/database.db

Connect to MySQL, PostgreSQL, and MongoDB:

perk-workbench 'mysql:user:pass@tcp(host:3306)/db'
perk-workbench 'postgres://user:pass@host:5432/db'
perk-workbench 'mongodb://user:pass@host:27017/db'

MongoDB connections accept mongosh-style statements in the query editor (db.restaurants.find({"borough": "Bronx"}).limit(5), countDocuments, aggregate, distinct, writes, and index DDL); the schema pane lists collections, and the structure tab shows fields sampled from the collection.

Or configure the connection with Laravel-compatible environment variables, then launch without an argument:

export DB_CONNECTION=mysql
export DB_HOST=127.0.0.1
export DB_PORT=3306
export DB_DATABASE=office
export DB_USERNAME=root
export DB_PASSWORD=secret
perk-workbench

Accepted DB_CONNECTION values are sqlite, mysql, and pgsql. SQLite requires DB_DATABASE; remote ports default to 3306 (MySQL) and 5432 (pgsql). A database argument passed on the command line overrides these variables. A .env file in the working directory is read as a fallback; real environment variables take precedence over it, and a command-line argument overrides both.

Variable Required Default
DB_CONNECTION yes — (sqlite, mysql, or pgsql)
DB_HOST sqlite: no · mysql/pgsql: yes
DB_PORT no 3306 (mysql) · 5432 (pgsql)
DB_DATABASE sqlite: yes · mysql/pgsql: no
DB_USERNAME mysql/pgsql: yes
DB_PASSWORD no empty

Credential storage

Connection profiles are saved to connections.json under your user config directory (~/.config/perk-workbench/). Literal passwords are encrypted at rest with AES-256-GCM using a key in secret.key inside the same directory; each ciphertext is bound to its profile and field, and the directory and files are locked down to 0700/0600. Connection targets that carry credentials — redis://user:pass@host, mongodb://user:pass@host/db, postgres://user@host/db?password=…, mysql:user:pass@tcp(host:3306)/db — are encrypted the same way; non-credential targets (file paths, database names) stay plaintext and readable.

Threat model. The key and the ciphertext live under the same user-owned directory, so encryption protects against accidental disclosure and copies of your config (backups, shared screenshots, misplaced files) — not against an attacker with your account access, who can read both. Env and file references are the stronger separation:

perk-workbench                # with DB_PASSWORD set, or
# ${MY_PASSWORD} / file:///path/to/secret in the connection form

A stored password that cannot be decrypted (tampered file, replaced key) is never shown as plaintext and is never rewritten: the app reports it and refuses to save until you re-enter the value, so a transient key problem cannot silently destroy your stored ciphertext.

Features

Browse schemas Tables, views, columns, types, indexes, foreign keys
Run queries Write, execute, and cancel SQL or mongosh-style queries
AI assist Natural language to SQL (OpenAI, Claude, Gemini)
4 backends SQLite, MySQL, PostgreSQL, MongoDB via a shared query interface
Configurable TLS support for MySQL/Postgres, custom keybindings, config.json defaults

Architecture

cmd/perk-workbench/    CLI entry point
internal/
├── workbench/         Bubble Tea models, layout, keybindings
├── core/              Workflow state machine (query lifecycle, focus, tabs)
├── database/          Connection dispatcher (routes DSN to driver)
├── sql/               Shared types & contracts (Service, Column, Rows)
├── sqlite/            SQLite driver (modernc.org/sqlite, no CGO)
├── mysql/             MySQL driver
├── postgres/          PostgreSQL driver
├── mongodb/           MongoDB driver (mongosh-style statements)
├── chrome/            Stateless terminal rendering helpers
├── ai/                AI clients (OpenAI, Anthropic, Gemini)
├── clipboard/         System clipboard access
└── log/               Event logging

Development

go test -race ./cmd/... ./internal/...
go vet ./cmd/... ./internal/...
go build ./cmd/perk-workbench
gofmt -l cmd internal

The build version is injected explicitly — never baked in:

go build -ldflags "-X main.version=<version>" ./cmd/perk-workbench
perk-workbench --version

--version prints perk-workbench <version>; a build without the injection honestly reports perk-workbench devel. The injected version is carried into the plugin test evidence document (host_version), so release evidence names the exact host build.

Demo databases for testing:

make sqlite      # Chinook (SQLite)
make mysql       # Office demo (MySQL)
make postgres    # Employees demo (PostgreSQL)
make mongo       # Restaurants demo (MongoDB)

License

MIT

Directories

Path Synopsis
cmd
perk-workbench command
internal
ai
clipboard
Package clipboard provides cross-platform clipboard access behind build-tag guards so that unsupported platforms compile without platform-specific dependencies.
Package clipboard provides cross-platform clipboard access behind build-tag guards so that unsupported platforms compile without platform-specific dependencies.
database/plugin
Package plugin hosts external database driver plugins: child processes speaking the perk/v1 JSON-RPC stdio protocol.
Package plugin hosts external database driver plugins: child processes speaking the perk/v1 JSON-RPC stdio protocol.
database/plugin/conformance
Package conformance runs the perk/v1 protocol conformance suite against one external plugin executable, outside Go's unit-test harness: fixture-driven protocol cases and generated transport cases, each in a fresh child spoken to as raw NDJSON-RPC on stdio.
Package conformance runs the perk/v1 protocol conformance suite against one external plugin executable, outside Go's unit-test harness: fixture-driven protocol cases and generated transport cases, each in a fresh child spoken to as raw NDJSON-RPC on stdio.
drivers/mongodb
Package mongodb implements the shared database service contract against MongoDB.
Package mongodb implements the shared database service contract against MongoDB.
log
Package log writes notable application events to ~/.config/perk-workbench/event.log.
Package log writes notable application events to ~/.config/perk-workbench/event.log.
sql
workbench/browse
Package browse owns the browse tab feature: the result table, page and sort/filter state, the row/document editors, the cell editor and viewer, the pager, and the pane rendering.
Package browse owns the browse tab feature: the result table, page and sort/filter state, the row/document editors, the cell editor and viewer, the pager, and the pane rendering.
workbench/chat
Package chat owns the AI assistant feature: the chat pane state (input, viewport, runs, tool rounds, slash completions, prompt history), rendering, context building, and read-only tool execution against the session service.
Package chat owns the AI assistant feature: the chat pane state (input, viewport, runs, tool rounds, slash completions, prompt history), rendering, context building, and read-only tool execution against the session service.
workbench/connection
Package connection owns the connection-screen feature: the profile form (values, validation, TLS modes, DSN building), the action buttons, the recent-profiles list and filter, profile add/edit/delete operations, and the pane rendering.
Package connection owns the connection-screen feature: the profile form (values, validation, TLS modes, DSN building), the action buttons, the recent-profiles list and filter, profile add/edit/delete operations, and the pane rendering.
workbench/notification
Package notification owns the notification feature: the scoped SQLite history store (with level migration and retention pruning) and the UI component — the popup, the history/detail overlays, the log-notification queue, and rendering.
Package notification owns the notification feature: the scoped SQLite history store (with level migration and retention pruning) and the UI component — the popup, the history/detail overlays, the log-notification queue, and rendering.
workbench/profile
Package profile owns connection profile persistence: the JSON record, UUIDv7 scope generation and validation, XDG path resolution, versioned AES-256-GCM at-rest encryption, secret-reference handling, and atomic hardened 0700/0600 saves.
Package profile owns connection profile persistence: the JSON record, UUIDv7 scope generation and validation, XDG path resolution, versioned AES-256-GCM at-rest encryption, secret-reference handling, and atomic hardened 0700/0600 saves.
workbench/querylog
Package querylog owns query-log history persistence: the scoped SQLite store, legacy migration, saved-queries import, and retention pruning.
Package querylog owns query-log history persistence: the scoped SQLite store, legacy migration, saved-queries import, and retention pruning.
workbench/schema
Package schema owns the schema sidebar and the structure/index/foreign-key tabs: the loaded schema tree with its filter and accordion animation, the structure tables and their filters, the column/index/foreign-key/table forms, and the relationship diagram.
Package schema owns the schema sidebar and the structure/index/foreign-key tabs: the loaded schema tree with its filter and accordion animation, the structure tables and their filters, the column/index/foreign-key/table forms, and the relationship diagram.
workbench/uikit
Package uikit holds the shared UI contracts and primitives of the workbench shell: keybinding scopes and the key matcher interface, the screen-layout snapshot passed to feature components, the typed events features emit for the root to act on, the theme palette, and the stateless table/viewport primitives shared by the root and the feature packages.
Package uikit holds the shared UI contracts and primitives of the workbench shell: keybinding scopes and the key matcher interface, the screen-layout snapshot passed to feature components, the typed events features emit for the root to act on, the theme palette, and the stateless table/viewport primitives shared by the root and the feature packages.
protocol
perk-v1
Package perkv1 embeds the canonical machine-readable perk/v1 contract: the JSON Schema document and the fixture frames plus their manifest, all under protocol/perk-v1.
Package perkv1 embeds the canonical machine-readable perk/v1 contract: the JSON Schema document and the fixture frames plus their manifest, all under protocol/perk-v1.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL