PHPackages                             clinically/laravel-companion - 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. [Logging &amp; Monitoring](/categories/logging)
4. /
5. clinically/laravel-companion

ActiveLibrary[Logging &amp; Monitoring](/categories/logging)

clinically/laravel-companion
============================

A structured JSON API for mobile and external tooling to inspect, monitor, and manage Laravel applications.

v0.0.5(3mo ago)015↓90.9%MITPHPPHP ^8.2

Since Mar 30Pushed 3mo agoCompare

[ Source](https://github.com/clinically-au/laravel-companion)[ Packagist](https://packagist.org/packages/clinically/laravel-companion)[ RSS](/packages/clinically-laravel-companion/feed)WikiDiscussions main Synced 3w ago

READMEChangelog (5)Dependencies (13)Versions (6)Used By (0)

clinically/laravel-companion
============================

[](#clinicallylaravel-companion)

A structured JSON API for mobile and external tooling to inspect, monitor, and manage Laravel applications. Ships with an admin dashboard (Livewire + Flux) for managing authenticated agents.

Designed as the server-side companion to a native iOS app, but protocol-agnostic — any HTTP client can consume the API.

> **See it in action:** [laravel-companion-demo](https://github.com/clinically-au/laravel-companion-demo) — a full Laravel 13 app that integrates every feature with 121 passing tests, an API Explorer, and Swagger UI docs.

Features
--------

[](#features)

- **Token-based agent authentication** with SHA-256 hashed tokens, scopes, expiry, IP allowlists
- **Feature toggles** — enable/disable endpoint groups; disabled features have zero runtime cost
- **Model browser** — introspect Eloquent models (via [laravel-introspect](https://github.com/Capevace/laravel-introspect)) and browse records with filtering, sorting, pagination
- **Route inspector** — list all registered routes with middleware, parameters, actions
- **Artisan command runner** — execute whitelisted commands with blacklist safety net
- **Queue management** — view failed jobs, retry, delete, flush
- **Cache inspector** — read keys, forget keys, flush
- **Config viewer** — full config tree with automatic sensitive value redaction
- **Log viewer** — parsed log entries with SSE live tail streaming
- **Scheduler viewer** — all scheduled commands with next due dates
- **Migration status** — batched migration history
- **Event/listener map** — registered events with their listeners
- **Horizon integration** — status, metrics, recent jobs, pause/continue/terminate
- **Pulse integration** — servers, slow queries/requests/jobs, exceptions, usage
- **Audit log** — every API request logged with agent, action, payload, response code, duration
- **Admin dashboard** — Livewire + Flux UI for managing agents, viewing audit logs, feature status
- **QR pairing** — generate QR codes for mobile app device pairing
- **Extensible** — register custom features, `CompanionSerializable` for model opt-in, events for integration

Requirements
------------

[](#requirements)

- PHP 8.2+
- Laravel 11+
- [mateffy/laravel-introspect](https://github.com/Capevace/laravel-introspect) ^1.1 (required)

**For the dashboard:**

- [Livewire](https://livewire.laravel.com) ^4.0
- [Flux](https://fluxui.dev) ^2.0 (free tier)

Installation
------------

[](#installation)

```
composer require clinically/laravel-companion
```

Then run the install command:

```
php artisan companion:install
```

This publishes the config, migrations, runs migrations, and optionally creates your first agent token.

Configuration
-------------

[](#configuration)

Publish the config separately if needed:

```
php artisan vendor:publish --tag=companion-config
```

See `config/companion.php` for all options including:

- **Route prefix/domain** — `COMPANION_PATH`, `COMPANION_DOMAIN`
- **Feature toggles** — enable/disable each endpoint group
- **Scopes &amp; presets** — define what agents can access
- **Command whitelist/blacklist** — control which artisan commands are executable
- **Model browser settings** — hidden columns, redaction patterns, pagination, column validation
- **Cache browser** — `cache.allowed_prefixes` to restrict which keys are accessible (empty = all)
- **Config redaction** — patterns, always/never redact rules
- **Rate limiting** — per-agent API and SSE connection limits
- **Audit log** — retention, read/write logging, automatic payload sanitisation

Artisan Commands
----------------

[](#artisan-commands)

CommandPurpose`companion:install`One-time setup: publish config, run migrations, create first agent`companion:agent`Create a new agent token interactively`companion:pair {agent}`Display pairing info for an existing agent`companion:agents`List all agents with status`companion:revoke {agent}`Revoke an agent token`companion:prune-audit`Prune old audit log entries`companion:status`Health check and feature status overviewDashboard
---------

[](#dashboard)

The admin dashboard is available at `/{path}/dashboard` (default: `/companion/dashboard`).

Access is controlled by the `viewCompanion` gate — open in local environment, locked in production. Define it in your `AppServiceProvider`:

```
Gate::define('viewCompanion', function (User $user) {
    return $user->is_admin;
});
```

### Embeddable Livewire Components

[](#embeddable-livewire-components)

All dashboard components can be embedded in your own admin panel:

```

```

API Authentication
------------------

[](#api-authentication)

Agents authenticate via bearer token:

```
Authorization: Bearer cmp_01hx...|a3f8b2...

```

Tokens are SHA-256 hashed before storage. The plain token is shown once at creation. The authenticated agent is accessible via `$request->companionAgent()`.

HasCompanionAccess Trait
------------------------

[](#hascompanionaccess-trait)

Add to your User model for convenience helpers:

```
use Clinically\Companion\Traits\HasCompanionAccess;

class User extends Authenticatable
{
    use HasCompanionAccess;
}
```

Provides `$user->companionAgents()`, `$user->createCompanionAgent()`, `$user->revokeCompanionAgent()`, `$user->canAccessCompanion()`.

Custom Features
---------------

[](#custom-features)

Register additional feature groups:

```
Companion::registerFeature('custom-metrics', function (Router $router) {
    $router->get('/custom-metrics', CustomMetricsController::class)
        ->middleware('companion.scope:custom-metrics:read');
});
```

Model Browser Opt-in
--------------------

[](#model-browser-opt-in)

Implement `CompanionSerializable` to control exactly what's exposed:

```
use Clinically\Companion\Contracts\CompanionSerializable;

class Patient extends Model implements CompanionSerializable
{
    public function toCompanionArray(): array
    {
        return $this->only(['id', 'first_name', 'last_name', 'mrn']);
    }

    public function companionRelationships(): array
    {
        return ['appointments'];
    }

    public function companionScopes(): array
    {
        return ['active'];
    }
}
```

Events
------

[](#events)

EventWhen`AgentCreated`New agent token generated`AgentRevoked`Agent revoked`AgentAuthenticated`Successful API auth`AgentAuthFailed`Failed auth attempt`CommandExecuted`Artisan command run via API`MutatingAction`Any write operationSecurity
--------

[](#security)

### Model Browser

[](#model-browser)

- Only models discovered in configured `models.paths` are accessible — arbitrary class names are rejected
- Sort/filter column names are validated against the database schema, excluding hidden and redacted columns
- LIKE search wildcards are escaped to prevent pattern injection
- Scopes can only be applied to models implementing `CompanionSerializable`
- Relationship data passes through the same redaction pipeline as top-level records
- Per-page limits are enforced (min 1, max configurable)

### Cache Browser

[](#cache-browser)

Configure `companion.cache.allowed_prefixes` to restrict key access:

```
'cache' => [
    'allowed_prefixes' => ['app:', 'companion:'],
],
```

When empty (default), all keys are accessible. In production, restrict to prevent exposure of session/token data.

### HTTPS

[](#https)

HTTPS is enforced in all non-local/testing environments. Requests over plain HTTP receive a `403`.

Testing
-------

[](#testing)

The package provides test helpers:

```
use Clinically\Companion\Testing\CompanionTestHelpers;

class MyTest extends TestCase
{
    use CompanionTestHelpers;

    public function test_something()
    {
        $agent = $this->createTestAgent(scopes: ['models:read']);

        $response = $this->withCompanionAgent($agent)
            ->getJson('/companion/api/models');

        $response->assertOk();
    }
}
```

### Running Package Tests

[](#running-package-tests)

```
composer test      # Pest tests
composer analyse   # PHPStan level 6
composer format    # Pint formatting
```

License
-------

[](#license)

MIT

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance82

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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 ~0 days

Total

5

Last Release

91d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f2ea2e401c2f1f18cafc42d8fb98305ae3575db1fb25455af1c3156d0e79f90e?d=identicon)[wojt-janowski](/maintainers/wojt-janowski)

---

Top Contributors

[![wojt-janowski](https://avatars.githubusercontent.com/u/209190810?v=4)](https://github.com/wojt-janowski "wojt-janowski (10 commits)")

---

Tags

apilaravelmonitoringadmincompanionintrospection

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/clinically-laravel-companion/health.svg)

```
[![Health](https://phpackages.com/badges/clinically-laravel-companion/health.svg)](https://phpackages.com/packages/clinically-laravel-companion)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3345.1M337](/packages/psalm-plugin-laravel)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k51.0M7.7k](/packages/larastan-larastan)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

77018.2M122](/packages/laravel-mcp)[spatie/laravel-health

Monitor the health of a Laravel application

87411.3M154](/packages/spatie-laravel-health)[api-platform/laravel

API Platform support for Laravel

59156.3k11](/packages/api-platform-laravel)[calebdw/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

15104.9k4](/packages/calebdw-larastan)

PHPackages © 2026

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