Everything in here is the build side of the app. What it does for the person using it is in README.md.
mise trust # once per clone: mise.toml carries a [settings] block
gh auth login # once per machine: make verify reads frankenphp's provenance over the API
make installThe toolchain via mise (node, go, composer and npm deps, the WebKit the browser checks
drive), plus the pinned Adminer and frankenphp downloads. On Linux it also runs
make linux-deps — the one step that needs apt, for the GTK/WebKit dev headers the webview
links against.
make run # build and open the window
make bundle # build.noindex/Adminer Desktop.app (icon, menu bar)
make zip # ...zipped, to hand to someone else
make dev # run, reloading the window on any change under app/
make demo # run logged into a seeded postgres (needs docker)Other targets: editor, logs, serve, down, destroy, dist, tarball, deb,
windows, clean. make on its own lists them.
make kill-orphansstops a server whose window is gone (crash, kill, Cmd+Q), the installed app's too.
make debug # run with Safari's Web Inspector attached- Safari → Develop → this machine → Adminer Desktop: console, DOM, network.
- Use it for anything visual or behavioural;
curlonly shows the generated HTML. - PHP errors:
~/Library/Logs/Adminer Desktop/(make logs). - Under
-debug,<data dir>/log/api.logrecords every call toapi.php.
make qa # php lint, phpstan, dresscode, golangci-lint, oxfmt, oxlint, shellcheck
make verify # adminer checksums + frankenphp's build provenance
make check # boots the app and asserts its behaviour before login
make e2e # Behat scenarios against postgres and mysql (needs docker)
make e2e-packaged # the same, against app/ as a release ships itmake check is the one that matters most: Adminer streams dumps with ob_flush(); flush(),
so it asserts long responses neither buffer nor time out, and it boots every shipped plugin in
turn. make e2e runs the Behat scenarios in tests/e2e/features/ in a real browser:
- A failed step leaves its page in
tests/e2e/artifacts/. - The folder decides the database:
data/runs on both,shell/(connections, settings, search, shortcuts, MCP) andpgsql/on postgres,mysql/on mysql. make e2e-visualshows the browser;SUITE=mysqlorARGS='--name …'narrows a run.- A step no context defines fails the run;
make qacatches one without docker. make e2e-packagedruns against app/ as a release ships it, so a template the build missed fails.- Manual testing covers what lives in the native shell (downloads), and the MCP bridge covers what an agent's call goes through, how to try it by hand, and its known weak spots.
CI is billed on this repo and macOS runners cost ten times the rest, so qa and check pass
locally before a push rather than being iterated against in Actions.
ADMINER_VERSION = 6.1.1
FRANKENPHP_VERSION = 1.13.3adminer.php, editor.php (compiled from its sources), 49 plugins and 28 designs all come from
that one Adminer tag, so
they cannot drift apart. Nothing ever resolves "latest", every download is checksum-verified,
and frankenphp is checked against the build provenance GitHub publishes for it.
Adminer itself is never edited. Behaviour changes go in the plugin the app loads alongside it,
and a fix to adminer goes upstream first and is carried in patches/ only until a release has
it — see patches/README.md.
app/ |
the document root: Adminer, and everything this app adds to it |
app/src/ |
the Desktop\ namespace, PSR-4 |
launcher/ |
the native shell (Go + Objective-C) — see its README |
tests/e2e/ |
the browser checks, one file per surface |
.docs/ |
this, and the Linux release story |
CLAUDE.md is the working guide to the codebase: the conventions, and the things that will bite. PLAN.md is why any of it is the way it is.