{"_id":"@ah_kamboh/agent-eyes","_rev":"2-3c868f9112c624b046b7853517a3581b","name":"@ah_kamboh/agent-eyes","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@ah_kamboh/agent-eyes","version":"0.1.0","keywords":["ai","agent","debugging","playwright","context","coding-agent","claude","cursor","eyes","mcp"],"author":{"url":"@ahkamboh","name":"Ali Hamza Kamboh"},"license":"MIT","_id":"@ah_kamboh/agent-eyes@0.1.0","maintainers":[{"name":"ah_kamboh","email":"alihamzakamboh180@gmail.com"}],"homepage":"https://github.com/ahkamboh/agent-eyes#readme","bugs":{"url":"https://github.com/ahkamboh/agent-eyes/issues"},"bin":{"agent-eyes":"bin/agent-eyes.js"},"dist":{"shasum":"7830e2f86d5a4afa09dcef48ebe71e51f29fdcba","tarball":"https://registry.npmjs.org/@ah_kamboh/agent-eyes/-/agent-eyes-0.1.0.tgz","fileCount":14,"integrity":"sha512-IMBK+xdlmIPSr0UE1spGYTSZYolmmfATZoDgNZHkVbztpk3kDBK4FGGcSyIgspY6ei9JzxUyjo1bolDAFaLjhg==","signatures":[{"sig":"MEUCIQCPCrsfgxE39BsUZOjKMA3mLd1uQWeNh+Hw539I9oNq8wIgFybHd/o0JroIFRncyfccxKB/DjpXaf+XMt/t2YQlAq8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33690},"engines":{"node":">=18"},"gitHead":"12aaeea83cb4f9e66d8fbcba2c0483e4deebad5b","scripts":{"demo":"node bin/agent-eyes.js http://localhost:5599 --auto examples/steps.json --out .agent-eyes"},"_npmUser":{"name":"ah_kamboh","email":"alihamzakamboh180@gmail.com"},"repository":{"url":"git+https://github.com/ahkamboh/agent-eyes.git","type":"git"},"_npmVersion":"11.7.0","description":"Give your AI coding agent eyes — record any URL, auto-detect the exact moment it breaks, and hand the agent the frame + the error.","directories":{},"_nodeVersion":"25.2.1","dependencies":{"playwright":"^1.61.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/agent-eyes_0.1.0_1782915643475_0.9694494009600179","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ah_kamboh/agent-eyes","version":"0.1.1","description":"Give your AI coding agent eyes — record any URL, auto-detect the exact moment it breaks, and hand the agent the frame + the error.","bin":{"agent-eyes":"bin/agent-eyes.js"},"engines":{"node":">=18"},"scripts":{"demo":"node bin/agent-eyes.js http://localhost:5599 --auto examples/steps.json --out .agent-eyes"},"keywords":["ai","agent","debugging","playwright","context","coding-agent","claude","cursor","eyes","mcp"],"author":{"name":"Ali Hamza Kamboh","url":"@ahkamboh"},"license":"MIT","homepage":"https://github.com/ahkamboh/agent-eyes#readme","repository":{"type":"git","url":"git+https://github.com/ahkamboh/agent-eyes.git"},"bugs":{"url":"https://github.com/ahkamboh/agent-eyes/issues"},"publishConfig":{"access":"public"},"dependencies":{"playwright":"^1.61.1"},"gitHead":"054810c7ee612c0f65de9c3bbe70374483292fa5","_id":"@ah_kamboh/agent-eyes@0.1.1","_nodeVersion":"25.2.1","_npmVersion":"11.7.0","dist":{"integrity":"sha512-8105XUaG7Lid3wkpfIQRmg0OHf+1iY6jFWztUKP7KmG0eIe6xxR6wJezJL+QWGKQj+fxwu4Hql34j4rBeqMv/A==","shasum":"4ba464a7810da68537132c04a95846f715dc8003","tarball":"https://registry.npmjs.org/@ah_kamboh/agent-eyes/-/agent-eyes-0.1.1.tgz","fileCount":14,"unpackedSize":34194,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAaYB+ZU136b4x/2lHR9lAgQ35Y73xM7IK55ghwD5+3WAiEA3ysxrdhJ962J8pv4U+70IvFuUy2XuxEirBxLB3JhdjE="}]},"_npmUser":{"name":"ah_kamboh","email":"alihamzakamboh180@gmail.com"},"directories":{},"maintainers":[{"name":"ah_kamboh","email":"alihamzakamboh180@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-eyes_0.1.1_1782917209205_0.24400010076009115"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-01T14:20:43.165Z","modified":"2026-07-01T14:46:49.451Z","0.1.0":"2026-07-01T14:20:43.622Z","0.1.1":"2026-07-01T14:46:49.348Z"},"bugs":{"url":"https://github.com/ahkamboh/agent-eyes/issues"},"author":{"name":"Ali Hamza Kamboh","url":"@ahkamboh"},"license":"MIT","homepage":"https://github.com/ahkamboh/agent-eyes#readme","keywords":["ai","agent","debugging","playwright","context","coding-agent","claude","cursor","eyes","mcp"],"repository":{"type":"git","url":"git+https://github.com/ahkamboh/agent-eyes.git"},"description":"Give your AI coding agent eyes — record any URL, auto-detect the exact moment it breaks, and hand the agent the frame + the error.","maintainers":[{"name":"ah_kamboh","email":"alihamzakamboh180@gmail.com"}],"readme":"<div align=\"center\">\n\n# 👁 agent-eyes\n\n### Give your AI coding agent eyes.\n\nA **local, MIT, no-API-key** CLI that records any URL, fuses **5 signals on one clock**, **detects the moments that break**, and hands your coding agent the exact frame + the error — so it stops guessing.\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-black.svg)](LICENSE)\n[![Node 18+](https://img.shields.io/badge/Node-18%2B-black.svg)](https://nodejs.org)\n[![Playwright](https://img.shields.io/badge/Playwright-powered-black.svg)](https://playwright.dev)\n[![No API key](https://img.shields.io/badge/API%20key-none-black.svg)](#)\n[![Local](https://img.shields.io/badge/runs-100%25%20local-black.svg)](#)\n\n`npx @ah_kamboh/agent-eyes <url>`\n\n</div>\n\n---\n\n## ⚡ Paste this into your AI agent (one-time setup)\n\nPaste this **once** into Claude Code / Cursor / Codex. It installs agent-eyes and **saves a rule to your global agent config** — so your agent runs it *first* on any UI bug in **every project**, automatically, not just this chat.\n\n```text\nSet up agent-eyes and make it stick across EVERY project.\n\n1) Install once (global — works in every project after this):\n   npm install -g @ah_kamboh/agent-eyes && npx playwright install chromium\n   (needs Node 18+ and ffmpeg on PATH — no API key, fully local)\n\n2) Make the rule PERMANENT — write it into my GLOBAL agent-rules file so it\n   applies to every project automatically (not just this conversation):\n     - Claude Code -> ~/.claude/CLAUDE.md\n     - Cursor      -> Settings > Rules > User Rules\n     - Codex       -> global AGENTS.md\n   The rule to save, verbatim:\n     \"Whenever I report a UI bug or ask 'why didn't X work' — BEFORE editing code —\n      run agent-eyes on the page first:\n        npx @ah_kamboh/agent-eyes <url>                     (I drive the broken flow), or\n        npx @ah_kamboh/agent-eyes <url> --auto steps.json   (replay steps headless).\n      Then read .agent-eyes/session.json — the markers[] array FIRST (silent-failure,\n      dead-click, visual-review); open the frame each marker points to and LOOK;\n      fix from that ground truth, don't guess from code; re-run to confirm.\"\n\n3) Confirm the rule is saved, then follow it from now on.\n```\n\n> Pasting into a chat only lasts that session — saving it to the global rules file above is what makes agent-eyes fire **automatically in every project**.\n\n---\n\n## The problem\n\nYour agent is blind.\n\nWhen you say *\"the signup is broken,\"* a console-only agent sees a form that looks completely normal. It can't watch the click. It can't see the `422` come back. It can't tell that the screen never changed. So it **guesses** — and guessing means wrong edits, extra edits, and burned tokens on a bug it never actually saw.\n\nMillions of new \"vibe coders\" only know how to prompt. They don't know to open the console or the network tab. Neither does their agent — unless you give it eyes.\n\n**agent-eyes** lets the agent *run the app first*, watch what really happens, and get ground truth before it touches a single line.\n\n---\n\n## ⚡ The proven demo\n\nWe pointed agent-eyes at a broken signup form. To a console-only agent, the form looks fine — so it guesses. Here's what agent-eyes said instead:\n\n```\n🔴 silent-failure @ 0.35s — click #submit → 422 POST /api/signup → screen did not change (no user-visible feedback)   (frames/f002.jpg)\n```\n\nAnd here is `frames/f002.jpg` — the frame captured at that exact moment:\n\n> The form looks **totally fine**. No error banner. No red text. Nothing.\n\n**That's the whole point.** The failure is *invisible on screen*. The user clicked submit, the server rejected it with a `422`, and the UI gave zero feedback. A screenshot alone lies to you. A console log alone is a haystack. agent-eyes fuses them and says: *here is the frame, here is the click that caused it, here is the status code, and here is why it's a bug.*\n\nThe agent jumps straight to the fix.\n\n---\n\n## Install\n\n```bash\nnpm install -g @ah_kamboh/agent-eyes    # or run ad-hoc: npx @ah_kamboh/agent-eyes <url>\nnpx playwright install chromium         # one-time: downloads the headless browser\n```\n\n**Requirements:** Node 18+ · `ffmpeg` on your PATH · no API key, fully local.\n**Source:** [github.com/ahkamboh/agent-eyes](https://github.com/ahkamboh/agent-eyes)\n\n---\n\n## CLI usage\n\n```bash\nnpx @ah_kamboh/agent-eyes <url> [--auto steps.json] [--seconds N] [--out dir] [--fps N] [--headed]\n```\n\n| Mode | Command | What happens |\n|------|---------|--------------|\n| **Manual** | `npx @ah_kamboh/agent-eyes <url>` | Opens a real browser window. You click around. Stops when you close the window or after `--seconds`. |\n| **Auto** | `npx @ah_kamboh/agent-eyes <url> --auto steps.json` | Headless. Replays your `steps.json` and captures everything. |\n\n**Flags**\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--auto <file>` | — | Replay a steps file headlessly instead of driving by hand |\n| `--seconds N` | — | Stop after N seconds |\n| `--out <dir>` | `.agent-eyes` | Output directory |\n| `--fps N` | — | Frame capture rate |\n| `--headed` | off | Force a visible window even in auto mode |\n\n**steps.json** is a simple list of actions:\n\n```json\n[\n  { \"fill\": \"#email\", \"value\": \"test@example.com\" },\n  { \"click\": \"#submit\" },\n  { \"wait\": 1200 }\n]\n```\n\n**Output** (default `.agent-eyes/`):\n\n- `session.json` — **markers[] first**, then `timeline[]` + `frames[]`\n- `frames/f###.jpg` — the captured frames\n- `run.mp4` — the full recording\n\nPoint it at anything: your localhost, a live site, or someone else's page.\n\n---\n\n## What it captures — 5 streams, one clock\n\nEverything is timestamped against a **single shared clock**, so a click, the request it fired, the console error it threw, the DOM change it caused (or didn't), and the frame on screen all line up to the same moment.\n\n| Stream | | What it records |\n|--------|--|-----------------|\n| 👁 **Video / frames** | | Screenshots + `run.mp4` of the actual pixels |\n| 🖱 **Actions** | | Every click, fill, and navigation |\n| 🧾 **Console** | | Logs, warnings, and JS errors |\n| 🌐 **Network** | | Requests + **response status codes** (the 4xx/5xx that matter) |\n| 🏷 **DOM changes** | | What actually changed in the page after each action |\n\nRecording all five is table stakes. The value is what comes next.\n\n---\n\n## The markers = the hero\n\nPlaywright Trace and other recorders already dump all the events. That's the problem — they dump **all** the events. Five hundred rows of timeline is not insight; it's a second haystack.\n\nagent-eyes' job is **detection**. It finds the 1–3 moments that actually broke and points the agent straight at them, with the frame attached. The agent *jumps to the problem* instead of sifting.\n\n**Detectors in v0.1:**\n\n| Detector | Fires when | Why it matters |\n|----------|-----------|----------------|\n| 🔴 **silent-failure** *(flagship)* | An action caused a **4xx/5xx or JS error**, but the UI showed the user **nothing** | Looks fine, is broken. The most expensive bug to catch by eye. |\n| ⚪ **dead-click** | You clicked and **nothing happened** — no DOM change, no request, no navigation | The button that isn't wired up. |\n| 🔵 **visual-review** | A frame worth eyeballing | Hands your already-vision-capable agent the exact image to check for blank / broken / overlapping UI. |\n\nDetection is why agent-eyes beats a raw recording: it doesn't just show the agent everything — it shows the agent **what's wrong**.\n\n---\n\n## session.json shape\n\n`markers[]` come first — that's what the agent reads before anything else:\n\n```json\n{\n  \"t\": 0.347,\n  \"kind\": \"silent-failure\",\n  \"frame\": \"frames/f002.jpg\",\n  \"summary\": \"click #submit → 422 POST /api/signup → screen did not change\",\n  \"evidence\": {\n    \"action\":  { \"type\": \"click\", \"selector\": \"#submit\", \"t\": 0.31 },\n    \"trigger\": { \"type\": \"network\", \"method\": \"POST\", \"url\": \"/api/signup\", \"status\": 422, \"t\": 0.34 }\n  }\n}\n```\n\nEach marker carries a timestamp, a kind, the frame to look at, a human summary, and the **evidence** — the action that caused it and the trigger that proves it. After `markers[]` come the full `timeline[]` and `frames[]` if the agent wants to dig deeper.\n\n---\n\n## How it works\n\n```\n   record  ─▶  frames  ─▶  detect  ─▶  emit\n      │           │          │          │\n  Playwright   ffmpeg     fuse 5      session.json\n  drives the   slices     streams     (markers[] first)\n  page &       the .mp4   on one      + frames/*.jpg\n  taps all 5   into       clock,      + run.mp4\n  streams      f###.jpg   flag the\n                          moments\n```\n\n1. **Record** — Playwright opens the URL and taps all five streams against one clock (manually, or replaying `steps.json`).\n2. **Frames** — ffmpeg turns the recording into indexed JPGs so every moment has an image.\n3. **Detect** — the fused timeline runs through the detectors; the 1–3 real problems get flagged and matched to their frame.\n4. **Emit** — everything is written to `session.json` (markers first), plus the frames and the full video.\n\n---\n\n## Honest limits\n\n- **\"Any URL\" is client-side only.** agent-eyes sees console, network, DOM, and pixels — the browser's view. It **cannot see someone else's server**. When it flags a `500`, it's reporting the response the browser received, not reading their backend.\n- **The recording engine is commodity.** Playwright Trace and RCE record too. The value here is the **markers** + **record-anything** + the **agent-first \"run it first\" UX** — not the recording itself.\n- **Visual heuristics are early.** v0.1 catches JS crashes and 4xx/5xx with no UI feedback. Blank-frame, overflow, and stuck-spinner detection are coming (see roadmap).\n- **Not affiliated** with Playwright, Cursor, Anthropic, or anyone else.\n\n---\n\n## Roadmap\n\nMore detectors — the recording stays the same; the intelligence grows:\n\n- [ ] **overflow** — content spilling / clipped layout\n- [ ] **blank-frame** — the page rendered nothing\n- [ ] **stuck-spinner** — a loader that never resolves\n- [ ] **regression-vs-baseline** — diff this run against a known-good one and flag what changed\n- [ ] richer visual heuristics for overlapping / broken UI\n\n---\n\n<div align=\"center\">\n\n**MIT © 2026 [Ali Hamza Kamboh](https://github.com/ahkamboh) ([@ahkamboh](https://github.com/ahkamboh))**\n\nRepo: [github.com/ahkamboh/agent-eyes](https://github.com/ahkamboh/agent-eyes)\n\nBuilt with Claude Code.\n\n</div>","readmeFilename":"README.md"}