承接 loupekit/laravel 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

loupekit/laravel

Composer 安装命令:

composer require loupekit/laravel

包简介

Loupe for Laravel — embeddable visual feedback that stores comments in your own database, gates access per user, serves the Loupe dashboard, and exposes the backlog to Claude Code over MCP.

README 文档

README

Loupe — Pin feedback to the live UI. Hand it to Claude.

loupekit/laravel

Loupe for Laravel — visual feedback, in your own app.
Your users pin a comment to any element on your live product and capture a screenshot.
Comments are stored in your database, gated to your users, triaged on your dashboard,
and handed to Claude Code over MCP — no separate backend to run.

Packagist version Packagist downloads PHP version Laravel 11, 12, 13 100% test coverage MIT license

Website · GitHub · Full guide · Changelog · SDK

Overview

Traditional feedback — "the revenue card looks off on the dashboard" — loses the one thing an engineer needs: which element, in what state, on which page. Loupe captures all of it at the moment of the comment. This package brings that loop into any Laravel app: the widget is a single Blade directive, comments are Eloquent rows in your database, and the triage board is a route you own behind your auth.

Pin a comment to any element

Table of contents

Features

🎯 Click-to-comment inspector Hover-highlight any element, click to pin a comment — dropped in with one @loupeWidget directive.
Free-region screenshots Drag a free-size box, screenshot exactly that area, comment on it. Anchors to the element under its center so it tracks reflow and scrolling.
🔁 Redeploy-surviving re-anchoring A multi-signal fingerprint re-locates the element after the UI changes; if it can't, the pin detaches instead of pointing at the wrong thing.
🗄️ Your database Comments are an Eloquent Comment model in a loupe_comments table. Swap in your own subclass to add relations/scopes.
🔐 Per-user gating loupe:use / loupe:admin Gate abilities and config closures decide who sees the widget and who opens the dashboard.
📋 Dashboard on your routes The full Kanban triage board at /loupe/dashboard, behind your session auth.
🤖 Claude Code over MCP php artisan mcp:start loupe hands Claude the fully-contextual backlog.
🔑 No secrets to manage Authenticates with your existing session + CSRF token. No HMAC keys.
100% tested A Testbench suite with a hard 100% line-coverage gate, across Laravel 11/12/13.

Requirements

Supported
PHP 8.4 and higher
Laravel 11, 12, 13
Database anything Eloquent supports (MySQL, PostgreSQL, SQLite, SQL Server)
MCP (optional) laravel/mcp ^0.8 — Laravel 11, 12 & 13

Install

composer require loupekit/laravel
php artisan loupe:install
php artisan migrate

loupe:install publishes the config, migration and browser assets (to public/vendor/loupe), then publishes and registers an App\Providers\LoupeServiceProvider where you control access.

Quick start

1. Add the widget to your Blade layout, just before </body>:

@loupeWidget
</body>

2. Decide who sees it. By default the widget and dashboard are visible only in local. Open app/Providers/LoupeServiceProvider.php and grant access:

Gate::define('loupe:use', fn ($user) => $user->is_staff);   // who sees the widget
Gate::define('loupe:admin', fn ($user) => $user->is_admin);  // who opens the dashboard

3. Open the board at /loupe/dashboard. That's the whole setup.

How it works

flowchart LR
  subgraph App["Your Laravel app"]
    W["@loupeWidget<br/>(Loupe SDK)"]
    API["/loupe/v1/*<br/>Comment + Blob controllers"]
    DASH["/loupe/dashboard<br/>Kanban board"]
    DB[("loupe_comments<br/>your database")]
    FS[["screenshots<br/>your disk"]]
    MCP["php artisan<br/>mcp:start loupe"]
  end
  CLAUDE["Claude Code"]

  W -->|"session cookie + CSRF"| API --> DB
  API --> FS
  DASH --> API
  MCP --> DB
  CLAUDE <-->|MCP| MCP
Loading

Identity is always the authenticated session user (auth()->user()); the store endpoint rejects a comment whose author.id is not the current user, so nobody can post as someone else.

Authorization — who can use it

Two abilities, checked in this order — config closure, then Gate ability:

