{"id":50645373,"url":"https://github.com/rtcoder/devdoctor","last_synced_at":"2026-06-07T12:01:26.977Z","repository":{"id":360778134,"uuid":"1251420119","full_name":"rtcoder/devdoctor","owner":"rtcoder","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-04T21:21:27.000Z","size":439,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-04T21:35:56.673Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://rtcoder.github.io/devdoctor/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rtcoder.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-27T15:00:20.000Z","updated_at":"2026-06-04T21:21:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/rtcoder/devdoctor","commit_stats":null,"previous_names":["rtcoder/devdoctor"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/rtcoder/devdoctor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtcoder%2Fdevdoctor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtcoder%2Fdevdoctor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtcoder%2Fdevdoctor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtcoder%2Fdevdoctor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rtcoder","download_url":"https://codeload.github.com/rtcoder/devdoctor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rtcoder%2Fdevdoctor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34020187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-07T02:00:07.652Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-07T12:01:25.500Z","updated_at":"2026-06-07T12:01:26.964Z","avatar_url":"https://github.com/rtcoder.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DevDoctor\n\nDeveloper diagnostics for humans.\n\nDevDoctor is a read-only CLI for catching common local, repository, environment, cache, HTTP URL, database, queue, Docker, Composer, Git, Node/frontend, Flutter/Dart, native mobile, monorepos, Python, Ruby/Rails, Go, Rust, Java/JVM, Terraform/IaC, Kubernetes/Helm, .NET, C/C++, generic web, and CI problems before they turn into manual debugging sessions.\n\nCurrent version: `1.40.0`\n\n## Installation\n\nDevDoctor requires PHP 8.5 or newer.\n\n```bash\ncomposer install\nphp devdoctor list\n```\n\nDevDoctor currently runs from the project checkout:\n\n```bash\nphp devdoctor \u003ccommand\u003e\n```\n\nBuild a local PHAR:\n\n```bash\nphp devdoctor app:build devdoctor.phar --build-version=1.40.0 --no-interaction\nphp builds/devdoctor.phar --version\n```\n\nTagged releases publish both the PHAR and PHPacker standalone binaries for Linux, macOS, and Windows. The standalone binaries bundle a PHP runtime, so users do not need PHP installed just to run DevDoctor.\n\nInstall as a Composer package:\n\n```bash\ncomposer global require rtcoder/devdoctor\ndevdoctor --version\n```\n\nInstall locally in a project:\n\n```bash\ncomposer require --dev rtcoder/devdoctor\nvendor/bin/devdoctor ci\n```\n\n## Commands\n\n```text\nenv        Check dotenv files and DevDoctor env rules\ncache     Check framework and tool cache health\nhttp      Check HTTP URL configuration\nports      Check local development port conflicts\ncomposer   Check Composer project health\ndeps       Check Composer and Node dependency health\ndb         Check database environment configuration\nqueue      Check queue environment configuration\nphp        Check PHP runtime and platform health\nnode       Check Node.js project and package manager health\nfrontend   Check frontend project presets and build readiness\nflutter    Check Flutter and Dart pubspec, lockfile, SDK constraints, dependency sources, and platform markers\nmobile     Check native Android and iOS project markers, wrappers, debug flags, and lockfiles\nmonorepo   Check monorepo tooling, workspace lockfiles, and root package scripts\npython     Check Python manifests and dependency manager health\nruby       Check Ruby and Rails manifests, lockfiles, versions, credentials, and dependency sources\ngo         Check Go module and workspace health\nrust       Check Rust Cargo manifest and workspace health\njava       Check Java/JVM Maven, Gradle, Ant, and Spring health\niac        Check Terraform, OpenTofu, and Terragrunt manifests, locks, modules, and secret hygiene\nkube       Check Kubernetes manifests and Helm charts, locks, images, services, and secret hygiene\ndotnet     Check .NET solution, project, SDK, lockfile, and NuGet health\ncpp        Check C/C++ build files, dependency managers, and portability risks\nweb        Check generic web entry files, assets, public config, and server hints\nlaravel    Check Laravel application health\nsymfony    Check Symfony application env, runtime directories, recipes, and Composer scripts\nsecurity   Check project security posture\ngit        Check Git repository hygiene\ndocker     Check Docker and Docker Compose project health\nhealth     Run a broad local project health check\ndoctor     Alias for health\nci         Run CI-safe DevDoctor diagnostics\npresets    Detect supported project framework and tooling presets\ninventory  Show detected presets and available modules\ncommands   List DevDoctor commands and documentation metadata\nversion    Show the current DevDoctor version\nexplain    Explain DevDoctor issue codes and hints\npolicy     Show DevDoctor safety and compatibility policy\nsupport-bundle Print a redacted support bundle without writing files\nself-update Check for a newer DevDoctor release and show or run the safest update command\ninit       Generate an initial devdoctor.yml configuration\n```\n\nAll public commands support the shared options:\n\n```bash\n--path=. --format=table --ci --strict\n```\n\nDiagnostic commands also support output shaping without changing the underlying exit code:\n\n```bash\n--only=error,warning\n--summary-only\n--no-hints\n```\n\nSupported diagnostic output formats are `table`, `json`, and `sarif`.\n\nLaravel Zero already defines a global `--env` option, so DevDoctor exposes the env-file selector as `--env-file`:\n\n```bash\nphp devdoctor env --env-file=.env.local --example=.env.example\n```\n\n## Examples\n\n```bash\nphp devdoctor env\nphp devdoctor env --format=json --strict\nphp devdoctor env --only=error,warning --no-hints\nphp devdoctor health --summary-only\nphp devdoctor cache\nphp devdoctor cache --max-size=1024\nphp devdoctor http\nphp devdoctor http --url=https://example.test\nphp devdoctor ports --common\nphp devdoctor ports --port=3000 --port=5173\nphp devdoctor php\nphp devdoctor php --ci --minimum-memory=256\nphp devdoctor node\nphp devdoctor frontend\nphp devdoctor flutter\nphp devdoctor mobile\nphp devdoctor monorepo\nphp devdoctor python\nphp devdoctor ruby\nphp devdoctor go\nphp devdoctor rust\nphp devdoctor java\nphp devdoctor iac\nphp devdoctor kube\nphp devdoctor dotnet\nphp devdoctor cpp\nphp devdoctor web\nphp devdoctor laravel\nphp devdoctor symfony\nphp devdoctor security\nphp devdoctor composer\nphp devdoctor deps\nphp devdoctor inventory --format=json\nphp devdoctor commands --format=json\nphp devdoctor version --format=json\nphp devdoctor explain DD_ENV_FILE_MISSING --format=json\nphp devdoctor policy --format=json\nphp devdoctor support-bundle\nphp devdoctor self-update\nphp devdoctor db\nphp devdoctor db --connect\nphp devdoctor queue\nphp devdoctor git --require-clean --scan-large-files\nphp devdoctor docker --compose-file=docker-compose.yml\nphp devdoctor health\nphp devdoctor health --include-ports\nphp devdoctor doctor --summary-only\nphp devdoctor ci --modules=env,php,node,laravel,composer,db,git,docker --no-fail-on-warnings\nphp devdoctor presets --format=json\nphp devdoctor init --dry-run\n```\n\n`ports` uses platform-specific read-only providers: `lsof` on macOS/Linux, `ss` as a Linux fallback, and `netstat -ano` on Windows. If no supported provider is available, DevDoctor reports `DD_PORT_PROVIDER_UNAVAILABLE` instead of failing unexpectedly.\n\n## Platform Support\n\nDevDoctor targets Linux, macOS, and Windows:\n\n| Capability | Linux | macOS | Windows |\n| --- | --- | --- | --- |\n| Command discovery | Native executable lookup | Native executable lookup | Native executable lookup |\n| Port listeners | `lsof`, then `ss` | `lsof` | `netstat -ano` |\n| Process suggestion | `kill -TERM \u003cpid\u003e` | `kill -TERM \u003cpid\u003e` | `taskkill /PID \u003cpid\u003e` |\n| Cache diagnostics | Supported | Supported | Supported |\n| HTTP URL diagnostics | Supported | Supported | Supported |\n| PHP runtime diagnostics | Supported | Supported | Supported |\n| Node.js project diagnostics | Supported | Supported | Supported |\n| Frontend project diagnostics | Supported | Supported | Supported |\n| Python project diagnostics | Supported | Supported | Supported |\n| Ruby/Rails diagnostics | Supported | Supported | Supported |\n| Go module diagnostics | Supported | Supported | Supported |\n| Rust Cargo diagnostics | Supported | Supported | Supported |\n| Java/JVM diagnostics | Supported | Supported | Supported |\n| Terraform/IaC diagnostics | Supported | Supported | Supported |\n| .NET diagnostics | Supported | Supported | Supported |\n| C/C++ diagnostics | Supported | Supported | Supported |\n| Generic web diagnostics | Supported | Supported | Supported |\n| Laravel application diagnostics | Supported | Supported | Supported |\n| Symfony application diagnostics | Supported | Supported | Supported |\n| Security posture diagnostics | Supported | Supported | Supported |\n| Database configuration diagnostics | Supported | Supported | Supported |\n| Database connection diagnostics | Supported when the matching PDO driver is installed | Supported when the matching PDO driver is installed | Supported when the matching PDO driver is installed |\n| Queue configuration diagnostics | Supported | Supported | Supported |\n| Composer, Git, Docker | Supported when their executables are installed | Supported when their executables are installed | Supported when their executables are installed |\n\nPlatform-specific commands are only suggested. DevDoctor never terminates a process automatically.\n\n## Diagnostic Details\n\n- Compose interpolation understands required references such as `${VAR}` and `${VAR?message}`.\n- Compose references with defaults such as `${VAR:-default}` and `${VAR-default}` do not produce missing-variable warnings.\n- Git reports `DD_GIT_BINARY_MISSING` when Git is unavailable instead of treating the path as a non-repository.\n- Windows port diagnostics use `tasklist` when available to resolve a PID to a process name.\n- Cache diagnostics inspect known Laravel, Symfony, and Node cache directories, size thresholds, writability, and Laravel cache artifacts without deleting anything.\n- HTTP diagnostics validate configured `APP_URL`, `FRONTEND_URL`, `API_URL`, and explicit `--url` values without making network requests.\n- PHP diagnostics compare the active CLI runtime with `composer.json`, required `ext-*` packages, `memory_limit`, loaded `php.ini`, and Xdebug state in CI.\n- Node.js diagnostics inspect `package.json`, npm/Yarn/pnpm/Bun lockfiles, stale lockfiles, `node_modules`, `engines.node`, `.nvmrc`, `.node-version`, and risky package scripts.\n- Frontend diagnostics inspect Vite, Next.js, Nuxt, Astro, React, Vue, Svelte, Angular, and generic static frontend evidence without running builds.\n- Flutter diagnostics inspect `pubspec.yaml`, `pubspec.lock`, Dart SDK constraints, local path/Git dependency sources, and Flutter platform markers without running `flutter pub get` or builds.\n- Mobile diagnostics inspect native Android/iOS markers, Gradle wrappers, Android debug flags, CocoaPods locks, and iOS debug entitlements without running Gradle, Xcode, or CocoaPods.\n- Monorepo diagnostics inspect Nx, Turbo, Lerna, pnpm workspaces, Rush, Bazel, Pants, workspace lockfiles, and root package scripts without running orchestrators or package managers.\n- Utility commands expose project inventory, issue-code explanations, safety policy, and redacted support bundles without modifying project files.\n- Python diagnostics inspect `pyproject.toml`, `requirements*.txt`, `Pipfile`, `poetry.lock`, `uv.lock`, and Conda files without installing packages.\n- Ruby diagnostics inspect `Gemfile`, `Gemfile.lock`, `.ruby-version`, Rails credentials, `config/database.yml`, and risky gem sources without running Bundler or Rails.\n- Go diagnostics inspect `go.mod`, `go.sum`, `go.work`, local `replace` directives, toolchain declarations, and vendor metadata without running `go mod tidy` or downloading modules.\n- Rust diagnostics inspect `Cargo.toml`, `Cargo.lock`, workspaces, `rust-toolchain.toml`, local path/git dependencies, and release profile settings without running Cargo.\n- Java diagnostics inspect Maven, Gradle, Ant, wrappers, Java version declarations, risky build scripts, and Spring production debug flags without running builds or dependency resolution.\n- IaC diagnostics inspect Terraform, OpenTofu, and Terragrunt files, provider lockfiles, provider version constraints, remote module refs, backend/provider secrets, and secret-like variable defaults without running `init`, `plan`, or network access.\n- Kubernetes diagnostics inspect manifests, Helm charts, values files, image tags, service exposure, hostPath mounts, and privileged containers without running `kubectl`, `helm`, or cluster queries.\n- .NET diagnostics inspect `.sln`, project files, `global.json`, `NuGet.config`, `packages.lock.json`, target frameworks, and restore lock mode without running `dotnet restore`, `build`, or `test`.\n- C/C++ diagnostics inspect CMake, Make, Meson, Autotools, vcpkg, Conan, compile command metadata, in-source build artifacts, compiler flags, generator assumptions, and shell portability risks without compiling code.\n- Generic web diagnostics inspect static entry files, obvious asset references, public config files, web server config hints, and conflicting local port declarations without running a build.\n- Laravel diagnostics inspect `.env`, `APP_KEY`, production debug mode, `APP_URL`, runtime directories, and config cache state.\n- Symfony diagnostics inspect `.env`/`.env.local`, `APP_SECRET`, production debug mode, runtime cache/log directories, Symfony Flex recipe drift, and Symfony Composer script risks without running `bin/console`.\n- Database diagnostics inspect `DB_CONNECTION`, required database keys, valid ports, SQLite file paths, and optional read-only PDO connectivity with `--connect`.\n- Queue diagnostics inspect `QUEUE_CONNECTION`, common async driver requirements, and production environments that still use the synchronous queue driver.\n- Security diagnostics inspect env example secrets, hard-coded secret patterns, risky Composer and package scripts, Docker privileged mode, Docker socket mounts, and `.env` ignore gaps.\n- Health aggregates local project diagnostics across `presets`, `env`, `cache`, `http`, `php`, `node`, `laravel`, `composer`, `db`, `queue`, `git`, `docker`, and `security`; it adds `frontend`, `flutter`, `mobile`, `monorepo`, `python`, `ruby`, `go`, `rust`, `java`, `iac`, `kube`, `dotnet`, `cpp`, `web`, and `symfony` automatically when matching presets are detected. Add `--include-ports` to include common local port checks.\n- Composer reports `DD_COMPOSER_LOCK_OUTDATED` when `composer.lock` is older than `composer.json`.\n- Process execution uses argument arrays and supports project paths containing spaces.\n\n## Project Presets\n\nThe `presets` command detects supported project stacks from files and declared dependencies without running project tools:\n\n| Preset | Detection evidence |\n| --- | --- |\n| Laravel | `laravel/framework` or `artisan` |\n| Symfony | `symfony/framework-bundle` or `bin/console` |\n| Node.js | `package.json` |\n| Frontend | frontend package dependencies, `index.html`, or common app entry files |\n| Vite | `vite` dependency or a `vite.config.*` file |\n| Next.js | `next` dependency |\n| Nuxt | `nuxt` dependency |\n| Astro | `astro` dependency |\n| Flutter / Dart | `pubspec.yaml`, `pubspec.lock`, `.metadata`, or Flutter SDK dependency |\n| Mobile native | Android manifests/build files, `Podfile`, `Podfile.lock`, or Xcode project markers |\n| Monorepo | `nx.json`, `turbo.json`, `lerna.json`, `pnpm-workspace.yaml`, `rush.json`, Bazel, Pants, or package workspaces |\n| Python | `pyproject.toml`, `requirements*.txt`, `Pipfile`, `uv.lock`, or Conda files |\n| pip / Poetry / Pipenv / uv / Conda | their lockfiles or manifests |\n| Ruby / Rails | `Gemfile`, `.ruby-version`, `config/application.rb`, or `bin/rails` |\n| Go | `go.mod` or `go.work` |\n| Rust | `Cargo.toml`, `Cargo.lock`, or `rust-toolchain.toml` |\n| Java/JVM | Maven, Gradle, or Ant build files |\n| Maven / Gradle / Ant / Spring | wrapper/build files or Spring Boot references |\n| IaC / Terraform | `*.tf`, `*.tfvars`, `.terraform.lock.hcl`, `tofu.lock.hcl`, or `terragrunt.hcl` |\n| Kubernetes / Helm | Kubernetes manifests, `Chart.yaml`, `Chart.lock`, `helmfile.yaml`, `kustomization.yaml`, or `values.yaml` |\n| C/C++ | CMake, Make, Meson, Autotools, vcpkg, or Conan files |\n| CMake | `CMakeLists.txt` |\n| .NET | solution/project files, `global.json`, or `NuGet.config` |\n| Generic web | static entry files, web server config, or frontend evidence |\n| Docker Compose | A supported Compose file |\n\n`v1.24.0` ships `devdoctor iac` with static diagnostics for Terraform, OpenTofu, and Terragrunt manifests, provider lockfiles, broad provider constraints, unpinned remote modules, and secret-like IaC values.\n\n`v1.25.0` ships `devdoctor kube` with static diagnostics for Kubernetes manifests and Helm charts. It checks Helm dependency locks, literal secrets in values files, mutable image tags, privileged containers, hostPath mounts, and NodePort service exposure without running `kubectl` or `helm`.\n\n`v1.26.0` ships `devdoctor flutter` with static diagnostics for Flutter and Dart projects. It checks pubspec lockfiles, Dart SDK constraints, path/Git dependencies, and platform markers without running Flutter commands or builds.\n\n`v1.27.0` ships `devdoctor mobile` with static diagnostics for native Android and iOS projects. It checks Gradle wrapper presence, Android debuggable manifests, CocoaPods lockfiles, and iOS debug entitlements without running platform build tools.\n\n`v1.28.0` ships `devdoctor monorepo` with static diagnostics for workspace tooling. It checks mixed orchestration tools, missing workspace lockfiles, and risky root scripts without running monorepo commands.\n\n`v1.29.0` ships utility commands: `inventory`, `explain`, `policy`, and `support-bundle`. They help inspect detected stacks, understand issue codes, review DevDoctor safety policy, and print redacted support context without writing files.\n\n`v1.30.0` ships documentation automation and a richer documentation site. The issue code catalog is generated from `schemas/v1/issue-codes.json`, includes filtering and copy controls, and the docs include scenario guides for Laravel, frontend, monorepo, and CI baseline rollout.\n\n`v1.31.0` adds documentation navigation polish with active navigation, breadcrumbs, copy buttons for command snippets, and additional scenario guides for Python, Kubernetes/Helm, Terraform/IaC, Symfony, and mobile projects.\n\n`v1.32.0` adds machine-readable documentation metadata with `docs/manifest.json` and `docs/commands.json` so tools can consume page and command references without scraping HTML.\n\n`v1.33.0` adds CLI discoverability with `devdoctor commands` and `devdoctor explain --module=...`, making command metadata and issue-code hints available without leaving the terminal.\n\n`v1.34.0` adds CI policy profiles: `local`, `ci`, `strict-ci`, and `security`, with documented defaults for warning handling, strict mode, and module selection.\n\n`v1.35.0` adds `--baseline-report` for CI baselines, showing active, suppressed, and resolved fingerprint counts without hiding findings.\n\n`v1.36.0` adds a manual `Update Homebrew Tap` workflow for publishing or repairing the Homebrew formula for an existing release after `HOMEBREW_TAP_TOKEN` is configured.\n\n`v1.37.0` adds update checks for interactive table output and `devdoctor self-update`, which reports the current version, the latest release, and the safest update command for the detected installation method.\n\n`v1.38.0` polishes the composite GitHub Action metadata for GitHub Marketplace publishing, including branding, clearer input descriptions, and updated pinned examples.\n\n`v1.38.1` renames the Marketplace Action to `DevDoctor CI Diagnostics` so GitHub accepts the listing with a unique Action name.\n\n`v1.38.2` changes the Marketplace Action branding color to `blue`.\n\n`v1.39.0` adds the repository `bump-version` helper so release pins can be updated from one command instead of hand-editing every file.\n\n`v1.40.0` adds `devdoctor version` for script-friendly version checks with table and JSON output.\n\nPreset detection is informational and can be included in CI explicitly:\n\n```bash\nphp devdoctor ci --modules=presets,env,php,node,laravel,composer,git,docker\n```\n\n## Table Output\n\n```text\nDevDoctor\n\nModule     Status   Errors Warnings  Info\nenv        warning       0        1     0\n\nWarnings\n  [DD_ENV_MISSING_IN_ENV] .env.example:2 QUEUE_CONNECTION QUEUE_CONNECTION exists in .env.example but is missing in .env\n    Hint: Add the key to the environment file or ignore it explicitly when it is optional.\n```\n\nActionable findings may include a hint and a suggested command. Suggested commands are never executed by DevDoctor. Commands that can change system state, such as terminating a process, are marked as destructive in JSON output.\n\n## JSON Output\n\n```json\n{\n    \"tool\": \"devdoctor\",\n    \"schema_version\": \"1.0\",\n    \"status\": \"warning\",\n    \"summary\": {\n        \"errors\": 0,\n        \"warnings\": 1,\n        \"info\": 0,\n        \"suppressed\": 0\n    },\n    \"modules\": [\n        {\n            \"name\": \"env\",\n            \"status\": \"warning\",\n            \"summary\": {\n                \"errors\": 0,\n                \"warnings\": 1,\n                \"info\": 0,\n                \"suppressed\": 0\n            },\n            \"issues\": [\n                {\n                    \"code\": \"DD_ENV_MISSING_IN_ENV\",\n                    \"severity\": \"warning\",\n                    \"message\": \"QUEUE_CONNECTION exists in .env.example but is missing in .env\",\n                    \"module\": \"env\",\n                    \"file\": \".env.example\",\n                    \"key\": \"QUEUE_CONNECTION\",\n                    \"hint\": \"Add the key to the environment file or ignore it explicitly when it is optional.\",\n                    \"suppressed\": false\n                }\n            ]\n        }\n    ]\n}\n```\n\n## SARIF Output\n\nUse SARIF 2.1.0 for code scanning integrations:\n\n```bash\nphp devdoctor ci --format=sarif \u003e devdoctor.sarif\n```\n\nEach result maps the issue code to a SARIF rule id, includes relative file locations when available, and carries a stable `devdoctorFingerprint/v1` based on code, module, file, and key. Hints and fix descriptions are included as metadata; suggested commands are never executed.\n\n## Health\n\nThe health command is a local, broad project overview. It uses the same output formats as other diagnostics and keeps `ports` opt-in to avoid machine-specific noise:\n\n```bash\nphp devdoctor health --format=json\nphp devdoctor health --include-ports\nphp devdoctor health --modules=env,security --exclude=security\n```\n\nUnknown health modules return exit code `3`.\n\n## CI\n\nThe CI aggregator runs `env`, `php`, `node`, `laravel`, `composer`, `git`, and `docker` by default. It adds `frontend`, `flutter`, `mobile`, `monorepo`, `python`, `ruby`, `go`, `rust`, `java`, `iac`, `kube`, `dotnet`, `cpp`, `web`, and `symfony` automatically when matching presets are detected. `ports` and `security` are excluded by default because they can depend on local machine state or intentionally present local files.\n\n```bash\nphp devdoctor ci --format=json\nphp devdoctor ci --profile=local\nphp devdoctor ci --profile=strict-ci\nphp devdoctor ci --profile=security\nphp devdoctor ci --modules=env,php,node,laravel,composer --exclude=composer\nphp devdoctor ci --modules=security --no-fail-on-warnings\nphp devdoctor ci --no-fail-on-warnings\n```\n\nCI profiles provide documented defaults:\n\n| Profile | Modules | Behavior |\n| --- | --- | --- |\n| `local` | `env,php,node,frontend,composer,git,docker` plus detected ecosystems | Does not fail on warnings by default |\n| `ci` | `env,php,node,laravel,composer,git,docker` plus detected ecosystems | Current default behavior |\n| `strict-ci` | `ci` modules plus `security` | Enables strict mode and fails on warnings |\n| `security` | `env,git,docker,security` | Security-oriented strict profile |\n\nUnknown modules and unknown profiles return exit code `3`. Selected modules are always included in JSON output.\n\nThe repository CI workflow runs tests on Linux, macOS, and Windows with PHP 8.5. It also builds and smoke-tests the PHAR and a PHPacker standalone Linux binary.\n\n### GitHub Action\n\nThe composite GitHub Action downloads a pinned release PHAR, verifies its SHA-256 checksum, and runs CI diagnostics:\n\n```yaml\n- uses: rtcoder/devdoctor@v1.40.0\n  with:\n    version: v1.40.0\n    format: sarif\n```\n\nThe Action metadata is prepared for GitHub Marketplace publishing with branding and explicit input descriptions. Always pin both the Action ref and the `version` input. The Action does not use `latest`.\n\n## Baselines\n\nBaselines let an existing project acknowledge current warnings and errors while continuing to fail CI for new findings:\n\n```bash\nphp devdoctor ci --write-baseline=devdoctor-baseline.json\nphp devdoctor ci --baseline=devdoctor-baseline.json\nphp devdoctor ci --baseline=devdoctor-baseline.json --baseline-report\n```\n\nBaseline fingerprints use issue code, module, normalized file path, and key. They do not depend on messages or line numbers. Suppressed findings remain visible in table, JSON, and SARIF output, but they do not affect status or exit code. Only warnings and errors are written. Use `--baseline-report` to show active, suppressed, and resolved fingerprint counts. Use `--force` to intentionally replace an existing baseline after review.\n\n## Configuration\n\nDevDoctor reads `devdoctor.yml` for env rules:\n\n```yaml\nmodules:\n  env:\n    files:\n      env: .env\n      example: .env.example\n    ignore:\n      missing_in_env:\n        - OPTIONAL_TOKEN\n      missing_in_example:\n        - LOCAL_ONLY_KEY\n    rules:\n      APP_KEY:\n        required: true\n      APP_DEBUG:\n        type: bool\n        forbidden_when:\n          APP_ENV: production\n      CACHE_DRIVER:\n        allowed:\n          - file\n          - redis\n      REDIS_URL:\n        required_when:\n          CACHE_DRIVER: redis\n```\n\nUse a different config file with:\n\n```bash\nphp devdoctor env --config=devdoctor.yml\nphp devdoctor ci --config=devdoctor.yml\n```\n\nGenerate an initial configuration with the interactive wizard:\n\n```bash\nphp devdoctor init\nphp devdoctor init --dry-run\nphp devdoctor init --config=config/devdoctor.yml\n```\n\nThe wizard detects supported env files and project presets, previews the YAML, and writes only after confirmation. It never copies environment values into the generated file. Existing files require `--force` and a second confirmation. In CI or `--no-interaction` mode, use `--dry-run`.\n\n## Exit Codes\n\n```text\n0 = no issues\n1 = warnings only\n2 = errors found\n3 = invalid DevDoctor config\n4 = required input / dependency missing\n5 = internal error / unexpected exception\n```\n\n## Stable Contracts\n\n- JSON output includes `schema_version` and follows the stable v1 schema at [schemas/v1/devdoctor-output.schema.json](schemas/v1/devdoctor-output.schema.json).\n- [schemas/devdoctor-output.schema.json](schemas/devdoctor-output.schema.json) remains an alias for the latest schema.\n- Issue identifiers are documented in the human-readable [docs/issue-codes.html](docs/issue-codes.html) catalog and the machine-readable [schemas/v1/issue-codes.json](schemas/v1/issue-codes.json).\n- Automation should match issue codes rather than human-readable messages.\n- Schema v1 will not receive breaking changes during `v1.x`. Existing issue codes will not be removed or repurposed without deprecation, and new codes may be added.\n- The version recorded in `composer.json` under `extra.devdoctor.version` matches the Git release tag.\n\n## Documentation\n\nFull static documentation lives in [docs/](docs/index.html), including installation, command reference, config, scenarios, output formats, baseline, safety, contracts, [issue codes](docs/issue-codes.html), release verification, [changelog](docs/changelog.html), and pinned CI examples for GitHub Actions, GitLab CI, and Bitbucket Pipelines.\n\nRegenerate the human-readable issue code catalog after changing `schemas/v1/issue-codes.json`:\n\n```bash\nphp scripts/build-docs.php\nphp scripts/build-docs.php --check\n```\n\n## Safety\n\nDevDoctor is read-only by default:\n\n- It does not rewrite `.env`, Compose, Composer, Git, or project files.\n- It does not run `composer install`, `composer update`, Composer scripts, or internet-dependent audits.\n- It does not run `docker compose up`, `start`, `stop`, `rm`, or `prune`.\n- Hints and suggested commands are informational only and are never executed.\n- Port diagnostics may suggest `kill -TERM \u003cpid\u003e`, but never execute it.\n- Basic diagnostics do not require telemetry or internet access.\n\n## Release Verification\n\nTagged releases publish `devdoctor.phar`, PHPacker standalone binaries, SHA-256 checksums, Cosign signatures, and Sigstore certificates.\n\nStandalone release assets:\n\n```text\ndevdoctor-linux-x64\ndevdoctor-linux-arm64\ndevdoctor-macos-x64\ndevdoctor-macos-arm64\ndevdoctor-windows-x64.exe\n```\n\nVerify the PHAR checksum before running a downloaded PHAR:\n\n```bash\nsha256sum --check devdoctor.phar.sha256\n```\n\nVerify every executable release asset with the combined checksum file:\n\n```bash\nsha256sum --check devdoctor.sha256\n```\n\nVerify the keyless signature with Cosign:\n\n```bash\ncosign verify-blob \\\n  --certificate devdoctor.phar.pem \\\n  --signature devdoctor.phar.sig \\\n  --certificate-identity-regexp 'https://github.com/rtcoder/devdoctor/' \\\n  --certificate-oidc-issuer https://token.actions.githubusercontent.com \\\n  devdoctor.phar\n```\n\n## Homebrew\n\nDevDoctor is available from the `rtcoder/tap` Homebrew tap:\n\n```bash\nbrew tap rtcoder/tap\nbrew install devdoctor\n```\n\nThe release workflow can update `rtcoder/homebrew-tap` after each tag when the repository secret `HOMEBREW_TAP_TOKEN` is configured with write access to the tap.\n\nIf the token was added after a release, run the `Update Homebrew Tap` workflow manually from GitHub Actions and pass the release version, for example `1.40.0` or `v1.40.0`. The workflow downloads `devdoctor.phar.sha256` from the GitHub Release and updates `Formula/devdoctor.rb` in `rtcoder/homebrew-tap`.\n\n## Development\n\nUpdate release version pins with:\n\n```bash\n./bump-version 1.40.0\n```\n\nThe helper updates `extra.devdoctor.version`, Action examples, documentation pins, CI examples, pinned test expectations, and `composer.lock`. Use `--no-lock` only when you intentionally want to skip the Composer lock refresh.\n\n```bash\ncomposer validate --strict\nphp devdoctor test\n./vendor/bin/pint --test\nphp devdoctor app:build devdoctor.phar --build-version=1.40.0 --no-interaction\nphp builds/devdoctor.phar --version\n./vendor/bin/phpacker build --src=./builds/devdoctor.phar --dest=./builds/standalone --php=8.5 linux x64\n./builds/standalone/linux/linux-x64 --version\n```\n\n## Roadmap\n\nSee [ROADMAP.md](ROADMAP.md) for the implementation roadmap and later distribution work.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtcoder%2Fdevdoctor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frtcoder%2Fdevdoctor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frtcoder%2Fdevdoctor/lists"}