Pinpoint

Haz clic en un elemento de tu aplicación web en ejecución o en el Simulador de iOS y di qué debería cambiar; tu agente de codificación (Claude Code, Cursor, Codex) recibe tu comentario con el selector, la ruta DOM, los estilos, la cadena de componentes, la pista del archivo fuente y una captura de pantalla recortada. Solo local, MIT.

Documentación

Pinpoint

tests licence: MIT stars npm Glama score

Haz clic en un elemento de tu sitio de desarrollo local, escribe qué debería cambiar, y tu agente de codificación lo recibe — con el selector, la ruta DOM, los estilos calculados, la cadena de componentes React/Vue, la pista del archivo fuente y una captura recortada. Sin archivos de captura acumulándose en tu carpeta de Descargas, sin describir "el tercer botón de la izquierda". ¿Estás creando una app nativa? Lo mismo funciona en el Simulador de iOS.

No es solo para estilos. Di qué debería hacer la cosa — "deshabilitar esto hasta que el formulario sea válido", "esto debería guardar el borrador antes de cerrar", "mostrar aquí el error que devolvió la API" — y al agente se le indica que trate el elemento como el punto de partida, y luego que lo siga hacia los manejadores, el estado, las llamadas a la API y el backend detrás de él. Más abajo.

Browser (extension) ──POST──▶ pinpoint bridge (127.0.0.1:7331) ──MCP / hooks──▶ Claude Code, Cursor, Codex…
        pins ◀──live events───┘   ~/.pinpoint/annotations.json   └── <repo>/.pinpoint/pending.md (optional)
iOS Simulator ─▶ 127.0.0.1:7331/ios ─┘  (screenshot + accessibility tree instead of the DOM)

Pinpoint on a local dev page: picking an element, writing what should change, and the agent picking it up

Haz clic en un elemento, di qué debería cambiar, tu agente lo recibe. (video a velocidad completa)

No es un agente que maneja el navegador

La distinción importa, porque ambos se archivan juntos y son opuestos:

  • Playwright MCP, agente-navegador, computer-use ponen al agente en el asiento del conductor — navega, hace clic y verifica. Bueno para pruebas y para navegar en tu nombre.
  • Pinpoint te mantiene a ti en el control. Tú haces clic, tú dices qué debería cambiar, y el agente recibe contexto estructurado para editar código: un selector, los estilos, la cadena de componentes, una pista del archivo fuente, un recorte del elemento. Nunca toca la página en sí.
  • Una captura de pantalla pegada no lleva nada de eso. El agente recibe píxeles y tiene que adivinar qué control querías decir, cómo se llama y dónde vive en el árbol.

Así que se compone con la automatización del navegador en lugar de competir: señala la cosa, deja que el agente la cambie, deja que tus pruebas manejen el navegador.

Inicio rápido

Necesitas Node 18+ y un navegador Chromium (Chrome, Edge, Brave, Arc, Opera, Vivaldi).

git clone https://github.com/gowtham012/pinpoint
node pinpoint/bridge/cli.js setup

Eso es la instalación. setup instala sus propias dependencias primero, luego pregunta — cada pregunta tiene un valor predeterminado, así que pulsar Enter todo el camino es una configuración funcional:

  • qué proyecto de UI quieres anotar — el repositorio cuyos archivos editará tu agente
  • si es una app web o una app nativa de iOS (o ambas) — web obtiene la extensión del navegador; iOS obtiene el selector del Simulador, y la configuración verifica Xcode, Maestro y Java y dice cómo obtener lo que falte. No instala ninguno por ti.
  • qué agentes conectar — detecta Claude Code, Cursor y Codex y escribe la entrada MCP para cada uno: claude mcp add para Claude Code, <project>/.cursor/mcp.json para Cursor, ~/.codex/config.toml para Codex. Las entradas existentes se fusionan, nunca se reemplazan, y el archivo TOML se respalda antes de tocarse.
  • si instalar los hooks de Claude Code, que llevan las notas pendientes con tu próximo mensaje
  • qué navegador cargar la extensión, listando los que realmente tienes (solo web)

