igclabs/floop

An autonomous feedback loop for Laravel. Testers submit feedback, AI agents fix the code. No database, no tickets, no waiting.

Maintainers

Package info

github.com/igclabs/floop

pkg:composer/igclabs/floop

Statistics

Installs: 64

Dependents: 0

Suggesters: 0

Stars: 12

Open Issues: 1

v0.3.23 2026-02-19 21:29 UTC

README

Floop Logo

An autonomous feedback loop for Laravel apps. Testers describe what they want. AI agents make it happen.

Feedback in. Fixes out. That's the floop.

Full Documentation

The Loop

  1. You notice something while browsing the app and hit the floop button
  2. Floop captures the intent + full page context (URL, route, controller, blade views, viewport etc) and writes a structured work order as a markdown file
  3. Ask your AI agent to "work through feedback" and it reads each file, locates the exact code using the captured context, makes the change, and closes the loop
  4. You verify the fix the next time you browse the screen

It's a feedback loop compressed into a single tool. In cybernetics, a system becomes self-correcting when it can sense errors and act on them. Floop gives your Laravel app that ability: the widget is the sensor, the markdown files are the signal, and your AI agent is the actuator.

Use Floop while your agent is busy working. Browse the app, queue up work orders, then process them in batches. ..or run it continuously in a dedicated terminal and watch as your app fixes itself while you browse.

Installation

composer require --dev igclabs/floop:@dev

Floop is a development tool — install it as a dev dependency so it's never deployed to production. The service provider is auto-discovered, the middleware registers itself, and the widget is automatically injected into every HTML response. Browse any page and you'll see the floop button.

Install the agent skill:

php artisan floop:install-skill

Now when you ask Claude Code to "work through feedback" or "process feedback", it knows exactly how to read the work orders, locate the code, make the changes, and close each loop.

How It Works

  • A floating button appears in the corner of every page
  • Users type what they want and hit Enter (or click)
  • Each submission generates a structured work order as a .md file in storage/app/feedback/pending/
  • The work order captures everything an agent needs: the controller method, Blade view hierarchy, route info, viewport, and the message
  • Click any element on the page to attach its CSS selector, tag, and text to the work order
  • Capture a screenshot of the current page state with one click
  • Console errors and failed network requests are automatically monitored and can be attached to any submission
  • A "floop" sound confirms the submission

When the agent processes a work order, it moves from pending/ to actioned/. The loop is closed.

storage/app/feedback/
├── pending/      ← open work orders
└── actioned/     ← closed loops

What It Captures

Every work order includes the tester's message plus everything an agent needs to find and fix the code:

  • Page context — URL, route name, controller method, HTTP method, viewport size, authenticated user
  • Blade views — every view and partial rendered on the page, not just the main one
  • Targeted element — click any element to capture its CSS selector, tag name, and text content
  • Screenshot — one-click page capture, saved as a companion PNG alongside the work order
  • Console errors — automatically monitored; attach up to 5 deduplicated errors to a submission
  • Network failures — failed HTTP requests (status 400+) captured automatically with method, URL, and status code

Here's what a work order looks like:

# 💬 Feedback: The submit button is too small on mobile

**Status:** 🟡 Pending
**Created:** 2026-02-16 14:30:00
**Type:** Feedback
**Priority:** 🔴 High

---

## Message

The submit button is too small on mobile. I can barely tap it.

---

## Page Context

| Property | Value |
|----------|-------|
| **URL** | `https://myapp.test/orders` |
| **Route** | `orders.index` |
| **Controller** | `App\Http\Controllers\OrderController@index` |
| **Method** | `GET` |
| **View** | `orders.index` |
| **User** | Joe (joe@example.com) |
| **Viewport** | 375x812 |

### Blade Views

- `layouts.app`
- `orders.index`
- `partials.header`
- `components.order-table`

---

## Targeted Element

| Property | Value |
|----------|-------|
| **Selector** | `#order-form > div.actions > button.btn-submit` |
| **Tag** | `BUTTON` |
| **Text** | Submit Order |
| **Position** | 340, 520 (240×36) |

---

## Screenshot

