zipavlin/redline
Redline is a lightweight Laravel/PHP package that helps you define and enforce boundaries in your application. With simple configuration and a clean API, it adds practical guard rails and limits without heavy dependencies, making it a good fit for small to mid-sized projects.
Embedded bug/feedback intake for Laravel apps, now with an agent-facing surface. Redline is a self-hosted reporting widget plus dashboard that drops into a Laravel host app. As of v0.3.0 it also ships an MCP server, so the decisions it informs now span both the human triage workflow and whether AI coding agents are first-class consumers of your feedback backlog:
LaravelAuthProvider/LaravelGuardProvider let Redline ride your existing User session — no second login, no parallel identity store. That keeps the integration cost low enough that "adopt" beats "build our own form" for Laravel apps that want a report inbox with screenshots/video, triage states, priorities, due dates, and a widget.report_list, report_get, screenshot_get, comment_list, user_list for reads, report_create, comment_create, report_update_status for writes — served at {redline.path}/api/mcp. Writes follow dashboard rules (sanitized HTML, role permissions, status transitions, new-report mail). Decide deliberately whether "an agent can move a report to progress and comment on it" is acceptable in your org, because it is one artisan command away. Read-only adoption is not the default; the tools ship together.php artisan redline:mcp (pick a user, name it, see active tokens, revoke), start with rlm_, work only as an Authorization: Bearer header, never expire, survive logout, and are invalidated only by a password change or explicit revoke. That means a token is effectively a long-lived delegation of one person's role. If your security review or offboarding checklist can't absorb "revoke via --revoke/--revoke-all," that's a blocker, not a caveat. Conversely, if you already run Claude Code/Cursor/Codex internally, this is the cheapest path to "agents file and triage their own findings."REDLINE_DISABLED is replaced by opt-in REDLINE_FEATURES (e.g. screenshots,comments,mcp). Nothing is on until listed. This is a genuine lever: you can enable the widget on day one and hold mcp back until the token policy is signed off, or enable mcp in staging only. Two consequences to plan for: a misspelled feature name stops the app with an error (clear cached config when it happens), and GET /bootstrap now advertises only enabled features — so any custom client must tolerate capabilities disappearing.report_get leaves a new report untouched unless the agent passes mark_noticed. That preserves the meaning of the noticed timestamp (and anything you report on it) instead of letting reads silently mark the whole backlog as seen.404 when the guard is inactive on every request — API, dashboard shell, and MCP — even with route:cache/optimize, so a route cached in one environment can't expose Redline in another. One documented exception: LaravelGuardProvider can't answer before the session stack runs, so its API/MCP surface is token-gated per request instead of 404. Know which guarantee you're relying on before writing it into a security review.GET /user is open to authenticated users for the member picker, but email is developer+ only — non-developers get an explicit 422, and search matches emails only for developer/admin. New in this release: report content is user-written, so the MCP server explicitly instructs agents to treat it as data, not instructions. Treat that as a mitigation for prompt injection, not a proof.noticed → progress) auto-assigns the claimer when eligible (approved, non-guest). That policy is baked in; confirm it matches your team's norms before shipping to users.redline:update (alias redline:upgrade) with --dry-run, --force, --no-backup, plus a Composer post-package-update hook that auto-migrates with a pre-migration backup, keeps "who owns upgrades" a near-non-answer. v0.3.0 adds a pending redline_tokens migration applied by that command, so plan one maintenance touch rather than assuming it's inert.has_media is gone (use screenshot:exists/video:exists) and user_agent is no longer serialized. v0.3.0 doesn't change the contract but does narrow bootstrap to enabled features, and the element limit of 512 characters applies only over MCP — dashboard and widget are unaffected.Adopt when most of these hold:
LaravelAuthProvider/LaravelGuardProvider, the calculus is much weaker.StorageProvider on a dedicated SQLite connection; the Orbit/FileStorageProvider backend and Base/Database model layers are gone. Fine for internal volume; wrong if you need Postgres/MySQL, sharding, or heavy concurrent writes.--list, who runs --revoke-all when someone leaves.Look elsewhere when:
User to a package."version": 2, has_media removed, user_agent dropped).include[]=email and filter[email]=… 422 below developer, and search matches emails only for developer/admin.LaravelGuardProvider 404-ing its API/MCP surface pre-session. It stays token-gated per request instead — documented, but not the stronger guarantee.Migration/upgrade notes worth flagging to engineering before the bump: upgrade the host to Laravel 12.41.1+ first; existing installs must set REDLINE_FEATURES once or every feature stays off; a misspelled feature name hard-fails the app (clear cached config); run redline:update --dry-run and expect the pending redline_tokens migration on the real run; confirm the Composer post-package-update auto-migrate-with-backup behavior is acceptable in your deploy pipeline; audit any existing tokens and note that logout does not revoke them; route:cache/optimize are now safe and routes survive caching, but verify in each environment since the guard-inactive behavior is the fix; migration 0008 still prunes historical author rows from the member table, pending-approval users still get 401 with a token_version bump invalidating pre-approval tokens, and emails are normalized to lowercase and matched case-insensitively.
For executives: Redline is a self-hosted feedback and bug-reporting widget that plugs into our Laravel app and uses the login we already have — no second account system, no vendor, no data leaving our infrastructure. The new release adds the piece that changes the economics: AI coding agents can now read, file, comment on, and move reports themselves through a standard protocol, so triage stops being a human copy-and-paste job without adding headcount or a SaaS subscription. Reports can still be assigned, prioritized, and given due dates by people, and agents can be switched off entirely per environment. Two costs to acknowledge up front: it now requires Laravel 12.41.1 or newer, so any host app on Laravel 11 needs upgrading first, and agent access uses long-lived tokens that don't expire on logout — acceptable for internal tooling, but it needs a named owner for issuing and revoking them. The deliberate trade-off is unchanged: single SQLite database on one host, right for internal volume, wrong for multi-tenant scale.
For engineering: v0.3.0 is an additive release with two breaking changes. First, Laravel 11 is dropped — Laravel 12.41.1+ or 13 is required, driven by the MCP server's dependencies. Second, features are now opt-in: REDLINE_DISABLED is replaced by REDLINE_FEATURES, existing installs must set it explicitly or everything stays dark, a misspelled name throws instead of being ignored, and GET /bootstrap advertises only enabled features — so any custom client must handle absent capabilities. New: an MCP server at {redline.path}/api/mcp toggled with php artisan redline:enable mcp, plus the redline:update run for the pending redline_tokens migration; eight tools with writes going through the same sanitization, role, and status-transition rules as the dashboard; report_get only marks a report noticed when explicitly asked; no assignment tool. Tokens are rlm_-prefixed, bearer-only, never expiring, invalidated by password change but not by logout, managed via php artisan redline:mcp with --list/--revoke/--revoke-all — treat them as delegated user credentials in any threat model, and note the MCP contract lives at redline-app/contracts/mcp.md. Security posture also improved and should be called out: Redline returns 404 when the guard is inactive across the API, dashboard shell, and MCP route even under route:cache/optimize, routes now survive route caching, forbidden POST /report returns 403 instead of a server error, and the server instructs agents to treat report content as data rather than instructions (a prompt-injection mitigation, not a guarantee). Known gap: LaravelGuardProvider can't 404 before the session stack runs, so its API/MCP surface is token-gated per request — see docs/06-guards.md. Upgrade path: bump Laravel first, set REDLINE_FEATURES, run redline:update --dry-run, then confirm the Composer post-package-update auto-migrate-with-backup is acceptable in our deploy pipeline before merging.
How can I help you explore Laravel packages today?