Luego registra el lanzador detrás del botón Iniciar bridge del popup y arranca el bridge. No interactivo, para una máquina con script: node pinpoint/bridge/cli.js setup ~/code/my-app --yes (añade --for ios o --for both; el valor predeterminado es web).

¿Construyendo solo una app nativa de iOS? Puedes omitir el clon: el selector de iOS no necesita extensión.

npx -y pinpoint-bridge                                      # the bridge, with the picker at /ios
claude mcp add pinpoint -s user -- npx -y pinpoint-bridge mcp   # once, for Claude Code

Pinpoint también está listado en el Registro MCP oficial (io.github.gowtham012/pinpoint), en cursor.directory (Añadir a Cursor con un clic) y en Glama. Todos ellos instalan solo el servidor MCP — para páginas web aún necesitas la extensión y el bridge del clon anterior.

El único paso que no puede ser un comando. Chrome no permite que una terminal cargue una extensión sin empaquetar en tu propio perfil — solo la Web Store o una política empresarial pueden hacerlo. Así que la configuración abre la página de extensiones de tu navegador y pone la carpeta extension/ en tu portapapeles: Modo desarrollador activado → Cargar descomprimida → pegar. La terminal confirma ✓ Pinpoint está activo en Chrome por sí sola, porque el bridge puede ver que la extensión se conecta.

Reinicia Claude Code una vez después — lee los servidores MCP y los hooks cuando comienza una sesión.

Luego pruébalo. Abre tu sitio de desarrollo (o la página de demostración), presiona ⌥⇧A / Alt+Shift+A, haz clic en cualquier elemento, escribe qué debería cambiar, ⌘↩ / Ctrl+Enter. Escribe cualquier cosa en Claude Code y tu nota llega con ello. Si la barra nunca aparece, consulta Solución de problemas.

Haciéndolo a mano en su lugar, y las notas de Windows / file://

setup escribe configuración en tu repositorio y en los archivos de tu agente. Si prefieres hacerlo tú mismo, son cuatro pasos — y el orden importa: $PWD está integrado en la entrada MCP, así que el paso 2 debe ejecutarse desde pinpoint/bridge, antes de que el bridge tome el control de la terminal.

# 1. get it
git clone https://github.com/gowtham012/pinpoint
cd pinpoint/bridge && npm install

# 2. wire up Claude Code (once, from this folder)
claude mcp add pinpoint -s user -- node "$PWD/cli.js" mcp
node cli.js install-hooks ~/code/my-app                  # notes arrive without being asked
node cli.js install-native-host --project ~/code/my-app   # optional: the popup's "Start bridge" button

# 3. load extension/ unpacked at chrome://extensions (Developer mode on)
# 4. start the bridge, and leave it running
node cli.js --project ~/code/my-app

Reinicia Claude Code una vez después del paso 2. --project es opcional: mantiene <repo>/.pinpoint/pending.md actualizado para agentes que leen un archivo en lugar de MCP.

¿Anotando una página que abriste como URL file://? Chrome lo mantiene desactivado por defecto. En chrome://extensions, abre los Detalles de Pinpoint y activa "Permitir acceso a URLs de archivo", luego recarga la página.

En Windows, $PWD funciona en PowerShell y Git Bash pero no en cmd.exe — ejecuta node cli.js --help y copia la línea claude mcp add … ya preparada que imprime, que ya lleva la ruta completa. Los atajos son Alt+Shift+A y Ctrl+Enter, y la interfaz los etiqueta así. install-native-host es solo para macOS y Linux; en Windows, inicia el bridge en una terminal.

Qué navegadores

Chromium — Chrome, Edge, Brave, Arc, Opera, Vivaldi. Carga descomprimida, como arriba; la suite de pruebas maneja Chromium sin interfaz, así que ese es el que se verifica continuamente. Safari — se compila en lugar de cargarse: bash tools/make-safari.sh (necesita Xcode). Firefox — aún no.

Qué difiere en Safari y qué bloquea a Firefox

