Configuration Reference
Maintainer resolves the consuming Composer project’s root automatically and reads project values from its config directory even when invoked from vendor/bin or another subdirectory. Use Publish Configuration to create these files with per-file overwrite protection.
The published file starts with Maintainer’s current defaults:
<?php
use ArtisanToolbox\Maintainer\Quality\Contracts\RunsPestCheck;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsPhpStanCheck;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsPintCheck;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsPintFix;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsRectorFix;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsVitePlusCheck;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsVitePlusCheckFix;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsVitePlusTest;use ArtisanToolbox\Maintainer\Quality\Contracts\RunsVueTscCheck;
return [ 'ai' => [ 'providers' => [ 'commit_message' => env('MAINTAINER_AI_COMMIT_MESSAGE_PROVIDER', 'openai'), 'release_type_suggestion' => env('MAINTAINER_AI_RELEASE_TYPE_SUGGESTION_PROVIDER', 'openai'), 'release_notes' => env('MAINTAINER_AI_RELEASE_NOTES_PROVIDER', 'openai'), 'release_changelog_update' => env('MAINTAINER_AI_RELEASE_CHANGELOG_UPDATE_PROVIDER', 'openai'), ], ], 'git' => [ 'diff' => [ 'output_format' => env('MAINTAINER_GIT_DIFF_OUTPUT_FORMAT', 'line_by_line'), ], ], 'quality' => [ 'fix' => [ RunsPintFix::class, RunsRectorFix::class, RunsVitePlusCheckFix::class, ], 'test' => [ RunsPestCheck::class, RunsPintCheck::class, RunsVitePlusCheck::class, RunsVitePlusTest::class, RunsVueTscCheck::class, RunsPhpStanCheck::class, ], 'pest' => [ 'parallel' => env('MAINTAINER_PEST_PARALLEL', false), ], 'phpstan' => [ 'memory_limit' => env('MAINTAINER_PHPSTAN_MEMORY_LIMIT', '2G'), ], ],];The quality.fix and quality.test lists use readable public command contracts under ArtisanToolbox\Maintainer\Quality\Contracts. Their names describe intent, such as RunsPintFix and RunsPintCheck, instead of exposing generic implementation names. Composer explicitly exports the quality and versioning contracts, SSH helpers, encryption support, and Deployer integration without exposing the package’s complete app/ directory. Maintainer resolves every quality contract to its bundled implementation at runtime. Project configuration must use these contracts instead of the private App\... implementation namespace.
The four ai.providers values select the Laravel AI provider used for commit messages, release type suggestions, release notes, and release changelog updates. Every configured release agent delegates model selection to the provider’s cheapest compatible model through Laravel AI’s UseCheapestModel attribute.
Encryption
Section titled “Encryption”Maintainer provides Laravel’s authenticated encryption layer through the Crypt::encryptString() and Crypt::decryptString() methods and the global encrypt() and decrypt() helpers. The AES-256-CBC encrypter requires maintainer_secrets.key only when encryption or decryption is requested. Every distributed secrets template contains that key and uses env('APP_KEY') as its default value:
use Illuminate\Support\Facades\Crypt;
$encrypted = Crypt::encryptString($privateKey);$privateKey = Crypt::decryptString($encrypted);The key may be a 32-byte value or Laravel’s conventional base64:-prefixed representation. Calling an encryption API without a non-empty maintainer_secrets.key throws Illuminate\Encryption\MissingAppKeyException with instructions to configure maintainer_secrets.key or APP_KEY. Invalid key lengths are rejected by Laravel’s encrypter.
Changing the key makes existing ciphertext unreadable. Keep APP_KEY outside the PHAR and source control, and provide it through the consuming project’s .env, the operating system, CI secrets, or another secret manager.
Environment variables
Section titled “Environment variables”Maintainer configuration supports Laravel’s conventional env() helper. The distributed templates use environment-backed values with working defaults, so projects may configure Maintainer in PHP, in their root .env, or through operating-system and CI environment variables.
For example:
MAINTAINER_AI_COMMIT_MESSAGE_PROVIDER=anthropicMAINTAINER_GIT_DIFF_OUTPUT_FORMAT=side_by_sideMAINTAINER_PEST_PARALLEL=trueMAINTAINER_PHPSTAN_MEMORY_LIMIT=4GAPP_KEY=base64:your-32-byte-key-encoded-as-base64OPENAI_API_KEY=your-api-keyMaintainer loads the .env from the consuming Composer project while evaluating its project configuration files. Variables already supplied by the operating system, CI, or Laravel Zero take precedence over values in that file; the second argument to env() remains the final fallback. Values loaded from the project file are scoped to configuration evaluation and are not exported to quality tools, deployment commands, or other subprocesses. Each delegated tool can therefore apply its own environment rules. As in a Laravel application, use env() only inside configuration files.
The configuration templates expose these variables:
APP_KEYas the default for the requiredmaintainer_secrets.key;MAINTAINER_AI_COMMIT_MESSAGE_PROVIDER;MAINTAINER_AI_RELEASE_TYPE_SUGGESTION_PROVIDER;MAINTAINER_AI_RELEASE_NOTES_PROVIDER;MAINTAINER_AI_RELEASE_CHANGELOG_UPDATE_PROVIDER;MAINTAINER_GIT_DIFF_OUTPUT_FORMAT;MAINTAINER_PEST_PARALLEL;MAINTAINER_PHPSTAN_MEMORY_LIMIT.
Secrets
Section titled “Secrets”Publishing Maintainer secrets creates config/maintainer_secrets.php and can add that path to the project’s .gitignore without creating duplicate entries. Like other PHP configuration files, it returns an array. Its required encryption key defaults to the Laravel application key:
<?php
return [ 'key' => env('APP_KEY'), 'ssh_key' => null, // AI provider credentials...];The secrets template contains every provider supported by the installed Laravel AI SDK. Add credentials only for providers the project uses. Provider values may include connection settings such as an endpoint in addition to an API key.
For Laravel applications, publishing Maintainer secrets through config:publish also generates an OpenSSH Ed25519 key. Maintainer asks for the owner’s email, embeds it as the SSH key comment, generates the key without an SSH passphrase, encrypts the complete private key with maintainer_secrets.key, and stores only that ciphertext under ssh_key. A valid encryption key must therefore be available through maintainer_secrets.key or its APP_KEY default before publishing application secrets.
Laravel packages skip the email prompt and SSH identity generation because they do not normally have an application encryption key. Their published secrets file keeps both key and ssh_key nullable until the project explicitly provides them. This does not affect code-quality workflows; deployment and SSH display commands require a configured encrypted identity.
The public key is never stored. It is deterministically derived from the decrypted private key when requested.
Maintainer uses phpseclib’s OpenSSH implementation and does not require the ssh-keygen executable or make the Sodium PHP extension mandatory. Environments with an available cryptographic acceleration engine may use it, while phpseclib retains a portable PHP implementation.
The secrets template uses the Laravel AI environment names, including ANTHROPIC_API_KEY, AZURE_OPENAI_*, AWS_*, COHERE_API_KEY, DEEPSEEK_API_KEY, ELEVENLABS_API_KEY, GEMINI_API_KEY, GROQ_API_KEY, JINA_API_KEY, MISTRAL_API_KEY, OLLAMA_*, OPENAI_API_KEY, OPENAI_COMPATIBLE_*, OPENROUTER_API_KEY, VOYAGEAI_API_KEY, and XAI_API_KEY. Values may still be written directly in the PHP array when environment configuration is not desired.
Content-generation workflows require a provider that supports text: anthropic, azure, bedrock, deepseek, gemini, groq, mistral, ollama, openai, openai-compatible, openrouter, or xai. Providers intended only for audio, embeddings, or reranking remain available in the template but are rejected for text workflows with an actionable error.
Defaults and project values
Section titled “Defaults and project values”Maintainer keeps its distributed defaults in its own config/maintainer.php and config/maintainer_secrets.php files and merges them with the consuming project’s corresponding configuration at runtime. Associative configuration is merged recursively, while ordered lists such as quality.fix and quality.test are replaced as complete values. Project values take precedence, while options introduced by newer Maintainer versions remain available to projects created with older configuration files. Projects without config/maintainer.php use all current non-secret defaults without creating a file automatically.
Maintainer reads these values internally with dot notation and caches them for the lifetime of its process. The internal configuration service is not part of the consuming project’s namespace or public API. Edit the PHP configuration or its referenced environment variables to change workflow behavior. A configuration file that fails to load or does not return an associative array raises an actionable exception.
Legacy JSON configuration
Section titled “Legacy JSON configuration”Maintainer continues reading root-level maintainer.json and maintainer_secrets.json files for backward compatibility when their PHP replacements do not exist. Use config:publish to create the current PHP configuration, then move any legacy project-specific values into the published arrays before removing the JSON files.

