prodstarter/filament-forge-insights
Filament Forge Insights brings Laravel Forge monitoring into your Filament admin panel, giving teams quick visibility into servers, sites, deployments, and key health metrics so you can spot issues and manage infrastructure without leaving your dashboard.
This is the initial v1.0.0 tag and the release notes carry no changelog detail, so treat the public API as newly stabilised and confirm the exact surface area against the source before building on it.
Minimal setup:
composer require prodstarter/filament-forge-insights
php artisan vendor:publish --tag="filament-forge-insights-config"
Add a Forge API token (create one in Forge under your profile → API, scoped to the organisations you want to surface):
FORGE_API_TOKEN=your-token-here
Register the plugin on the panel you want it to appear in:
// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(ForgeInsightsPlugin::make());
}
Look here first, in this order:
composer.json — confirm the filament/filament constraint (^3.0 vs ^4.0) and the PHP floor before anything else. A v1.0.0 of a Filament plugin usually pins one major.config/filament-forge-insights.php — token key, cache TTL, organisation filter, navigation settings.src/ForgeInsightsPlugin.php — the fluent make() config: navigation group/label, which pages or widgets are registered, and any ->authorize()/->visible() hooks.Pages/, Resources/, or Widgets/ directories — this tells you immediately whether the package is dashboard-widget-shaped or CRUD-resource-shaped, which decides how you integrate it.The fastest first use case is a read-only dashboard widget: register the plugin, drop ForgeInsightsPlugin::make() into a non-production panel, and confirm server/site status renders for one organisation. Don't wire deploy actions or webhooks until you've validated token scope and caching behaviour.
Panel scoping. Most Filament plugins of this shape register pages into the panel they're attached to. If you run separate admin and tenant panels, register the plugin only where it belongs — a plugin registering Resources globally via a service provider is harder to unwind than one registered per panel.
Cache-first reads. Forge data is remote and slow. Wrap every read in Cache::remember() keyed by organisation + resource, with a short TTL (60–300s) for status and a longer one for static metadata. If the package ships its own cache layer, configure it via the config file rather than adding a second one on top.
Webhook-driven invalidation. Pair the plugin's cached view with a Forge deployment webhook hitting a small route in your app that busts the relevant cache keys. This gives near-real-time deployment status without polling the API on every page load.
// routes/api.php
Route::post('/forge/deploy-hook', function (Request $request) {
Cache::forget("forge:site:{$request->input('site.id')}");
return response()->noContent();
});
Authorization before exposure. Forge data leaks infrastructure detail — IPs, repo names, env var names. Gate the plugin's pages behind a policy or ->visible(fn () => Gate::allows('viewForgeInsights')) and keep the plugin off any panel with broader access than your ops team.
Multi-organisation setups. If your token can see several Forge organisations, prefer an explicit allow-list in config over "show everything". A config-driven organisations array is easier to reason about than filtering inside widgets.
Extension via your own pages. Rather than forking, add your own Filament page that injects the package's service/API client and renders a custom view. Keeps you on the upgrade path.
storage/logs/laravel.log for swallowed HTTP exceptions..env and reference it via config() only. If the config file ships with a hardcoded default, remove it.protected static ?string $pollingInterval, each tick is an API call per user per widget. Set it to something sane (30s+) or null and refresh on demand.composer.json and read the package's constraint carefully.->timezone(config('app.timezone')) or set the display timezone in config.Http::fake() with captured Forge API fixtures so your test suite never touches the real API. If the package ships a facade or client class, bind a fake in the container instead — cleaner than URL-matching.php artisan vendor:publish interactively once to see all available tags; a config-only publish will silently skip any migrations or views the package expects.^1.0 but review diffs on minor bumps until the API settles.How can I help you explore Laravel packages today?