Safari no acepta extensiones sin empaquetar, así que tools/make-safari.sh lo envuelve en una pequeña app de macOS — convierte, compila e imprime los cuatro ajustes de Safari que debes cambiar (el importante es Desarrollar ▸ Permitir extensiones sin firmar, que se restablece cada vez que Safari se cierra). Una capacidad falta allí: los scripts de contenido "world": "MAIN" no son compatibles, así que inspector.js no puede leer los fibers de React ni las instancias de Vue, lo que te cuesta la cadena de componentes y la pista del archivo fuente. Todo lo demás — selección, regiones, comentarios, pines, capturas, el bridge, MCP — no cambia.

Firefox está más cerca de lo que estaba (cada script prefiere browser donde existe), pero dos bloqueadores de manifest permanecen: background: { service_worker } donde Firefox MV3 quiere background: { scripts }, y falta un browser_specific_settings.gecko.id. Ambos son solucionables, pero mantenerlos honestos necesita un trabajo de Firefox en CI en lugar de una afirmación en un README. Abre un issue si lo quieres.

Apps nativas de iOS (Simulador)

Una app nativa no tiene DOM, así que esta ruta lee el árbol de accesibilidad en su lugar. Funciona para apps SwiftUI, UIKit, React Native y Flutter, y no necesita nada añadido a tu app.

Necesitas Xcode con un Simulador iniciado y Maestro (lee el árbol, y necesita Java — un openjdk de Homebrew se encuentra incluso cuando no está en tu PATH). El bridge mantiene un proceso maestro mcp ejecutándose para ello, así que solo la primera carga espera (~10s, mientras Maestro inicia su controlador en el dispositivo); cada actualización posterior tarda alrededor de un segundo. Cada Maestro en tu Mac comparte ese único controlador, así que si otro (el servidor MCP de Maestro de un agente, una ejecución de pruebas) lo reinicia, la siguiente lectura del bridge falla, y el bridge entonces inicia un Maestro nuevo e intenta una vez más. Si la primera carga tarda minutos, cierra las sesiones de Claude Code que no estés usando y que tengan el servidor MCP de Maestro.

La configuración pregunta si tu app es web o iOS, y para iOS abre esta página por ti. De lo contrario, con el bridge ejecutándose — node cli.js desde el clon, o npx -y pinpoint-bridge sin clon en absoluto — abre http://127.0.0.1:7331/ios. Muestra la pantalla del Simulador: pasa el cursor para ver cada elemento, haz clic en uno, escribe qué debería cambiar, ⌘↩. La nota llega a tu agente como cualquier otra, con el accessibilityIdentifier del elemento (tu testID), su etiqueta, su ruta en el árbol, su marco y un recorte. Presiona R (o Actualizar) después de que la app cambie; las notas resueltas desaparecen.

Lo que no puede darte: una pista del archivo fuente o una cadena de componentes (el árbol no tiene ninguna — dale a los elementos un identificador y el agente lo busca con grep), estilos, o recheck_annotation, que espera un navegador y agota el tiempo aquí. Android aún no está conectado.

Dónde se ejecuta

Pinpoint es una herramienta para la app que estás construyendo, así que solo se carga en páginas de desarrollo local: localhost, 127.0.0.1, .local / .test / .localhost hosts, y páginas file:// una vez que has concedido acceso a archivos. En cualquier otro sitio simplemente no está — sin barra, sin superposición, nada inyectado.

En cualquier otro lugar — una URL de staging, o una dirección LAN como 192.168.1.5:3000 cuando pruebas desde tu teléfono — el popup de la barra de herramientas lo activa para esa pestaña.

Cómo usarlo

Mientras el bridge se ejecuta, una pequeña barra se sitúa en la esquina superior derecha de cada página. Haz clic en ella (o presiona ⌥⇧A / Alt+Shift+A) para comenzar a marcar. Haz clic en un elemento, escribe qué debería cambiar, presiona ⌘↩ / Ctrl+Enter, y estás inmediatamente listo para el siguiente. Esc cuando termines, o haz clic en Detener en la barra. La × oculta la barra para ese sitio; el popup la trae de vuelta, y puede moverla a cualquier esquina.

The bar, idleThe bar resting as a dotThe bar while picking, with a Stop control
Te dice el atajo, y quién está aquí — tú, y tu agente.Después de unos segundos se reduce a un punto, fuera de tu camino. Pasa el cursor para traerla de vuelta.Seleccionando. La barra es de clic transparente para que nunca pueda bloquear el elemento al que apuntas; Detener es la excepción.