// Option A — Gate abilities (in the published App\Providers\LoupeServiceProvider)
Gate::define('loupe:use',   fn ($user) => $user->hasRole('staff'));
Gate::define('loupe:admin', fn ($user) => $user->hasRole('admin'));

// Option B — config closures (config/loupe.php); take precedence over the Gates
'authorize' => [
    'use'       => fn ($user) => $user->can_give_feedback,
    'dashboard' => fn ($user) => $user->is_admin,
],

Denied users never receive the widget markup, and the API/dashboard return 403.

The dashboard

The full Kanban board — open / in progress / done, page filter, screenshot thumbnails, status moves, delete, and Copy for Claude — served at /loupe/dashboard behind your web+auth middleware and the loupe:admin ability. Configuration is injected server-side, so no secret ever reaches the browser.

Triage board

Claude Code over MCP

With laravel/mcp installed, a local MCP server named loupe is registered automatically:

php artisan mcp:start loupe

It reads your database directly (no HTTP hop, no admin key) and exposes three tools:

Tool Arguments Returns
list_comments status?, url? the backlog, newest first
get_comment id Claude-ready package: request + element HTML + computed styles + screenshot (or region rect)
update_status id, status marks a comment open / in_progress / done
Hand the backlog to Claude

Configuration

config/loupe.php (published by loupe:install):

Key Default Purpose
enabled true Master switch.
path loupe Route prefix for the API + dashboard.
project_key app Scopes comments (one app = one project).
middleware.api ['web','auth'] Guards the JSON API.
middleware.dashboard ['web','auth'] Guards the dashboard.
authorize.use / authorize.dashboard null Closures fn($user): bool (take precedence over Gates).
user_resolver null Customize the {id,name,email} payload sent to the SDK.
comment_model Loupekit\Loupe\Models\Comment Swap for your own subclass.
disk public Filesystem disk for screenshots.

See the full guide for Sanctum/SPA setups, private screenshot disks, and the complete reference.

Data model

Migration create_loupe_comments_tableloupe_comments:

Column Type Notes
id string (PK) client-generated UUID
project_key string, indexed scopes to this app
url text normalized (utm / click ids stripped)
status string, indexed open · in_progress · done
body text the comment
kind string element · region
author / author_id json / string {id,name,email?} + denormalized id
anchor / context / offset json fingerprint, element HTML + styles, pin position
region json, nullable rectangle for region comments
screenshot_url text, nullable URL of the stored screenshot
created_at / updated_at timestamps

Try it locally

Point a scratch Laravel app at this package with a path repository:

// composer.json of your test app
"repositories": [
  { "type": "path", "url": "../loupe/packages/laravel" }
]
composer require loupekit/laravel:@dev
php artisan loupe:install && php artisan migrate
# add @loupeWidget to resources/views/…​, log in, and open /loupe/dashboard

Publishing

This package lives in the Loupe monorepo under packages/laravel. Packagist reads a repo's root composer.json, so it's mirrored to a dedicated repo automatically by .github/workflows/laravel-split.yml:

  • every push to main syncs the split repo's main;
  • every vX.Y.Z tag is forwarded to the split repo → Packagist auto-updates.

The same tag also drives the npm release (@loupekit/*), so one vX.Y.Z tag ships the npm packages and the Packagist package together.

One-time setup:

  1. Create the target repo (default loupekit/laravel; override via the LARAVEL_SPLIT_ORG / LARAVEL_SPLIT_REPO repository variables).
  2. Add a Personal Access Token with repo scope as the ACCESS_TOKEN secret.
  3. Submit the split repo once at packagist.org/packages/submit and enable Auto-update (the Packagist GitHub webhook).

After that, releasing is just: git tag -a vX.Y.Z && git push --tags.

Testing

composer install
composer test               # run the suite
composer test:coverage-100  # run with the hard 100% coverage gate

Every push runs the suite across Laravel 11/12/13 in CI (.github/workflows/laravel.yml). The browser bundles in resources/dist are vendored from @loupekit/sdk and @loupekit/dashboard; refresh them with bin/sync-assets.sh after changing either.

Related packages

Author

Created and maintained by Mohamed Ashraf ElsaedLinkedIn · GitHub · m.ashraf.saed@gmail.com

License

MIT © Mohamed Ashraf Elsaed

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-07-11

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固