agent-comments
v0.1.4
Published
Right-click any element in your web app, leave a comment, and let your AI coding agent pull the feedback and implement it.
Maintainers
Readme
Agent Comments
Comment on your UI. Let your AI agent fix it.
⌘ + right-click any element in your running web app, say what should change, and your coding agent
(Claude Code, or anything that can read HTTP) picks it up the moment you hit enter - finds the code,
makes the change, and marks the comment resolved. The pin turns green in your browser.
It's the Claude Design / Figma comment loop, but on your real app and your real codebase.
flowchart LR
browser["you, in the browser<br/>⌘+right-click element<br/>"make this smaller""]
server["local server<br/>localhost:4747<br/>.agent-comments/*.json"]
agent["your agent<br/>watch → implement<br/>→ resolve with note"]
browser -- POST --> server
server -- SSE --> agent
agent -- PATCH --> server
server -- "live · pin turns green" --> browser
classDef browser fill:#dbeafe,stroke:#2563eb,color:#1e3a8a
classDef server fill:#fef3c7,stroke:#d97706,color:#78350f
classDef agent fill:#dcfce7,stroke:#16a34a,color:#14532d
class browser browser
class server server
class agent agent- Zero dependencies. One custom element, one Node server, one CLI. Nothing to configure.
- Framework-agnostic. Works anywhere HTML does. First-class React/Next.js wrapper included.
- Context-rich. Each comment captures the selector, text, HTML, ancestors, computed style, and — in React/Vue/Svelte dev mode — the source file and line, so the agent opens the right file.
- Live. Server-sent events both ways: the agent sees comments instantly; you see resolutions instantly.
- Local by default, hostable by design. Comments live in a JSON file in your repo. The same server
runs as a shared service with
projectscoping and token auth when you want it to.
Quick start
npm i -D agent-comments1. Add it to your app (dev only)
Next.js / React
// app/layout.tsx (or pages/_app.tsx)
import { AgentComments } from 'agent-comments/react';
export default function RootLayout({ children }) {
return (
<html><body>
{children}
<AgentComments />
</body></html>
);
}Renders nothing unless NODE_ENV === 'development'.
Any HTML / Astro / Vue / Svelte
<script type="module"
src="http://localhost:4747/agent-comments.js"></script>
<agent-comments collapsed></agent-comments>Astro: wrap in {import.meta.env.DEV && (…)} and add is:inline to the script.
2. Install the agent skill (once, global)
npx agent-comments install-skill # → ~/.claude/skills/agent-commentsUsing something other than Claude Code? The skill is a single plain-markdown file —
skill/SKILL.md — copy it
wherever your framework loads instructions from (Cursor rules, an AGENTS.md, a custom system prompt),
or skip it entirely and point your agent at the HTTP API directly.
3. Start the loop
In Claude Code, in your app's repo:
/agent-commentsThe agent starts the server if it isn't running, arms a background listener, and tells you it's ready.
Open your app, ⌘+right-click (Ctrl on Windows/Linux) anything, type, ⌘+Enter. Watch the pin turn green.
Prefer to run the server yourself?
npx agent-comments servefrom the repo root. Want a sandbox?npx agent-comments serve --demo→ http://localhost:4747
What the agent sees
$ npx agent-comments list
## #3 [open] make this button match the primary colour
- **Page:** http://localhost:3000/pricing (Pricing)
- **Selector:** `[data-testid="cta"]`
- **Source:** `src/components/Hero.tsx:42`
- **Component:** Hero
- **Text:** "Get started"
- **HTML:**
```html
<button class="btn secondary" data-testid="cta">Get started</button>
And live, one line per event from `npx agent-comments watch`:
PENDING #2 id=3f9a1c2e page=/about el=main > h1 src=src/pages/about.astro:12 text="About me" :: make this smaller NEW #3 id=8b21d0aa page=/pricing el=[data-testid="cta"] component=Hero :: match the primary colour
The full record (`--json`) also includes attributes, bounding rect, computed style, ancestors, viewport
and user agent.
### How the source location is found
1. **Exact (`src=`)** — dev-mode markers the component reads off the element: React `_debugSource`
(React ≤18), Vue `__file`, Svelte `__svelte_meta`, and build-time stamp attributes such as
`data-insp-path` ([code-inspector-plugin](https://github.com/zh-lx/code-inspector)),
`data-locatorjs-id`, `data-sentry-source-file`, or a `data-src="file:line"` from your own transform.
React 19 / current Next.js no longer expose `_debugSource`, so install one of those plugins in dev
for exact locations — the cost is one string attribute per element, dev only.
2. **Likely (`likely=`)** — when there's no exact marker, the server `git grep`s the repo it was started
in (`--root <dir>`, default cwd; `--root off` disables) for the element's test id, id, text, component
name and class combos, and attaches up to five `file:line` candidates. Heuristic — the agent verifies.
---
## Component
```html
<agent-comments
server="http://localhost:4747" <!-- default -->
modifier="meta ctrl" <!-- which key + right-click opens it: meta | ctrl | shift | alt -->
collapsed <!-- start with the panel closed; pins still show -->
position="bottom-center" <!-- button/panel placement: bottom-center | bottom-left | bottom-right | top-center | top-left | top-right -->
project="my-app" <!-- scope, for shared servers -->
token="…" <!-- bearer token, for hosted servers -->
></agent-comments>Everything renders in a shadow root, so it won't fight your CSS. Pins are shown for comments whose page path matches and whose selector still resolves. Plain right-click is never intercepted.
React props mirror the attributes (server, project, token, collapsed, position, plus enabled to
override the dev-only default).
CLI
agent-comments serve [--port 4747] [--file .agent-comments/comments.json] [--root <dir>|off] [--retain <dur>] [--demo] [--token X]
agent-comments watch [--once] [--json] [--timeout <sec>] one line per new comment
agent-comments list [--status open|resolved] [--all] [--json]
agent-comments resolve <id> [note...]
agent-comments reopen <id> [new comment...] | delete <id> | clear [--all]
agent-comments install-skill [--project]
agent-comments snippetEnv: AGENT_COMMENTS_SERVER, AGENT_COMMENTS_PROJECT, AGENT_COMMENTS_TOKEN, AGENT_COMMENTS_RETAIN.
Keeping the page tidy
Resolved comments are hidden from the panel and the page pins by default (a green pin floats away when
one gets resolved); Show resolved brings them back and Clear resolved deletes them. For an
automatic version, start the server with --retain <duration>: resolved comments older than that are
no longer served by the list/stream endpoints (so they vanish from the panel and from list/watch),
but they stay in the JSON file as history. --retain 0 hides resolved comments from the moment the
server restarts (per-session view), --retain 1d keeps a day visible. Open comments are always served.
HTTP API
Use this from any agent or tool — the CLI is just a thin client.
| Method | Path | |
| -------- | --------------------------------------- | ------------------------------------------------ |
| GET | /comments?status=open&format=md | list (markdown or JSON) |
| GET | /comments/:id | one comment |
| POST | /comments | create { comment, element, page, project? } |
| PATCH | /comments/:id | { status, resolution, resolvedBy } |
| DELETE | /comments/:id · /comments?keep=open | delete one / clear |
| GET | /events | SSE: snapshot, created, updated, deleted |
| GET | /health · / | status |
Add ?project= to scope, Authorization: Bearer when the server has a token.
How the skill works
skill/SKILL.md teaches the agent to:
GET /health; if down, startservein the background from the repo root.- Arm a persistent background listener on
watch— each new comment wakes the agent. - For each comment: locate the code (
source→component→ text/test-id → selector), implement,resolve <id> "what I changed", report in one line. - Keep listening until told to stop.
It's plain markdown — adapt it for other harnesses, or point them at the HTTP API directly.
Hosting it centrally
Same server, different flags:
AGENT_COMMENTS_TOKEN=secret agent-comments serve --host 0.0.0.0 --port 8080 --file /data/comments.json<agent-comments server="https://annotations.example.com" project="my-app" token="secret"></agent-comments>export AGENT_COMMENTS_SERVER=https://annotations.example.com AGENT_COMMENTS_PROJECT=my-app AGENT_COMMENTS_TOKEN=secretComments are scoped by project. The JSON-file store (load/save in server/server.js) is the
only thing to swap for a database. This is a dev tool — don't ship the token in production HTML.
Notes
- Node ≥ 18. No runtime dependencies. React is an optional peer for the wrapper.
.agent-comments/is the store — commit it for a shared history, or gitignore it.- Two apps at once on one machine? Give one a
--port, or use one hosted server withproject=.
License
MIT