The comment popover on a form field, showing the element it picked

El popover nombra exactamente lo que seleccionaste, para que puedas distinguir dos botones casi idénticos antes de escribir.

A numbered pin on the annotated field

Un pin numerado se adhiere al elemento — numerado por página, así que cada página cuenta desde 1. Los pines viven en el bridge, no en la página, así que sobreviven a las recargas, aparecen en cada pestaña que muestra esa página, y desaparecen en el momento en que tu agente marca el cambio como hecho. En apps que reconstruyen su DOM, cada pin reencuentra su propio elemento por identidad, y se oculta en lugar de posarse sobre un elemento diferente que casualmente coincide con el selector antiguo. El contador de la barra abre la lista de todo lo marcado en esta página; haz clic en una fila para saltar a ello.

Two notes on a panel that rebuilds itself: one re-finds its element, the other says it is not on this view

Las mismas dos notas, dos veces. Cambia de pestaña y el panel se reconstruye desde cero — la nota 1 reencuentra su propio elemento entre nodos que no existían hace un momento, mientras que la nota 2 admite que no está en esta vista. Un agente que pregunte en ese momento recibe lo mismo.

Cuando la página se mueve debajo de un pin. Un pin que ya no puede encontrar su elemento no solo se oculta — se le informa al bridge, así que lo próximo que lea tu agente dice que el elemento puede estar obsoleto en lugar de entregarle un selector que ha caducado. Y recheck_annotation le pide a tu navegador que mire de nuevo ahora mismo: reencuentra el elemento, dice si ha desaparecido, se ha movido fuera de su selector, o simplemente ha cambiado, y devuelve un recorte nuevo junto al tomado cuando lo marcaste. Si no hay ninguna pestaña abierta en esa página, dice que no pudo mirar — nunca que nada cambió.

Marcando un área. Algunos cambios son sobre un grupo — "haz que estas tarjetas sean de dos columnas en móvil". Arrastra en lugar de hacer clic y obtienes una caja, anclada al elemento más profundo que la contiene por completo. Tu agente recibe un contenedor real para cambiar, más la lista de lo que contenía la caja y una captura recortada a ella. Lectura de la respuesta. Una nota terminada no desaparece. Permanece en el panel con la respuesta de tu agente debajo, para que puedas leer qué cambió sin volver a la terminal.

The notes panel: a pending note, and a finished one with the agent's reply beneath it

Esa respuesta es el note que tu agente pasa a resolve_annotation, lo cual es obligatorio — la herramienta le indica que leíste esto en tu navegador, y que "hecho" no es una respuesta. Mientras funciona, la barra indica lo que está haciendo: la nota que está revisando recibe un anillo, y una nota que completa desaparece frente a ti.

Luego simplemente habla con Claude Code con normalidad. Con los hooks instalados no tienes que mencionar Pinpoint en absoluto; sin ellos, di "aplica mis anotaciones de pinpoint". Si el puente no está en ejecución, Enviar copia un prompt listo para pegar en tu portapapeles, para que nada se pierda.

Iniciar y reiniciar el puente desde el navegador

Un navegador no puede iniciar un proceso, por lo que install-native-host registra un pequeño lanzador con Chrome (y Brave, Edge, Arc, Chromium, Vivaldi, Opera). Después de eso, el botón Iniciar puente del popup funciona, y mientras el puente está en ejecución, ese botón y el ↻ en la barra de la página lo reinician — lo que quieres después de obtener una nueva compilación, sin salir de la página.

El lanzador puede hacer exactamente una cosa: ejecutar el cli.js de este repositorio en un número de puerto, leído desde la configuración del popup y nunca desde la página. El reinicio es HTTP simple hacia el propio puente, por lo que no necesita lanzador y también funciona en Safari. Solo macOS y Linux por ahora; en Windows, inicia el puente en una terminal.

Cuando más de un agente está conectado

Los agentes se presentan en el handshake de MCP, por lo que la barra nombra al que está trabajando (claude-code, cursor-vscode, codex) en lugar de decir "tu agente", y cada respuesta en el panel se atribuye a quien la escribió. wait_for_annotation entrega cada nueva nota a exactamente un agente en espera, por lo que dos agentes observando a la vez comparten la cola en lugar de hacer ambos la misma nota — y si uno resuelve algo que otro ya terminó, se le informa.

