147 lines
5.2 KiB
Markdown

# 🏭 GooseFactory HITL Modals
> Interactive MCP App modals for Human-in-the-Loop feedback collection.
## What's Here
5 production-ready, self-contained HTML modals designed for sandboxed iframes inside AI chat interfaces:
| Modal | File | Use Case | Key Feature |
|---|---|---|---|
| 🚦 **Traffic Light** | `src/traffic-light.html` | Pass/Polish/Rework decisions | LED glow, tag pills, response time tracking |
| 📋 **Report Card** | `src/report-card.html` | Multi-dimension grading (A-F) | Bubble-fill animation, GPA auto-calc, grade change tracking |
| ⚡ **Speed Round** | `src/speed-round.html` | Batch pass/fail (timed) | 60s timer, streak counter, skip detection, full stats |
| ⚔️ **Side-by-Side Arena** | `src/side-by-side.html` | A/B comparison | Hover time tracking, per-dimension breakdown, winner celebration |
| 🌡️ **Thermometer** | `src/thermometer.html` | Subjective quality (0-100) | Draggable mercury, bg color transitions, particles, drag journey capture |
## Quick Start
```bash
# Serve the preview page
npx serve src/preview -p 3333
# Or serve all files for direct access
npx serve src -p 3334
```
Then open `http://localhost:3333` for the interactive preview environment.
## Architecture
### Self-Contained
Each modal is a **single HTML file** with inline CSS and JS. No external dependencies. This is intentional — modals are served as MCP App resources inside sandboxed iframes.
### Communication Protocol
Every modal follows the `CONTRACTS.md` §3 "Modal Data Contract":
```
Host → Modal: window.__FACTORY_CONTEXT__ (injected before load)
Modal → Host: window.parent.postMessage()
```
#### Message Types
| Type | Direction | When |
|---|---|---|
| `factory_modal_ready` | Modal → Host | Modal loaded and interactive |
| `factory_modal_response` | Modal → Host | User submitted feedback |
| `factory_modal_close` | Modal → Host | Modal wants to close |
| `factory_modal_resize` | Modal → Host | Modal wants to change size |
| `factory_modal_error` | Modal → Host | Modal hit an error |
### Hidden Behavioral Metrics
Every modal automatically captures:
- `timeToFirstInteractionMs` — How long before user engaged
- `timeToDecisionMs` — Total time from open to submit
- `totalInteractions` — Click/tap count
- `fieldsModified` — Which inputs were changed
- `deviceType` — Mobile vs desktop
- `viewportSize` — Screen dimensions
Plus modal-specific metrics:
- **Traffic Light**: `responseTimeMs` (fast = high confidence)
- **Report Card**: `gradeChanges` (mind-change tracking)
- **Speed Round**: Per-item `timeMs`, streaks, speed curve
- **Side-by-Side**: `hoverTimeA/B` (attention distribution)
- **Thermometer**: `dragJourney` (full temperature path during drag)
## File Structure
```
packages/modals/
├── package.json
├── README.md ← You are here
├── src/
│ ├── traffic-light.html ← 🚦 Pass/Polish/Rework
│ ├── report-card.html ← 📋 A-F grading
│ ├── speed-round.html ← ⚡ Timed batch review
│ ├── side-by-side.html ← ⚔️ A/B comparison
│ ├── thermometer.html ← 🌡️ Quality temperature
│ ├── shared/
│ │ └── modal-utils.js ← Canonical utility functions
│ └── preview/
│ └── index.html ← Dev preview page with mock context & console
```
## Design Principles
1. **3-Second Rule** — Instantly obvious what to do
2. **Dopamine Design** — Every interaction feels satisfying
3. **Data Density** — Rich signal from every tap/drag/click
4. **Dark Mode First**`#111` background, designed for chat panels
5. **Touch-Friendly** — 48px minimum tap targets
6. **400-600px Width** — Optimized for chat panel constraints
## Integrating with GooseFactory
### MCP App Host Usage
```typescript
// In your MCP tool response:
const response = {
_meta: {
goose: {
toolUI: {
displayType: "inline",
name: "Traffic Light Review",
renderer: "mcp-ui",
},
},
},
content: [{
uri: "ui://factory-modal",
mimeType: "text/html",
text: trafficLightHtml, // The full HTML file content
}],
};
```
### McpAppHost Component
The host component (React/Desktop) should:
1. Create a sandboxed iframe with `allow-scripts allow-forms`
2. Inject `window.__FACTORY_CONTEXT__` before the modal HTML
3. Listen for `postMessage` events
4. Forward `factory_modal_response` to `POST /v1/feedback`
5. Handle timeouts gracefully
See `CONTRACTS.md` §4.4 for the full `McpAppHost` component contract.
## Preview Page
The preview page at `src/preview/index.html` provides:
- Sidebar with all 5 modals
- 500px-wide iframe with simulated device chrome
- Mock context data (editable pipeline/item names)
- Real-time `postMessage` console showing all events
- Reload and new-window buttons for testing
## Next Modals (Planned)
The design doc (`design-hitl-modal-collection.md`) defines 25 total modals. Next batch:
- 🃏 Tinder Swipe — Batch card swiping
- 🎯 Spotlight — Code annotation with attention heatmap
- 🏆 Judge's Scorecard — Olympic-style weighted scoring
- 🎲 Priority Poker — Fibonacci estimation cards
- 🔫 Mission Briefing — High-stakes go/no-go with flight checks