{"owner":"vrana","repo":"adminer","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"skills":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Commands\n\n**First-time setup:**\n```bash\ngit submodule update --init --recursive   # Initialize submodules (adminer/static/jush, conf/JsShrink, conf/PhpShrink)\ncomposer install                          # Does the same through the `submodules` script, plus PHPCS, PHPStan and the npm packages needed by ESLint\n```\n\n**Development server:**\n```bash\nphp -S 127.0.0.1:8000\n```\nBrowse to `http://127.0.0.1:8000/adminer/` for the dev version.\n\n**Build (compile single-file distribution):**\n```bash\ncomposer compile                   # All drivers, all languages → adminer.php\nphp compile.php mysql              # MySQL driver only\nphp compile.php mysql en           # MySQL + English only\nphp compile.php editor mysql       # Adminer Editor with MySQL\n```\n\n**Code quality:**\n```bash\ncomposer check                                     # Runs phpcs + phpstan + eslint\nvendor/bin/phpcs --standard=conf/phpcs.xml         # PHP code style (PSR-12 based, tab-indented)\nvendor/bin/phpstan analyse -c conf/phpstan.neon    # Static analysis (level 6)\n```\n\n**Clean:**\n```bash\ncomposer clean    # Remove all compiled adminer*.php and editor*.php\n```\n\n**Tests:** Browser-based end-to-end tests in `tests/*.spec.js`, one file per driver, run headless by `composer e2e` (Playwright, needs the dev server on `http://127.0.0.1:8000` and the database servers set up as described in `tests/README.md`; the `native` and `pdo` projects test both PHP extensions). Standalone unit tests: `tests/unit/compress.php` (string compression round-trip and pure-PHP inflate fallback), `tests/unit/host_port.php` (host:port parsing) and `tests/unit/url.php` (URL escaping) – they print errors and exit 0 when OK, run them all by `composer test` or individually by `php`.\n\n## Architecture\n\nAdminer is a database management tool deployable as a **single PHP file** (`adminer.php`), compiled from modular source by `compile.php`.\n\n### Entry points\n- `adminer/index.php` – dev version; routes requests via `$_GET` parameter presence (e.g., `?select=table`, `?indexes=table`, `?dump=`)\n- `editor/index.php` – Adminer Editor variant (data manipulation only, no DDL)\n- `adminer.php` – compiled single-file production version\n\n### Four main classes (`Adminer` namespace)\n- **`Adminer`** (`adminer/include/adminer.inc.php`) – ~80 overridable methods for all UI/behavior; this is what plugins hook into\n- **`Plugins`** (`adminer/include/plugins.inc.php`) – plugin manager; `__call()` chains registered plugins until one returns non-null\n- **`Driver`** (`adminer/include/driver.inc.php`) – database driver interface; static registry of available drivers\n- **`Db`** (`adminer/include/db.inc.php`) – low-level DB connection abstraction; always exactly one instance per driver\n\n### Plugin system\nPlugins are PHP classes implementing any methods from `Adminer`.\nThe `Plugins` manager discovers them from an `adminer-plugins/` directory or `adminer-plugins.php` file alongside the deployed PHP file.\nMost hooks short-circuit on first non-null return; `dumpFormat`, `dumpOutput`, `editRowPrint`, `editFunctions`, and `config` aggregate across all plugins.\n\nBuilt-in plugins live in `plugins/`. Plugin drivers (Elasticsearch, MongoDB, Redis, etc.) live in `plugins/drivers/`.\n\n### Driver system\nCore SQL drivers: `adminer/drivers/{mysql,pgsql,sqlite,mssql,oracle}.inc.php`\nPlugin drivers: `plugins/drivers/{elastic,mongo,redis,igdb,imap,firebird,clickhouse,simpledb}.php`\n\nEach driver registers via `add_driver(\"key\", \"Label\")` and implements a `Db` class with `attach()`, `quote()`, `select_db()`, `query()`.\n\n### Compilation\n`compile.php` inlines all `include` files, minifies CSS/JS, deflate-compresses translations, and optionally runs PhpShrink to strip PHP 7.4 type declarations (making the output PHP 5.3 compatible). Source requires PHP 7.4+.\n\n## Code Conventions (see docs/developing.md for full details)\n\n**Indentation:** Tabs, not spaces – `Generic.WhiteSpace.DisallowSpaceIndent` is enforced despite PSR-12 base.\n\n**Escaping:**\n- `h($val)` – HTML output (like `htmlspecialchars`, escaping `\"` and `'`)\n- `q($val)` – SQL string values\n- `idf_escape($val)` – SQL identifiers (column/table names)\n\n**Translations:** Always use `lang('...')` with **single quotes** – the string extractor requires literal single-quoted strings.\nPlugins must ship their own `$translations` array and call `$this->lang('...')`, even for a string that already exists in Adminer's translations.\nPlugins are not compiled but compilation converts core `lang()` identifiers to numbers, so `Adminer\\lang('...')` in a plugin silently returns untranslated English.\n\n**Array access:** Use bare `$_GET[\"key\"]` (not `isset()` or `??`). Adminer silences undefined-key warnings intentionally via `adminer/include/errors.inc.php`. Never use `$_REQUEST`.\n\n**Empty checks:** Use `$var != \"\"` not `!$var` – table names can be `\"0\"`, which is falsy.\n\n**Control flow:** Always use `{}` blocks. Use `elseif` (not `else if`).\n\n**Naming:** Functions and variables use `snake_case`; class methods use `camelCase` (except `Db` and driver classes which use `snake_case` to match mysqli conventions).\n\n**JavaScript:** ES6 (ES2015) only – no `?.`, `??`, `??=`, `async`/`await` or ES2017+ built-ins like `Object.entries()`, in `adminer/static/*.js`, `editor/static/*.js`, plugins and inline `script()`. Newer syntax is a parse error, so one modern token disables all of Adminer's JavaScript. `conf/eslint.config.mjs` pins `ecmaVersion` (it catches syntax, not built-ins). Browser APIs stay at the same generation (~Safari 10, Chrome 54, Firefox 50); feature-detect anything newer instead of using it outright – `fetch` and `navigator.clipboard` already are.\n\n**Comments:** `//!` = TODO, `//~` = debug code. Doc-comments are imperative (\"Get\" not \"Gets\"), no trailing period, `@param` only when type is more specific than the declaration.\n\n**Commit style:** `Area: Message` format (e.g., `MySQL: Fix connection timeout`). Bug fixes append `(fix #n)`. Update `CHANGELOG.md` with user-visible changes.\n\n**Changelog subsections:** A release section is the main list, optionally followed by `### Plugins` and `### Internal` – in this order, no blank line before a heading. The main list ends with the newly translated languages. `### Plugins` holds everything about plugins: the plugin API (a documented interface, so it belongs in the changelog), changes of bundled plugins prefixed `Plugin <name>: `, and `New plugin: ` – entries there are not prefixed `Plugins: `. `### Internal` is for changes a user cannot observe: build and compilation, dev tooling, tests, code organization, refactoring; compilation fixes with a visible symptom stay in the main list. Accessibility attributes, new translations and skin-affecting HTML/CSS restructuring are deliberately not recorded at all. (Releases before 5.0.0 also have a historic `### Customization`, the former name of the plugin API.)\n\n**CSS skins:** Default styles are `adminer/static/{default,dark}.css`, but users apply alternative skins by dropping an `adminer.css` (or `adminer-dark.css`) next to the deployed script. These skins target Adminer's HTML structure, class names, and IDs. Bundled examples live in `designs/`, but many more exist in the wild (gallery: https://www.adminer.org/#extras) and can't be updated in lockstep. Avoid breaking them: don't rename or drop existing selectors, IDs, or class names, or restructure HTML, without good reason – prefer additive changes.\n"},"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Commands\n\n**First-time setup:**\n```bash\ngit submodule update --init --recursive   # Initialize submodules (adminer/static/jush, conf/JsShrink, conf/PhpShrink)\ncomposer install                          # Does the same through the `submodules` script, plus PHPCS, PHPStan and the npm packages needed by ESLint\n```\n\n**Development server:**\n```bash\nphp -S 127.0.0.1:8000\n```\nBrowse to `http://127.0.0.1:8000/adminer/` for the dev version.\n\n**Build (compile single-file distribution):**\n```bash\ncomposer compile                   # All drivers, all languages → adminer.php\nphp compile.php mysql              # MySQL driver only\nphp compile.php mysql en           # MySQL + English only\nphp compile.php editor mysql       # Adminer Editor with MySQL\n```\n\n**Code quality:**\n```bash\ncomposer check                                     # Runs phpcs + phpstan + eslint\nvendor/bin/phpcs --standard=conf/phpcs.xml         # PHP code style (PSR-12 based, tab-indented)\nvendor/bin/phpstan analyse -c conf/phpstan.neon    # Static analysis (level 6)\n```\n\n**Clean:**\n```bash\ncomposer clean    # Remove all compiled adminer*.php and editor*.php\n```\n\n**Tests:** Browser-based end-to-end tests in `tests/*.spec.js`, one file per driver, run headless by `composer e2e` (Playwright, needs the dev server on `http://127.0.0.1:8000` and the database servers set up as described in `tests/README.md`; the `native` and `pdo` projects test both PHP extensions). Standalone unit tests: `tests/unit/compress.php` (string compression round-trip and pure-PHP inflate fallback), `tests/unit/host_port.php` (host:port parsing) and `tests/unit/url.php` (URL escaping) – they print errors and exit 0 when OK, run them all by `composer test` or individually by `php`.\n\n## Architecture\n\nAdminer is a database management tool deployable as a **single PHP file** (`adminer.php`), compiled from modular source by `compile.php`.\n\n### Entry points\n- `adminer/index.php` – dev version; routes requests via `$_GET` parameter presence (e.g., `?select=table`, `?indexes=table`, `?dump=`)\n- `editor/index.php` – Adminer Editor variant (data manipulation only, no DDL)\n- `adminer.php` – compiled single-file production version\n\n### Four main classes (`Adminer` namespace)\n- **`Adminer`** (`adminer/include/adminer.inc.php`) – ~80 overridable methods for all UI/behavior; this is what plugins hook into\n- **`Plugins`** (`adminer/include/plugins.inc.php`) – plugin manager; `__call()` chains registered plugins until one returns non-null\n- **`Driver`** (`adminer/include/driver.inc.php`) – database driver interface; static registry of available drivers\n- **`Db`** (`adminer/include/db.inc.php`) – low-level DB connection abstraction; always exactly one instance per driver\n\n### Plugin system\nPlugins are PHP classes implementing any methods from `Adminer`.\nThe `Plugins` manager discovers them from an `adminer-plugins/` directory or `adminer-plugins.php` file alongside the deployed PHP file.\nMost hooks short-circuit on first non-null return; `dumpFormat`, `dumpOutput`, `editRowPrint`, `editFunctions`, and `config` aggregate across all plugins.\n\nBuilt-in plugins live in `plugins/`. Plugin drivers (Elasticsearch, MongoDB, Redis, etc.) live in `plugins/drivers/`.\n\n### Driver system\nCore SQL drivers: `adminer/drivers/{mysql,pgsql,sqlite,mssql,oracle}.inc.php`\nPlugin drivers: `plugins/drivers/{elastic,mongo,redis,igdb,imap,firebird,clickhouse,simpledb}.php`\n\nEach driver registers via `add_driver(\"key\", \"Label\")` and implements a `Db` class with `attach()`, `quote()`, `select_db()`, `query()`.\n\n### Compilation\n`compile.php` inlines all `include` files, minifies CSS/JS, deflate-compresses translations, and optionally runs PhpShrink to strip PHP 7.4 type declarations (making the output PHP 5.3 compatible). Source requires PHP 7.4+.\n\n## Code Conventions (see docs/developing.md for full details)\n\n**Indentation:** Tabs, not spaces – `Generic.WhiteSpace.DisallowSpaceIndent` is enforced despite PSR-12 base.\n\n**Escaping:**\n- `h($val)` – HTML output (like `htmlspecialchars`, escaping `\"` and `'`)\n- `q($val)` – SQL string values\n- `idf_escape($val)` – SQL identifiers (column/table names)\n\n**Translations:** Always use `lang('...')` with **single quotes** – the string extractor requires literal single-quoted strings.\nPlugins must ship their own `$translations` array and call `$this->lang('...')`, even for a string that already exists in Adminer's translations.\nPlugins are not compiled but compilation converts core `lang()` identifiers to numbers, so `Adminer\\lang('...')` in a plugin silently returns untranslated English.\n\n**Array access:** Use bare `$_GET[\"key\"]` (not `isset()` or `??`). Adminer silences undefined-key warnings intentionally via `adminer/include/errors.inc.php`. Never use `$_REQUEST`.\n\n**Empty checks:** Use `$var != \"\"` not `!$var` – table names can be `\"0\"`, which is falsy.\n\n**Control flow:** Always use `{}` blocks. Use `elseif` (not `else if`).\n\n**Naming:** Functions and variables use `snake_case`; class methods use `camelCase` (except `Db` and driver classes which use `snake_case` to match mysqli conventions).\n\n**JavaScript:** ES6 (ES2015) only – no `?.`, `??`, `??=`, `async`/`await` or ES2017+ built-ins like `Object.entries()`, in `adminer/static/*.js`, `editor/static/*.js`, plugins and inline `script()`. Newer syntax is a parse error, so one modern token disables all of Adminer's JavaScript. `conf/eslint.config.mjs` pins `ecmaVersion` (it catches syntax, not built-ins). Browser APIs stay at the same generation (~Safari 10, Chrome 54, Firefox 50); feature-detect anything newer instead of using it outright – `fetch` and `navigator.clipboard` already are.\n\n**Comments:** `//!` = TODO, `//~` = debug code. Doc-comments are imperative (\"Get\" not \"Gets\"), no trailing period, `@param` only when type is more specific than the declaration.\n\n**Commit style:** `Area: Message` format (e.g., `MySQL: Fix connection timeout`). Bug fixes append `(fix #n)`. Update `CHANGELOG.md` with user-visible changes.\n\n**Changelog subsections:** A release section is the main list, optionally followed by `### Plugins` and `### Internal` – in this order, no blank line before a heading. The main list ends with the newly translated languages. `### Plugins` holds everything about plugins: the plugin API (a documented interface, so it belongs in the changelog), changes of bundled plugins prefixed `Plugin <name>: `, and `New plugin: ` – entries there are not prefixed `Plugins: `. `### Internal` is for changes a user cannot observe: build and compilation, dev tooling, tests, code organization, refactoring; compilation fixes with a visible symptom stay in the main list. Accessibility attributes, new translations and skin-affecting HTML/CSS restructuring are deliberately not recorded at all. (Releases before 5.0.0 also have a historic `### Customization`, the former name of the plugin API.)\n\n**CSS skins:** Default styles are `adminer/static/{default,dark}.css`, but users apply alternative skins by dropping an `adminer.css` (or `adminer-dark.css`) next to the deployed script. These skins target Adminer's HTML structure, class names, and IDs. Bundled examples live in `designs/`, but many more exist in the wild (gallery: https://www.adminer.org/#extras) and can't be updated in lockstep. Avoid breaking them: don't rename or drop existing selectors, IDs, or class names, or restructure HTML, without good reason – prefer additive changes.\n"},"items":[{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Commands\n\n**First-time setup:**\n```bash\ngit submodule update --init --recursive   # Initialize submodules (adminer/static/jush, conf/JsShrink, conf/PhpShrink)\ncomposer install                          # Does the same through the `submodules` script, plus PHPCS, PHPStan and the npm packages needed by ESLint\n```\n\n**Development server:**\n```bash\nphp -S 127.0.0.1:8000\n```\nBrowse to `http://127.0.0.1:8000/adminer/` for the dev version.\n\n**Build (compile single-file distribution):**\n```bash\ncomposer compile                   # All drivers, all languages → adminer.php\nphp compile.php mysql              # MySQL driver only\nphp compile.php mysql en           # MySQL + English only\nphp compile.php editor mysql       # Adminer Editor with MySQL\n```\n\n**Code quality:**\n```bash\ncomposer check                                     # Runs phpcs + phpstan + eslint\nvendor/bin/phpcs --standard=conf/phpcs.xml         # PHP code style (PSR-12 based, tab-indented)\nvendor/bin/phpstan analyse -c conf/phpstan.neon    # Static analysis (level 6)\n```\n\n**Clean:**\n```bash\ncomposer clean    # Remove all compiled adminer*.php and editor*.php\n```\n\n**Tests:** Browser-based end-to-end tests in `tests/*.spec.js`, one file per driver, run headless by `composer e2e` (Playwright, needs the dev server on `http://127.0.0.1:8000` and the database servers set up as described in `tests/README.md`; the `native` and `pdo` projects test both PHP extensions). Standalone unit tests: `tests/unit/compress.php` (string compression round-trip and pure-PHP inflate fallback), `tests/unit/host_port.php` (host:port parsing) and `tests/unit/url.php` (URL escaping) – they print errors and exit 0 when OK, run them all by `composer test` or individually by `php`.\n\n## Architecture\n\nAdminer is a database management tool deployable as a **single PHP file** (`adminer.php`), compiled from modular source by `compile.php`.\n\n### Entry points\n- `adminer/index.php` – dev version; routes requests via `$_GET` parameter presence (e.g., `?select=table`, `?indexes=table`, `?dump=`)\n- `editor/index.php` – Adminer Editor variant (data manipulation only, no DDL)\n- `adminer.php` – compiled single-file production version\n\n### Four main classes (`Adminer` namespace)\n- **`Adminer`** (`adminer/include/adminer.inc.php`) – ~80 overridable methods for all UI/behavior; this is what plugins hook into\n- **`Plugins`** (`adminer/include/plugins.inc.php`) – plugin manager; `__call()` chains registered plugins until one returns non-null\n- **`Driver`** (`adminer/include/driver.inc.php`) – database driver interface; static registry of available drivers\n- **`Db`** (`adminer/include/db.inc.php`) – low-level DB connection abstraction; always exactly one instance per driver\n\n### Plugin system\nPlugins are PHP classes implementing any methods from `Adminer`.\nThe `Plugins` manager discovers them from an `adminer-plugins/` directory or `adminer-plugins.php` file alongside the deployed PHP file.\nMost hooks short-circuit on first non-null return; `dumpFormat`, `dumpOutput`, `editRowPrint`, `editFunctions`, and `config` aggregate across all plugins.\n\nBuilt-in plugins live in `plugins/`. Plugin drivers (Elasticsearch, MongoDB, Redis, etc.) live in `plugins/drivers/`.\n\n### Driver system\nCore SQL drivers: `adminer/drivers/{mysql,pgsql,sqlite,mssql,oracle}.inc.php`\nPlugin drivers: `plugins/drivers/{elastic,mongo,redis,igdb,imap,firebird,clickhouse,simpledb}.php`\n\nEach driver registers via `add_driver(\"key\", \"Label\")` and implements a `Db` class with `attach()`, `quote()`, `select_db()`, `query()`.\n\n### Compilation\n`compile.php` inlines all `include` files, minifies CSS/JS, deflate-compresses translations, and optionally runs PhpShrink to strip PHP 7.4 type declarations (making the output PHP 5.3 compatible). Source requires PHP 7.4+.\n\n## Code Conventions (see docs/developing.md for full details)\n\n**Indentation:** Tabs, not spaces – `Generic.WhiteSpace.DisallowSpaceIndent` is enforced despite PSR-12 base.\n\n**Escaping:**\n- `h($val)` – HTML output (like `htmlspecialchars`, escaping `\"` and `'`)\n- `q($val)` – SQL string values\n- `idf_escape($val)` – SQL identifiers (column/table names)\n\n**Translations:** Always use `lang('...')` with **single quotes** – the string extractor requires literal single-quoted strings.\nPlugins must ship their own `$translations` array and call `$this->lang('...')`, even for a string that already exists in Adminer's translations.\nPlugins are not compiled but compilation converts core `lang()` identifiers to numbers, so `Adminer\\lang('...')` in a plugin silently returns untranslated English.\n\n**Array access:** Use bare `$_GET[\"key\"]` (not `isset()` or `??`). Adminer silences undefined-key warnings intentionally via `adminer/include/errors.inc.php`. Never use `$_REQUEST`.\n\n**Empty checks:** Use `$var != \"\"` not `!$var` – table names can be `\"0\"`, which is falsy.\n\n**Control flow:** Always use `{}` blocks. Use `elseif` (not `else if`).\n\n**Naming:** Functions and variables use `snake_case`; class methods use `camelCase` (except `Db` and driver classes which use `snake_case` to match mysqli conventions).\n\n**JavaScript:** ES6 (ES2015) only – no `?.`, `??`, `??=`, `async`/`await` or ES2017+ built-ins like `Object.entries()`, in `adminer/static/*.js`, `editor/static/*.js`, plugins and inline `script()`. Newer syntax is a parse error, so one modern token disables all of Adminer's JavaScript. `conf/eslint.config.mjs` pins `ecmaVersion` (it catches syntax, not built-ins). Browser APIs stay at the same generation (~Safari 10, Chrome 54, Firefox 50); feature-detect anything newer instead of using it outright – `fetch` and `navigator.clipboard` already are.\n\n**Comments:** `//!` = TODO, `//~` = debug code. Doc-comments are imperative (\"Get\" not \"Gets\"), no trailing period, `@param` only when type is more specific than the declaration.\n\n**Commit style:** `Area: Message` format (e.g., `MySQL: Fix connection timeout`). Bug fixes append `(fix #n)`. Update `CHANGELOG.md` with user-visible changes.\n\n**Changelog subsections:** A release section is the main list, optionally followed by `### Plugins` and `### Internal` – in this order, no blank line before a heading. The main list ends with the newly translated languages. `### Plugins` holds everything about plugins: the plugin API (a documented interface, so it belongs in the changelog), changes of bundled plugins prefixed `Plugin <name>: `, and `New plugin: ` – entries there are not prefixed `Plugins: `. `### Internal` is for changes a user cannot observe: build and compilation, dev tooling, tests, code organization, refactoring; compilation fixes with a visible symptom stay in the main list. Accessibility attributes, new translations and skin-affecting HTML/CSS restructuring are deliberately not recorded at all. (Releases before 5.0.0 also have a historic `### Customization`, the former name of the plugin API.)\n\n**CSS skins:** Default styles are `adminer/static/{default,dark}.css`, but users apply alternative skins by dropping an `adminer.css` (or `adminer-dark.css`) next to the deployed script. These skins target Adminer's HTML structure, class names, and IDs. Bundled examples live in `designs/`, but many more exist in the wild (gallery: https://www.adminer.org/#extras) and can't be updated in lockstep. Avoid breaking them: don't rename or drop existing selectors, IDs, or class names, or restructure HTML, without good reason – prefer additive changes.\n","category":"root","tokens":1889}]}