Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Agent Detector Laravel Package

ergebnis/agent-detector

Detect whether your PHP code is running under an AI agent. This Composer package checks environment variables for 30+ agents like Claude Code, Codex, Cursor, and Copilot, exposing a simple Detector class with one isAgentPresent() method.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is a single-purpose, zero-dependency library: one Detector class exposing isAgentPresent(array $env): bool. It performs a pure lookup over an environment array — no I/O, no framework coupling, no service provider, no config surface.
  • This is an almost perfect architectural fit for a Laravel codebase because it imposes nothing: it can be consumed directly (new Detector()), bound as a singleton, or hidden behind our own AgentContext abstraction without friction.
  • The design is deliberately testable: because the environment is injected as an array, unit tests need no putenv() juggling. This is the single most valuable property for us — we can test the behaviour matrix (local/CI/staging/prod) deterministically.
  • It is a policy input, not a capability. It answers "am I running under an agent?" and nothing else — no agent name, no agent ID, no confidence. Architecture must supply the rest.

Integration feasibility

  • composer require ergebnis/agent-detector and a single call site. Realistic effort: well under a day for the wrapper plus tests; the remaining work is entirely product/policy decisions, not engineering.
  • Laravel nuance to resolve in the spike: the documented usage calls getenv(), while Laravel loads .env through vlucas/phpdotenv. Values inherited from the shell (which is how agents set these variables) generally appear in both getenv() and $_SERVER, but .env-defined values do not. Decision: pass an explicit array sourced from a single, documented location (e.g. $_SERVER or Env::getRepository()) so behaviour is reproducible across CLI, queue workers, and FPM.
  • No illuminate/* constraints → no conflict with Laravel 10/11/12 upgrades and no Composer resolution risk.

Technical risk

  • False positives are the dominant risk, and PHP-specific. The package treats AMP_CURRENT_THREAD_ID as an agent signal, but that variable is associated with the Amp/Revolt async stack — a mainstream PHP runtime component. Any Laravel service using amphp/fibers may be misclassified as "agent present". Likewise REPL_ID is set for all Replit-hosted workloads, including production, and COPILOT_* variables can leak into CI or container images via misconfigured secrets. Guards that disable notifications, seeding, or telemetry could silently activate in production.
  • Not a security boundary. Process environment is controller-controlled; these variables are trivially spoofable and, conversely, invisible for remote agents hitting an HTTP API. Any use to block or rate-limit external traffic is unsound — and the "detection" story for inbound requests is a different problem entirely (headers/user-agents/IPs), which this package does not address.
  • Detection list is hardcoded. New agents (Amp, Antigravity, Pi, OpenCode are recent additions) require an upstream release or a fork. Staleness yields false negatives, which are silent.
  • Low external validation. 24 stars, 0 dependents, single maintainer, "limited support" policy. Mitigating factor: the entire surface is ~100 LOC under MIT, so fork-and-own cost is negligible. The vendor is a known, disciplined PHP OSS publisher (strict static analysis, mutation/infection-style CI, changelog, semver), which raises quality confidence above what the star count implies.
  • Metadata anomaly to verify: the "last release" date (2026-10-29) is future-dated relative to a normal timeline. Confirm the actual release cadence and whether the package is actively maintained before pinning it as a dependency.

Key questions

  1. What observable behaviour changes when an agent is present — and can any of it be revenue-, security-, or compliance-relevant? (If yes, this package is the wrong control.)
  2. Do we need which agent (attribution for analytics, cost allocation, support triage), or is a boolean sufficient? A boolean-only API will force a wrapper if attribution is ever wanted.
  3. Is the production container's environment guaranteed free of COPILOT_*, REPL_ID, AMP_CURRENT_THREAD_ID, and CURSOR_*? Who owns that invariant?
  4. Is a one-class dependency with "limited support" preferable to a ~40-line internal helper we fully own? (Fork cost is low; ownership cost is not zero either way.)
  5. What is the false-positive blast radius if a guard misfires on a busy production node?

Integration Approach

Stack fit

  • Compatible with any Laravel version our platform standardises on (PHP 7.4–8.6 declared; Laravel 11/12 on PHP 8.2+ is comfortably inside the supported matrix). No ext-* requirements, no PSR coupling, Composer 2 only.
  • Recommended shape: bind Ergebnis\AgentDetector\Detector as a singleton in AppServiceProvider, wrap it in an App\Support\AgentContext service that caches the boolean for the process lifetime and exposes named helpers (shouldSuppressNotifications(), shouldUseMachineOutput()), and optionally a thin facade for ergonomics. Application code must never call new Detector() directly — the wrapper is our upgrade and exit path.
  • Config-driven, not code-driven: a config/agent.php with per-environment enablement, an allowlist of which signals we trust, and a kill switch. Default the kill switch off in production.

Migration path

  • Incremental and reversible, in three steps:
    1. Instrument first, act never. Ship the wrapper plus a log line / counter (agent.present) and run it for a sprint to measure how often the detector fires in each environment. This converts the false-positive risk from speculation into data before any behaviour depends on it.
    2. Dev-tooling only. Gate developer-facing conveniences: non-interactive artisan output, skipped mail/notification drivers in agent-driven loops, seeder/factory safety checks, testbench helpers. Zero production blast radius.
    3. Operational policy (conditional). Only if step 1 shows clean signals: adjust queue/command behaviour or telemetry attribution. Do not proceed to HTTP middleware for blocking purposes at all.
  • Each step is a separate PR with its own rollback (config flag), so no big-bang cutover.

Compatibility

  • Pin ^1.2 (range allows 1.x additions without pulling breaking changes; the changelog shows a clean additive 1.x history: 1.1.0 Cursor var, 1.1.1 PHP 8.6, 1.2.0 Copilot/Pi vars).
  • Watch PHP-floor drift: the library still declares PHP 7.4 support (EOL). That is permissive, not restrictive, so it never blocks us — but it means the package tolerates very old runtimes and will not force modernisation either way.
  • Conflict risk is effectively nil; the only real compatibility surface is the environment variable namespace, which we share with CI, hosting platforms, and other tooling.

Sequencing

  1. Spike PR: wrapper + singleton binding + unit tests driven by injected env arrays (no putenv).
  2. Establish the trust allowlist — explicitly decide which signals we honour and which we ignore (recommend ignoring AMP_CURRENT_THREAD_ID and REPL_ID unless the use case demands them).
  3. Ship instrumentation, collect a sprint of data per environment.
  4. Define and document the behaviour matrix per environment in the wrapper's README/docblock.
  5. Roll out dev-tooling gates behind the config flag; revisit operational gates only with data.

Operational Impact

Maintenance

  • Runtime dependency surface is one class — near-zero maintenance. Ongoing cost centres on (a) keeping our wrapper aligned with new upstream agent signals, and (b) periodically re-auditing the trusted-signal allowlist as agents and hosting platforms evolve.
  • Upstream releases are largely dev-dependency bumps and CI hygiene; those do not affect us. Expect quiet periods punctuated by small agent additions. Budget a light quarterly review rather than continuous attention.
  • Assign explicit internal ownership of the wrapper and the "no agent variables in production env" invariant. This is the real ongoing obligation, not the package.

Support

  • Upstream offers "limited support" from a single maintainer; no SLA, no vendor escalation path, no security guarantee beyond a documented policy.
  • Mitigation: treat the package as forkable source. Record the fork procedure (copy the class, keep the MIT notice, own the signal list) in the wrapper's docblock so a maintainer-abandonment event is a same-day, low-risk action rather than an incident.
  • Community support is thin (24 stars, 0 dependents), so internal documentation — not GitHub issues — must be our primary knowledge base.

Scaling

  • Effectively free: one array scan, O(number of signals), no allocation of note, no network or filesystem access. Negligible against any Laravel request or job budget.
  • Cost only becomes measurable if called per-request and per-job across a large fleet — solved by the singleton wrapper caching the result at bootstrap. No horizontal-scaling, throughput, or memory considerations.

Failure modes

  • False positive → feature suppression in production. Highest-severity mode: leaked COPILOT_*/CURSOR_* secrets in an image, REPL_ID on a Replit-hosted deployment, or AMP_CURRENT_THREAD_ID in an amphp-based worker could disable notifications, mail, or seeding. Severity depends entirely on what we gate; this is why gating destructive/observable behaviour is discouraged.
  • False negative → guard silently inert. A new or unlisted agent, or a subprocess that does not inherit the environment, yields "no agent" and all guards no-op. Failure is silent, which is acceptable for conveniences and unacceptable for compliance.
  • Spoofing. Any environment-controlling party can force either outcome. Security or billing decisions must never depend on this signal.
  • Environment-source mismatch. getenv() vs Laravel's .env repository vs $_SERVER (itself dependent on variables_order) can produce different answers in web vs CLI vs queue contexts. Resolve by sourcing from one documented place and asserting consistency in tests.
  • Metadata/version risk. Verify the anomalous release date and confirm the tag exists on Packagist before pinning; a phantom release would break composer install in CI.