![Screenshot](2026-02-16_143000_the-submit-button-is-too-small.png)

CLI Commands

# List work orders (defaults to pending)
php artisan floop:list
php artisan floop:list --status=actioned
php artisan floop:list --type=bug

# Close the loop / reopen
php artisan floop:action filename.md
php artisan floop:action filename.md --note="What you changed"  # appends an "Agent Notes" section to the work order
php artisan floop:action filename.md --reopen

# Install agent skill
php artisan floop:install-skill             # auto-detects .claude, .codex, .agents, .opencode
php artisan floop:install-skill --choose    # manually pick targets
php artisan floop:install-skill --force     # overwrite existing

# Clear work orders
php artisan floop:clear              # clear pending
php artisan floop:clear --actioned   # clear actioned
php artisan floop:clear --all        # clear everything

# Watch for work orders and process them autonomously
php artisan floop:watch
php artisan floop:watch --once              # process current pending items then exit
php artisan floop:watch --interval=10       # poll every 10 seconds (default: 5)
php artisan floop:watch --timeout=120       # max 120s per work order (default: 300)
php artisan floop:watch --model=sonnet      # use a specific Claude model

# Enable / disable the widget
php artisan floop:enable
php artisan floop:disable

Autonomous Mode

Run Floop in a dedicated terminal and watch as your app fixes itself while you browse:

php artisan floop:watch

The watcher polls the pending directory for new work orders, dispatches each one to Claude Code (claude -p), and streams the output in real-time. When Claude finishes a work order, it runs floop:action to close the loop and moves on to the next one. Work orders are processed sequentially (oldest first) to avoid code conflicts.

Use --once to process the current queue and exit — useful for CI or one-off batch runs. Configure defaults in config/floop.php under the watch key.

Configuration

Publish config (optional):

php artisan vendor:publish --tag=floop-config

Key options in config/floop.php:

Key Default Description
auto_inject true Auto-inject widget into HTML responses (set false to use @floop manually)
storage_path storage_path('app/feedback') Where work order files are stored
route_prefix _feedback URL prefix for the submission endpoint
environments ['local'] Environments where the widget renders (['*'] for all)
position bottom-right Widget position: bottom-right, bottom-left, top-right, top-left
shortcut ctrl+shift+f Keyboard shortcut to toggle the feedback panel
hide_shortcut ctrl+shift+h Keyboard shortcut to hide/show the entire widget
default_type feedback Default feedback type
watch.interval 5 Seconds between polling for new work orders
watch.timeout 300 Max seconds per work order before timeout
watch.tools Bash,Read,Edit,... Comma-separated Claude tools to allow
watch.model null Claude model override (uses default if null)

Customisation

By default, Floop auto-injects the widget before </body> on every HTML response. If you want manual control over placement:

1. Disable auto-injection in config/floop.php:

'auto_inject' => false,

2. Add @floop to your Blade layout (before </body>):

@floop

Keyboard Shortcuts

  • Ctrl+Shift+F = toggle the feedback panel open/closed
  • Ctrl+Shift+H = hide/show the entire widget
  • Enter = submit (when typing in the textarea)
  • Shift+Enter = new line in the textarea
  • Escape = close the panel

Design

  • Self-contained: all CSS and JS are inline, no CDNs or external assets
  • Filesystem-native: lives in your repo, not your infrastructure
  • Dark mode: respects prefers-color-scheme: dark and data-bs-theme="dark"
  • All styles scoped under #floop-widget to avoid conflicts
  • Submit sound synthesized via Web Audio API (no audio files)
  • Dispatches FeedbackStored and FeedbackActioned events so you can hook in notifications, webhooks, or custom integrations

Roadmap

  • React & Vue support : first-class components for React and Vue so the widget integrates natively into SPA and Inertia apps instead of relying on Blade injection
  • Storage interface & drivers : a pluggable storage layer so work orders can live in a database, S3, or any custom driver instead of only the local filesystem
  • Team testing tools : better support for multi-tester workflows: assignments, labels, filtering, and visibility controls so teams can triage and track feedback together

Made by

Floop is built and maintained by Intelligent Graphic & Code, a development studio in the UK.

License

MIT