Cómo se entera tu agente

Tres mecanismos, del más fuerte al más débil. Se acumulan — usar los tres está bien.

  • Hooks (automáticos). node cli.js install-hooks <repo> añade un hook de SessionStart y uno de UserPromptSubmit a <repo>/.claude/settings.json, ambos ejecutando cli.js print --hook. No imprime nada cuando no hay nada pendiente, por lo que una sesión normal no se ve afectada. Marca algo en el navegador, escribe cualquier cosa en Claude Code, y vendrá. Tus propias configuraciones en ese archivo se conservan, y volver a ejecutar actualiza en lugar de duplicar. Reinicia Claude Code una vez después.
  • MCP (bajo petición). Las instrucciones del servidor pinpoint le dicen al agente que revise las anotaciones cada vez que hables de un cambio de UI o de funcionalidad, por lo que "haz ese botón más grande" suele activar una búsqueda por sí solo.
  • Un bucle de vigilancia (sin intervención). Di "vigila pinpoint y aplica cada cambio a medida que llegue". El agente se estaciona en wait_for_annotation, que regresa en el instante en que pulsas Enviar — captura de pantalla incluida.

Apariencia o comportamiento

El comentario es la instrucción, en tus palabras, y puede ser sobre cualquier cosa de la que el elemento forme parte. Ambas son buenas notas:

  • "Haz esto a ancho completo en móvil y quita la sombra" — un cambio de estilo, hecho donde está el elemento.
  • "Al hacer clic en esto debería guardar el borrador primero, y mostrar un toast si el guardado falla" — un cambio de comportamiento. El botón es solo la vía de entrada: se le dice al agente que lo siga desde su componente hasta el manejador, el estado, la llamada a la API y, si ahí es donde pertenece la corrección, la ruta del backend.

Cada canal — MCP, los hooks, pending.md, los botones de copiar al portapapeles — le dice al agente que una nota puede ser sobre cualquiera de los dos, por lo que una solicitud de comportamiento no se reestiliza y se da por terminada. Cuanto más digas sobre el resultado que quieres ("debería", "en lugar de", "cuando … entonces …"), menos tendrá que adivinar el agente.

Conectando otros agentes

La entrada más simple ejecuta el paquete publicado, por lo que no hay una ruta que acertar: npx -y pinpoint-bridge mcp. Habla con cualquier puente que esté en ejecución, clonado o no. Para fijar el agente a tu clon en su lugar, usa la ruta absoluta a cli.js (desde pinpoint/bridge, ejecuta pwd y añade /cli.js, o copia la línea que imprime node cli.js --help). Reinicia el editor después; los servidores MCP se leen al inicio.

Cursor — un clic desde cursor.directory, o .cursor/mcp.json (o ~/.cursor/mcp.json para cada proyecto):

{ "mcpServers": { "pinpoint": { "command": "npx", "args": ["-y", "pinpoint-bridge", "mcp"] } } }

Codex CLI — ~/.codex/config.toml:

[mcp_servers.pinpoint]
command = "npx"
args = ["-y", "pinpoint-bridge", "mcp"]

Cualquier cliente MCP sobre HTTP — http://127.0.0.1:7331/mcp (Streamable HTTP, sin estado). Windsurf, Cline, Continue, Zed y Gemini CLI aceptan una URL.

Sin MCP en absoluto — ejecuta el puente con --project <repo> y mantiene <repo>/.pinpoint/pending.md actualizado (con su propio .gitignore). Dile a cualquier agente "lee .pinpoint/pending.md y aplícalo"; termina cada uno con node cli.js resolve <id>. O usa Copiar prompt en el popover para pegar en cualquier chat.

Comandos

Ejecuta estos desde pinpoint/bridge.

node cli.js [start]            start the bridge (default command)
node cli.js mcp                run as a stdio MCP server
node cli.js status             is it running? how many pending?
node cli.js print              pending annotations as markdown  (--consume also resolves them)
node cli.js resolve <id...> --note "what you changed"
                               mark done — the pin disappears and your note is shown as the reply
