PHPackages                             fast-forward/dev-tools - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. fast-forward/dev-tools

ActiveComposer-plugin[Testing &amp; Quality](/categories/testing)

fast-forward/dev-tools
======================

Fast Forward Development Tools for PHP projects

v1.25.5(1mo ago)01.1k↓90%[26 issues](https://github.com/php-fast-forward/dev-tools/issues)12MITPHPPHP ^8.3

Since Apr 8Pushed 2w agoCompare

[ Source](https://github.com/php-fast-forward/dev-tools)[ Packagist](https://packagist.org/packages/fast-forward/dev-tools)[ Docs](https://github.com/php-fast-forward/)[ Fund](https://www.paypal.com/donate/?business=JLDAF45XZ8D84)[ GitHub Sponsors](https://github.com/sponsors/php-fast-forward)[ RSS](/packages/fast-forward-dev-tools/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (10)Dependencies (42)Versions (48)Used By (12)

FastForward\\DevTools
=====================

[](#fastforwarddevtools)

FastForward DevTools is a Composer plugin that standardizes quality checks, documentation builds, consumer repository bootstrap, and packaged agent skills across Fast Forward libraries.

[![PHP Version](https://camo.githubusercontent.com/c9b19f1cbf8aefb8c278c8b5d392b64401164a08fced6ccbf376b32135d6714f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e332d3737374242343f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://www.php.net/releases/)[![Composer Package](https://camo.githubusercontent.com/af4acbb1e04b4456d07a7425ceb25ebc63fcd3891d7d338af671fd977feb5dd5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f6d706f7365722d666173742d2d666f72776172642532466465762d2d746f6f6c732d4632384431412e7376673f6c6f676f3d636f6d706f736572266c6f676f436f6c6f723d7768697465)](https://packagist.org/packages/fast-forward/dev-tools)[![Tests](https://camo.githubusercontent.com/2769ac41d9be065da9bad9bc22075588c95ae5928802a5523bd0591301a417d1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7068702d666173742d666f72776172642f6465762d746f6f6c732f74657374732e796d6c3f6c6f676f3d676974687562616374696f6e73266c6f676f436f6c6f723d7768697465266c6162656c3d746573747326636f6c6f723d323243353545)](https://github.com/php-fast-forward/dev-tools/actions/workflows/tests.yml)[![Coverage](https://camo.githubusercontent.com/783041b70aa9cfca2a0969ddc49e11178a3367b14165ef787853fdc3075f43b3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f7665726167652d706870756e69742d3441444538303f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://php-fast-forward.github.io/dev-tools/coverage/index.html)[![Metrics](https://camo.githubusercontent.com/847d24da02dc503c2bbe9c6a4fb6f97ece711710ac9c0e2d5f996fbd7a701ffb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d6574726963732d7068706d6574726963732d3842354346363f6c6f676f3d706870266c6f676f436f6c6f723d7768697465)](https://php-fast-forward.github.io/dev-tools/metrics/index.html)[![Docs](https://camo.githubusercontent.com/e55ba192986418684cfbf917099b42e94ac901b099ce5d50c81c37db35942e80/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6465706c6f796d656e74732f7068702d666173742d666f72776172642f6465762d746f6f6c732f6769746875622d70616765733f6c6f676f3d72656164746865646f6373266c6f676f436f6c6f723d7768697465266c6162656c3d646f6373266c6162656c436f6c6f723d31453239334226636f6c6f723d333842444638267374796c653d666c6174)](https://php-fast-forward.github.io/dev-tools/index.html)[![License](https://camo.githubusercontent.com/760bfa1fae8e3b7bc05c205a3f1d63c7b88f66d746373c081a4c47a0dff7f243/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7068702d666173742d666f72776172642f6465762d746f6f6c733f636f6c6f723d363437343842)](LICENSE)[![GitHub Sponsors](https://camo.githubusercontent.com/d61f432861a7c60e0a9620738dffd3b884bcf392c86e48a2cc87ea57a077e90a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f7068702d666173742d666f72776172643f6c6f676f3d67697468756273706f6e736f7273266c6f676f436f6c6f723d776869746526636f6c6f723d454334383939)](https://github.com/sponsors/php-fast-forward)

 [![Fast Forward DevTools mascot](docs/_static/mascot-banner.png)](docs/_static/mascot-banner.png)

✨ Features
----------

[](#-features)

- Aggregates refactoring, PHPDoc, code style, tests, and reporting under a single Composer-facing command vocabulary
- Adds dependency analysis for missing and unused Composer packages through a single report entrypoint
- Manages Keep a Changelog 1.1.0 files with local authoring, validation, version inference, release promotion, and release-note rendering commands
- Ships shared workflow stubs, `.editorconfig`, Dependabot configuration, and other onboarding defaults for consumer repositories
- Packages a rigorous pull-request review skill, matching `review-guardian`project agent, and ready-for-review workflow brief for high-signal review intake
- Generates `.github/CODEOWNERS` files from local project metadata instead of shipping repository-specific owners into consumers
- Synchronizes packaged skills and project-agent prompts into consumer `.agents/skills` and `.agents/agents` directories using safe link-based updates
- Supports guide-only and automation-only repositories by skipping PHPUnit or wiki generation gracefully when no runnable PHP surface exists
- Works both as a Composer plugin and as a local binary
- Preserves local overrides through consumer-first configuration resolution

🚀 Installation
--------------

[](#-installation)

```
composer require --dev fast-forward/dev-tools
```

🛠️ Usage
--------

[](#️-usage)

Once installed, the plugin automatically exposes the aggregated `dev-tools`command and the individual Composer commands described below.

```
# Run all standard checks (refactoring, code styling, docs, tests, and reports)
composer dev-tools

# Automatically fix code standards issues where applicable
composer dev-tools:fix

# Run the standalone binary from another project directory
vendor/bin/dev-tools --working-dir=/path/to/project tests

# Store generated reports and caches outside the default .dev-tools workspace
vendor/bin/dev-tools --workspace-dir=.artifacts reports

# Update the installed DevTools package
vendor/bin/dev-tools self-update
```

You can also run individual commands for specific development tasks:

```
# Run PHPUnit tests
composer dev-tools tests
composer dev-tools tests --json
composer dev-tools tests --pretty-json

# Analyze missing, unused, misplaced, and outdated Composer dependencies
composer dependencies
composer dependencies --max-outdated=8
composer dependencies --max-outdated=-1
composer dependencies --dev
composer dependencies --dump-usage=symfony/console
composer dependencies --upgrade --dev

# Analyze code metrics with PhpMetrics
composer metrics
composer metrics --target=.dev-tools/metrics
composer --working-dir=packages/example metrics

# Add one changelog entry to Unreleased or a published version
composer changelog:entry "Add changelog automation for release workflows (#28)"
composer changelog:entry --type=fixed --release=1.2.0 --date=2026-04-19 "Preserve published release sections during backfill (#28)"
composer changelog:entry --json "Add changelog automation for release workflows (#28)"
composer changelog:entry --pretty-json "Add changelog automation for release workflows (#28)"

# Verify that the current branch added a meaningful Unreleased entry
composer changelog:check
composer changelog:check --against=origin/main
composer changelog:check --json
composer changelog:check --pretty-json

# Infer the next semantic version from Unreleased
composer changelog:next-version
composer changelog:next-version --json

# Promote Unreleased into a published version
composer changelog:promote 1.3.0
composer changelog:promote 1.3.0 --json

# Render one published section as release notes
composer changelog:show 1.3.0
composer changelog:show 1.3.0 --json

# Check and fix code style using ECS and Composer Normalize
composer code-style

# Refactor code using Rector
composer refactor

# Check and fix PHPDoc comments
composer phpdoc

# Generate HTML API documentation using phpDocumentor
composer docs
composer docs --source=docs/user-guide

# Generate Markdown documentation for the wiki
composer wiki

# Generate documentation frontpage and related reports
composer reports
composer reports --target=.dev-tools --coverage=.dev-tools/coverage
FAST_FORWARD_WORKSPACE_DIR=.artifacts composer reports

# Synchronize packaged agent skills into .agents/skills
composer skills

# Synchronize packaged project agents into .agents/agents
composer agents

# Synchronize Composer funding metadata with .github/FUNDING.yml
composer funding
composer funding --dry-run

# Generate .github/CODEOWNERS from composer.json metadata
composer codeowners
composer codeowners --interactive

# Merges and synchronizes .gitignore files
composer gitignore

# Manages .gitattributes export-ignore rules for leaner package archives
composer gitattributes

# Generates a LICENSE file from composer.json license information
composer license

# Copies packaged or local resources into the consumer repository
composer copy-resource --source resources/docblock --target .docheader

# Installs Fast Forward Git hooks
composer git-hooks

# Updates the composer.json file to match the packaged schema
composer update-composer-json --force

# Installs and synchronizes dev-tools scripts, GitHub Actions workflows,
# .editorconfig, .gitignore rules, packaged skills, packaged agents, and the
# repository wiki submodule in .github/wiki
composer dev-tools:sync
```

The `dependencies` command ships with `shipmonk/composer-dependency-analyser` and `rector/jack` as direct dependencies of `fast-forward/dev-tools`, so it works without extra installation in the consumer project.

The packaged `tests.yml` workflow runs dependency health as a required job and defaults to `--max-outdated=-1`, which keeps outdated-package findings visible in CI without failing the workflow for their count alone.

The `metrics` command ships with `phpmetrics/phpmetrics` as a direct dependency of `fast-forward/dev-tools`, so consumer repositories can generate metrics reports without extra setup.

Guide-only repositories and workflow-only repositories can still use the packaged command surface. When no runnable PHPUnit surface exists, `tests`returns a controlled warning instead of failing. When a repository ships guides without PSR-4 source paths, `docs` builds the guide site without trying to synthesize API pages. When `.github/wiki` is absent and no wiki has been initialized yet, `wiki` now skips generation with a warning instead of failing the whole automation run.

The changelog commands manage Keep a Changelog 1.1.0 files without requiring extra tooling in the consumer repository. `changelog:entry` bootstraps a missing changelog file on first use, `changelog:check` enforces meaningful `Unreleased` entries in pull requests, `changelog:next-version` infers the next semantic version from pending changes, `changelog:promote` publishes the current `Unreleased` section into a tagged version, and `changelog:show`renders one published section for GitHub release notes. Repositories that require changelog enforcement in branch protection should require the aggregate changelog check:

- Direct workflow invocation: `Changelog Validation`
- Reusable workflow wrappers (`resources/github-actions/changelog.yml`): `changelog / Changelog Validation`

This remains stable for normal pull requests and release-preparation branches, while the lower-level validation job can be skipped intentionally for `release/v...` branches.

Structured output is available across the DevTools command surface through `--json`, which returns deterministic `message` / `level` / `context` payloads for CI, bots, and AI-agent workflows while preserving the normal human-readable terminal output by default. Use `--pretty-json` when you want the same structured payload indented for manual inspection in a terminal. `--pretty-json` also implies JSON output, so there is no need to pass both flags together. In agent environments, DevTools can also switch to JSON automatically when the runtime is detected as agent-driven. For `changelog:next-version` and `changelog:show`, the default text mode still prints raw values so release workflows can keep capturing semantic versions and piping rendered release notes directly into GitHub releases.

`--pretty-json` intentionally remains valid JSON. DevTools does not inject ANSI escape sequences into that mode today because preserving a parseable payload takes precedence over terminal-only color. Where orchestrated tools can expose structured subprocess results safely, DevTools prefers adding stable fields to the JSON context rather than coloring otherwise strict JSON output.

For the `tests` command, structured runs now capture the bundled PHPUnit agent-reporter payload inside `context.output` while preserving the normal DevTools JSON envelope. That means the top-level command still emits one final document, and consumers can inspect stable nested keys such as `context.output.result`, `context.output.summary`, optional `context.output.details`, and `context.output.coverage` when minimum-coverage validation is active.

Progress output is disabled by default on the commands that support transient rendering, and `--progress` re-enables it for human-readable terminal runs. When `--json` or `--pretty-json` is active on commands that orchestrate other tools, DevTools keeps progress suppressed, forwards JSON flags where the underlying tool supports structured output, and otherwise falls back to quieter subprocess modes so the captured payload stays machine-readable. The `tests` command now captures the bundled PHPUnit agent-reporter payload in structured runs and stores it in `context.output`, preserving `result`, `summary`, optional `details`, and a `raw_output` fallback when coverage or other PHPUnit text is emitted before the final reporter JSON. In GitHub Actions, queued subprocess output is grouped into collapsible sections, and logged failures emit native workflow error annotations, including file and line metadata when commands provide it. The packaged tests, reports, wiki, and changelog workflows also append concise Markdown outcomes to `GITHUB_STEP_SUMMARY` so maintainers can scan versions, URLs, preview refs, verification status, and release results without expanding full logs. This repository also keeps a bounded retry workflow that reruns failed jobs once when failed job logs match transient GitHub-side checkout or transport errors such as HTTP 500 fetch failures, while leaving genuine logic and quality failures untouched.

When the packaged changelog workflow is synchronized into a consumer repository, pull requests are expected to add a notable changelog entry before merge. The same workflow can be triggered manually to prepare a release bump pull request from `Unreleased`, and merged release branches publish GitHub releases from the exact changelog section body.

The `funding` command keeps supported `composer.json` funding entries aligned with `.github/FUNDING.yml`, including GitHub Sponsors handles and `custom`URLs, while preserving unsupported providers in place and re-running `composer normalize` after manifest updates.

The `codeowners` command generates `.github/CODEOWNERS` from local `composer.json` metadata. It prefers explicit GitHub profile URLs from author metadata, falls back to commented suggestions from support metadata, and can prompt for owners when `--interactive` is used in a terminal.

The `skills` command keeps `.agents/skills` aligned with the packaged Fast Forward skill set. It creates missing links, repairs broken links, and preserves existing non-symlink directories. The `dev-tools:sync` command calls `skills` automatically after refreshing the rest of the consumer-facing automation assets. The packaged skills include reusable flows for GitHub issue authoring, issue implementation, changelog maintenance, and rigorous pull request review.

The `agents` command keeps `.agents/agents` aligned with the packaged Fast Forward project-agent prompt set. It follows the same symlink-preservation and broken-link-repair safety model as the packaged skill synchronization flow, and `dev-tools:sync` calls it automatically in normal synchronization mode. The packaged agent set includes role prompts such as `issue-implementer`, `docs-writer`, `test-guardian`, `readme-maintainer`, `review-guardian`, and `changelog-maintainer`.

The packaged workflow stubs synchronized by `dev-tools:sync` now also include changelog automation for pull-request validation and release preparation, so consumer repositories can adopt the same changelog-driven release flow without copying workflow logic by hand. They also include a rigorous review intake workflow that reacts when a pull request becomes ready for review and posts a deterministic brief for the dedicated review agent.

The release workflow is intentionally two-step: `workflow_dispatch` prepares a `release/v...` pull request, and merging that release pull request publishes the GitHub release and tag. Consumer repositories must enable GitHub Actions **Read and write permissions** and **Allow GitHub Actions to create and approve pull requests** under `Settings -> Actions -> General`. If those controls are disabled, an organization or repository admin must unlock them before the release-preparation workflow can create pull requests.

This repository also keeps role-based project agents in `.agents/agents`. They are packaged for consumer repositories alongside `.agents/skills`, so downstream projects can adopt both reusable role prompts and the procedural skills they depend on.

🧰 Command Summary
-----------------

[](#-command-summary)

CommandPurpose`composer dev-tools`Runs the full `standards` pipeline.`composer tests`Runs PHPUnit with local-or-packaged configuration.`composer dependencies`Previews Jack dependency updates, then reports missing, unused, misplaced, and outdated Composer dependencies.`composer metrics`Runs PhpMetrics for the current project and generates requested report artifacts.`composer changelog:entry`Adds one categorized changelog entry to `Unreleased` or a published release section.`composer changelog:check`Verifies that a changelog file contains meaningful `Unreleased` notes, optionally against a git base reference.`composer changelog:next-version`Infers the next semantic version from the current changelog state.`composer changelog:promote`Moves `Unreleased` entries into a published version section and records the release date.`composer changelog:show`Renders one published changelog section for release notes and automation.`composer docs`Builds the HTML documentation site from PSR-4 code and `docs/`.`composer agents`Creates or repairs packaged project-agent links in `.agents/agents`.`composer skills`Creates or repairs packaged skill links in `.agents/skills`.`composer funding`Synchronizes managed funding metadata between `composer.json` and `.github/FUNDING.yml`.`composer codeowners`Generates managed `.github/CODEOWNERS` content from local repository metadata.`composer gitattributes`Manages export-ignore rules in `.gitattributes`.`composer dev-tools:sync`Updates scripts, CODEOWNERS, funding metadata, workflow stubs, `.editorconfig`, `.gitignore`, `.gitattributes`, wiki setup, packaged skills, and packaged agents.`vendor/bin/dev-tools self-update` / `composer dev-tools:self-update`Updates the local DevTools package, or the Composer global installation when the active binary is globally installed.`--working-dir`/`-d` changes the project root used by the standalone binary. `--workspace-dir`/`-w` changes where generated DevTools artifacts and caches are written when command-specific paths are omitted. Composer executions can use `FAST_FORWARD_WORKSPACE_DIR=.artifacts composer reports` for the same workspace policy, while explicit options such as `--target`, `--coverage`, `--metrics`, and `--cache-dir` continue to take precedence.

🔌 Integration
-------------

[](#-integration)

DevTools integrates with consumer repositories in two ways. The Composer plugin exposes the command set automatically after installation, and the local binary keeps the same command vocabulary when you prefer running tools directly from `vendor/bin/dev-tools`. The consumer sync flow also refreshes `.agents/skills`and `.agents/agents` so agents can discover the packaged skills and packaged role prompts shipped with this repository, including workflows for GitHub issue/PR handling, changelog maintenance, rigorous pull-request review, PHP quality tasks, Sphinx docs, README generation, and repository `AGENTS.md`authoring.

🏗️ Architecture
---------------

[](#️-architecture)

- `Composer Plugin` - `FastForward\DevTools\Composer\Plugin` exposes the packaged command set to Composer and runs `dev-tools:sync` after install and update.
- `DevTools Container` - `FastForward\DevTools\Container\ContainerFactory::get(FastForward\DevTools\Console\DevTools::class)`resolves the shared application from `DevToolsServiceProvider`, which wires process execution, filesystem access, changelog services, Git helpers, diffing, reporting, and template loading.
- `Generic Link Synchronization` - `FastForward\DevTools\Sync\PackagedDirectorySynchronizer` provides the shared symlink-preserving workflow used by both `skills` and `agents`, keeping consumer-owned directories intact while repairing broken links.
- `Lazy Command Loading` - `DevToolsCommandLoader` discovers `#[AsCommand]`classes and resolves most commands only when they are invoked, while orchestration commands such as `standards` dispatch other commands through the console application itself.
- `Consumer Sync Pipeline` - `dev-tools:sync` refreshes `composer.json`, CODEOWNERS, funding metadata, workflow stubs, repository defaults, git metadata files, packaged Git hooks, and, in normal mode, the wiki submodule plus packaged skills and packaged project agents.

🤝 Contributing
--------------

[](#-contributing)

Run `composer dev-tools` before opening a pull request. If you change public commands or consumer onboarding behavior, update `README.md` and `docs/`together so downstream libraries keep accurate guidance.

Notable pull requests are also expected to add a changelog entry before review is complete. A typical contributor flow looks like this:

```
# Record the user-visible change
composer changelog:entry --type=changed "Refine changelog automation for release publication (#28)"

# Validate that the branch added meaningful Unreleased notes
composer changelog:check --against=origin/main
```

For release preparation, maintainers can infer and promote the next version locally before using the packaged GitHub workflow:

```
# Inspect the version that Unreleased implies
composer changelog:next-version

# Publish Unreleased into the selected version and review the resulting notes
composer changelog:promote 1.3.0
composer changelog:show 1.3.0
```

📄 License
---------

[](#-license)

This package is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.

🔗 Links
-------

[](#-links)

- [Repository](https://github.com/php-fast-forward/dev-tools)
- [Packagist](https://packagist.org/packages/fast-forward/dev-tools)
- [Documentation](https://php-fast-forward.github.io/dev-tools/index.html)
- [RFC 2119](https://datatracker.ietf.org/doc/html/rfc2119)

###  Health Score

50

—

FairBetter than 95% of packages

Maintenance94

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 83.5% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

42

Last Release

41d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/bb658791d4db57e57ac164a268f94340ddff4d1ee0aad1358d4593847051a9fe?d=identicon)[coisa](/maintainers/coisa)

---

Top Contributors

[![coisa](https://avatars.githubusercontent.com/u/426835?v=4)](https://github.com/coisa "coisa (319 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (53 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (10 commits)")

---

Tags

code-styledevdeveloper-toolsdevelopmentdevopsfakergrumphpgrumphp-taskphpphp-cs-fixerphp-cs-fixer-configphpdocphpdocumentorphpunitrectorrectorphpstandardsunit-testingwikitestingstatic analysisCode styleECSrectordev-toolsfast-forward

### Embed Badge

![Health badge](/badges/fast-forward-dev-tools/health.svg)

```
[![Health](https://phpackages.com/badges/fast-forward-dev-tools/health.svg)](https://phpackages.com/packages/fast-forward-dev-tools)
```

###  Alternatives

[tempest/framework

The PHP framework that gets out of your way.

2.2k31.1k12](/packages/tempest-framework)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M196](/packages/sulu-sulu)[drupal/core-recommended

Locked core dependencies; require this project INSTEAD OF drupal/core.

6941.5M396](/packages/drupal-core-recommended)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.6k38.2k](/packages/matomo-matomo)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.4M517](/packages/shopware-core)[jolicode/castor

A lightweight and modern task runner. Automate everything. In PHP.

54642.4k4](/packages/jolicode-castor)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
