octave/tools-bundle
Octave Tools Bundle collects practical developer utilities for Laravel applications into one configurable Composer package, giving teams a single dependency for common tooling needs instead of scattering small helpers across projects. Enable only the tools each app requires.
Treat onboarding as a source-reading exercise first. The package has no adoption footprint, no changelog, and no usage guide, so the repository is the documentation.
1. Read before you require. Clone the repo and inspect composer.json for illuminate/* or symfony/* constraints, the PHP floor, and the autoload block. The -bundle suffix plus the Octave CMS namespace strongly suggests Symfony conventions (*Bundle, service definitions in Resources/config/, a DependencyInjection extension) rather than a Laravel service provider. That single check decides your path:
symfony/*, do not composer require it into a Laravel app. Vendor the helper classes you want into app/Support/ with attribution and be done.illuminate/support and an extra.laravel.providers block, it is genuinely a Laravel package and the flow below applies.2. Install and confirm discovery.
composer require octave/tools-bundle
php artisan package:discover --ansi
php artisan about
If nothing registers, check vendor/octave/tools-bundle/composer.json for the extra.laravel block. A Symfony-style bundle will not auto-discover and must not be forced in.
3. Read the three files that matter, in order:
config/ — every key and its default. Note the merge strategy.tests/ — or its absence. The test suite is your only behavioral spec.4. First use case. Start with the read-only debug utilities: readable dumps and quick inspection are non-destructive, need no wiring, and let you confirm the package boots and behaves before you touch string/array helpers that domain code might depend on. Wire one call into a throwaway Tinker session or a local-only route. Only after that do you let helper calls into application code.
5. Name an owner. With zero upstream dependents, the person who reads the source is the maintainer. Record that before the first merge.
Thin adapter over the helpers. Do not call octave/tools-bundle functions directly from controllers, models, or jobs. Wrap each one you actually use behind your own interface or static facade in app/Support/:
namespace App\Support;
class Str
{
// delegates now, replaces later — callers never see the package
public static function slugify(string $value): string
{
return \Octave\ToolsBundle\Support\Str::slugify($value);
}
}
This is the whole adoption pattern. It makes vendor-vs-fork-vs-skip a later decision that costs a file edit instead of a refactor, and it keeps the blast radius of a behavioral change inside one class.
Debug utilities stay dev-only. Gate every dump/inspect call behind an explicit environment check or a config flag owned by your app, not the package. These are the helpers most likely to be re-run under Octave and the ones whose output format you care least about, so they are the highest-value, lowest-risk thing to adopt.
Config publish, then diff. Run the vendor publish once and commit the published config. Diff it against the package default so upgrade-time config drift is visible in review rather than at runtime. If the package merges config aggressively, set your keys explicitly and assume the package's defaults are placeholders.
Test the surface you use, not the package. Write a small contract test in your own suite covering each adopted helper's input/output for the cases your app relies on. You are not validating the package's quality — you are freezing the behavior you depend on so an unpinned composer update fails your CI instead of your users.
Vendor for anything small. If the source is a few hundred lines, copy the classes you need into app/Support with a license header and delete the dependency. In practice this is usually the right call for a tooling bundle: you keep the utility and shed the governance risk.
-bundle suffix is the trap. It is a Symfony convention. Confirm the framework target from composer.json before anything else; a Laravel-focused description and a Symfony package can coexist and will waste your afternoon.extra.laravel.providers, so package:discover reports success while registering nothing. Never infer registration from a clean install.composer.json; do not accept ^1.0-style ranges or dev-main.var_dump request state can print secrets in non-production logs. Grep for the package's dump helper before shipping and add it to your "no direct call in app code" rule.How can I help you explore Laravel packages today?