node cli.js install-hooks [dir]  wire up Claude Code
node cli.js install-native-host   let the popup's "Start bridge" button start the bridge
                               (--uninstall removes it; --id <id> allows a second checkout)
node cli.js clear              delete everything
node cli.js --help

http://127.0.0.1:7331/ios      the iOS Simulator picker, served by the running bridge

--port <n>       default 7331, or $PINPOINT_PORT (set the same number in the popup)
--project <dir>  mirror pending annotations into <dir>/.pinpoint/
--print          echo each new annotation to stdout as it arrives
$PINPOINT_HOME   where annotations are stored (default ~/.pinpoint)

Herramientas MCP

herramientapropósito
get_pending_annotationstodo lo pendiente como lista de tareas en markdown, cada una con su captura de pantalla
list_annotationsuna línea por anotación
get_annotationdetalle completo + captura de pantalla para un id o número de pin
recheck_annotationreencontrar el elemento en la página en vivo e informar qué cambió, con un recorte nuevo junto al original
resolve_annotationmarcar como hecho → el pin desaparece en el navegador en menos de un segundo
wait_for_annotationbloquear hasta que el desarrollador envíe la siguiente
clear_annotationsborrar todo

Recurso: pinpoint://pending (markdown).

Qué contiene una anotación

comment          "make this full-width on mobile"          ← the only instruction
page             url, title, viewport, scroll
element          tag, id, classes, a CSS selector built from stable attributes where they exist
                 (`button[data-action="next"]` rather than `:nth-of-type(2)`; shadow DOM via
                 "host >>> inner"), DOM path, rendered text, trimmed outerHTML, role/aria/data-*
                 attributes, bounding box, ~25 computed style properties, and a fingerprint
                 (tag + text + key attributes) used to verify a pin is still on the right element
source           framework (react/vue/svelte/angular/astro), component chain,
                 file:line where the dev build exposes it
screenshot       PNG of just the element (+8px), long edge ≤1200px

Desde el Simulador de iOS, element lleva el identificador de accesibilidad, la etiqueta, el texto y el valor en su lugar, la ruta a través del árbol de accesibilidad, y el marco en puntos; source es ios-native sin archivo, y page.url es ios-simulator://<device name>.

Para file:line exacto en React 19 o Next, añade un plugin de inspector solo para desarrollo (vite-plugin-react-inspector, @react-dev-inspector) — Pinpoint lee los atributos data-source que emiten, así como los propios _debugSource/_debugStack de React y __file de Vue.

Solución de problemas

No aparece ninguna barra en la página

La barra solo se muestra mientras el puente está en ejecución — así es como te dice que está activo. Comprueba node cli.js status desde pinpoint/bridge. Si el puente está activo pero la barra sigue sin aparecer, probablemente la página no es una en la que Pinpoint se inyecte automáticamente (ver Dónde se ejecuta) — abre el popup de la barra de herramientas y actívalo para esa pestaña.

Nada en absoluto en una página file://

Chrome mantiene el acceso a archivos desactivado por extensión. En chrome://extensions → Pinpoint → Detalles → "Permitir acceso a URL de archivo", luego recarga.

El punto de la barra de herramientas nunca se pone verde

O el puente no está en ejecución, o está en un puerto diferente al de la extensión: el campo Puerto del popup y el --port del puente deben coincidir. Si node cli.js status dice "el puerto responde, pero NO es el puente de pinpoint", algo más posee ese puerto — inicia el puente con --port 7332 y establece 7332 en el popup también.

el puerto 7331 ya está en uso

Normalmente el puente ya está en ejecución desde otra terminal, en cuyo caso ya está hecho. De lo contrario, elige un puerto libre como arriba. No ejecutes dos puentes a la vez: comparten un único archivo de almacenamiento y el último escritor gana.

Una anotación no tiene captura de pantalla

La imagen se toma justo después de que tu comentario se almacena, por lo que el comentario nunca se pierde. Si la página navegó o la pestaña se cerró en ese momento, la anotación registra el motivo en lugar de adjuntar una imagen de la página equivocada. El comentario, el selector y los estilos siguen ahí.