Ramp-up

  • Developer ramp-up is near zero: one class, one method, one Composer line — a mid-level Laravel engineer is productive in under an hour, and the injected-array signature makes test writing obvious.
  • The genuine ramp-up cost is organisational: teams must agree what changes when an agent is detected, document it, and understand it is a heuristic convenience layer rather than a control. Treat the policy doc, not the package, as the deliverable.
  • Recommendation: adopt, conditionally — appropriate for developer tooling, output formatting, and telemetry attribution behind a config flag; inappropriate as a security, rate-limiting, or billing control. The 21.5 overall vs 64.9 opportunity spread reads correctly: high leverage per line of code, low ecosystem validation, and value that is entirely a function of the policy we build around it.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
roundly-consulting/kubernetes-api-for-laravel
roundly-consulting/plausible-for-laravel
gvp/gvp-laravel-template
metasyncsite/laravel-metasync-client
roundly-consulting/onboarding-for-laravel
andydefer/laravel-notification
adachsoft/cli-process-tester
jhaskell13/laraflow
sebastienheyd/boilerplate-media-manager
ccast/tagixo-primix
pretendtrue/laravel-builder
sawmainek/laravel-scout-tntsearch-driver
tomshaw/laravel-calendar-table
dibakar/laravel-ownership
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo