genericmilk/docudoodle
AI-powered PHP documentation generator that analyzes your codebase and writes clear Markdown docs. Skips existing docs, caches unchanged files to cut costs, and helps teams quickly understand legacy apps. Supports multiple providers (OpenAI, Claude, Gemini, Azure, Ollama).
Installation:
composer require genericmilk/docudoodle
php artisan vendor:publish --tag=docudoodle-config
Publish the config file to customize settings in config/docudoodle.php.
Configure API Key:
Add your OpenAI (or alternative provider) key to .env:
OPENAI_API_KEY=sk-your-key-here
DOCUDOODLE_API_PROVIDER=openai # or 'claude', 'gemini', 'azure', 'ollama'
First Run:
php artisan docudoodle:generate
Outputs Markdown files to storage/docudoodle (configurable).
Document a Legacy Laravel App:
php artisan docudoodle:generate --skip-dirs="vendor/,node_modules/,tests/"
app/, config/, and routes/.Post-Feature Documentation:
php artisan docudoodle:generate --force-rebuild
Incremental Updates:
php artisan docudoodle:generate --no-cache
Team Onboarding:
php artisan docudoodle:generate --output-dir=docs/onboarding
--jira or --confluence for centralized access.CI/CD Pipeline:
Add to phpunit.xml or GitHub Actions:
<php>
<env name="OPENAI_API_KEY" value="${{ secrets.OPENAI_API_KEY }}" />
</php>
Run as a post-commit hook or scheduled job.
Laravel Events:
Trigger docs generation after ModelCreated or MigrationRan:
use GenericMilk\Docudoodle\Facades\Docudoodle;
event(new ModelCreated(User::class));
Docudoodle::generate(['app/Models/User.php']);
Custom Prompts:
Extend the default template (resources/docudoodle/templates/default.md) to include:
## Security Notes
{# if contains(FILE_CONTENT, 'password') #}
- **Sensitive Data**: Ensure encryption is applied to `{BASE_NAME}` fields.
{/if #}
API Rate Limits:
429 Too Many Requests errors.max_tokens in config/docudoodle.php or use --no-cache to batch requests.DOCUDOODLE_DEBUG=true in .env.Wildcard Skip Directories:
skip_dirs with * (e.g., tests/*/) may not work as expected.DocudoodleServiceProvider.Ollama Offline Mode:
if (!Docudoodle::isOllamaRunning()) {
throw new \RuntimeException('Ollama service unavailable. Docs skipped.');
}
Cache Issues:
.docudoodle_cache.json to force a full rebuild.cache_file_path is writable:
chmod 666 storage/docudoodle/.docudoodle_cache.json
Template Errors:
php artisan docudoodle:generate --debug
{# #} blocks or invalid variables.Custom Output Formats:
Override GenericMilk\Docudoodle\Services\MarkdownRenderer to generate HTML/PDF:
class HtmlRenderer extends MarkdownRenderer {
protected function renderContent(string $content): string {
return (new \ParsedownExtra())->text($content);
}
}
Pre/Post-Processing:
Hook into the docudoodle.generated event:
Docudoodle::generate(['app/Http/Controllers/*.php']);
event(new \GenericMilk\Docudoodle\Events\DocumentationGenerated(
'app/Http/Controllers/',
'storage/docudoodle/controllers'
));
Azure OpenAI:
DOCUDOODLE_AZURE_EMBEDDINGS=true for vector search integration.azure_api_version matches your deployment’s API version.'concurrency_limit' => 3, // in config/docudoodle.php
skip_dirs:
'skip_dirs' => [
'vendor/*',
'database/migrations/*', // Often verbose
],
DOCUDOODLE_CACHE_DRIVER=file for faster reprocessing.Service Provider Binding: If using Laravel’s service container, bind the Docudoodle facade:
$this->app->bind('docudoodle', function ($app) {
return new \GenericMilk\Docudoodle\Docudoodle(
$app['config']['docudoodle']
);
});
Artisan Command Conflicts:
Avoid naming custom commands docudoodle:generate to prevent conflicts.
File System Permissions:
Ensure storage/docudoodle is writable:
mkdir -p storage/docudoodle && chmod -R 775 storage/docudoodle
How can I help you explore Laravel packages today?