Claude Code no menciona mis notas

Los hooks se leen cuando una sesión comienza — reiníciala una vez después de install-hooks. Comprueba que <your repo>/.claude/settings.json tiene dos entradas que contienen print --hook, y que la ruta en ellas sigue existiendo (mover tu clon de Pinpoint lo rompe — vuelve a ejecutar install-hooks). Siempre puedes simplemente decir "aplica mis anotaciones de pinpoint".

"Iniciar puente" dice que se necesita una configuración única, o no puede encontrar Node

Ejecuta node cli.js install-native-host una vez, luego presiónalo de nuevo. Si ya lo has ejecutado, ejecútalo de nuevo — mover el repositorio, o recargar una compilación sin el manifiesto key, cambia el id de la extensión, y Chrome reporta un id rechazado de la misma manera que un lanzador faltante. Sal y vuelve a abrir el navegador después. El lanzador también incorpora una ruta absoluta a node, porque un proceso iniciado por el navegador no obtiene tu PATH del shell; si node se movió (una nueva versión de nvm, una actualización de Homebrew), vuelve a ejecutarlo.

Quieres un estado limpio

node cli.js clear vacía el almacenamiento; ~/.pinpoint/annotations.json es el único estado fuera de tu repositorio.

Una página para probarlo

demo/index.html es un sitio de demostración autónomo — sin compilación, sin red — con las formas que hacen que Pinpoint valga la pena: una cuadrícula de tarjetas y niveles de precios para arrastres de región, botones hermanos casi idénticos, un panel de pestañas que se reconstruye a sí mismo, una tabla densa y un formulario.

cd demo && python3 -m http.server 8080     # then open http://localhost:8080

Pruebas

cd test && npm install && npx playwright install chromium && npm test

102 pruebas. bridge.test.mjs cubre el daemon, CLI, hooks, la ruta de árbol a anotación del selector de iOS y cada herramienta MCP tanto sobre stdio como Streamable HTTP; e2e.test.mjs carga la extensión desempaquetada en Chromium sin cabeza y maneja páginas reales — React, Vue, shadow DOM, un iframe, una página con CSP estricto, una página de estrés de 3,600 nodos, DPR 2, sincronización entre pestañas y un formulario que reconstruye todo su DOM. Consulta CONTRIBUTING.md para saber para qué sirve cada suite.

Seguridad y almacenamiento

El puente se vincula a 127.0.0.1, rechaza cualquier solicitud que lleve un Origin de una página web (la única excepción es la suya propia, para la página /ios que sirve, que también se niega a ser enmarcada), y se identifica con un marcador service; todo lo extraído de la página se etiqueta como no confiable donde llega a tu agente, y solo tu comentario escrito se presenta como una instrucción. Las capturas de pantalla viven codificadas en base64 dentro de ~/.pinpoint/annotations.json en lugar de como archivos sueltos. SECURITY.md tiene las notas completas sobre los límites de confianza, incluido por qué se necesita el permiso <all_urls>, y PRIVACY.md dice exactamente qué se recopila, dónde se almacena y el único lugar donde sale — el agente de codificación al que lo conectas.

Hoja de ruta

  • Emulador de Android: maestro hierarchy ya lee el árbol allí; necesita adb para la captura de pantalla.
  • Pistas de fuente nativas: las ubicaciones de creación de widgets de _debugSource de React Native y de Flutter, a través de un paquete opcional solo para desarrollo en la aplicación.
  • Mapeo de fuente CSS a través de chrome.debugger (qué conjunto de reglas estableció este color, y dónde).
  • Anotaciones a nivel de página — una nota sobre toda la página en lugar de un elemento o un área.
  • Firefox: el manifiesto necesita un fondo scripts y un gecko.id.
  • Respuestas del agente en el propio pin, no solo en el panel de notas.

Contribuir

Las issues y las pull requests son bienvenidas — consulta CONTRIBUTING.md. No hay paso de compilación: clónalo, npm install en bridge/, carga extension/ desempaquetado, y estás desarrollando. Cada cambio de comportamiento debería venir con una prueba.

Licencia

MIT — consulta LICENSE. Las notas de versión se encuentran en CHANGELOG.md.