npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@grip-labs/wadington

v0.3.3

Published

WAD Agent y WAD Harness: el agente de manejo de dinero. Politica antes de cada pago, libro de todo intento, y un piso de capacidades que el agente no puede levantar.

Downloads

646

Readme

Wadington · WAD Agent · WAD Harness

Instalar

curl -fsSL https://harness.wad.cash/install | sh
wad

La primera vez que escribís wad, Wadington nace: se presenta, te pregunta con qué modelo pensar (DeepSeek, Claude, ChatGPT u OpenRouter), prueba tu key de verdad y la guarda en el Llavero de tu Mac. No hay archivos que editar. De ahí en más, wad lo despierta y se acuerda de lo que hablaron.

wad                  # hablar con Wadington
wad web              # la misma conversación, en el navegador
wad "¿cuánto tengo?" # una pregunta suelta
wad modelo           # cambiar el modelo con el que piensa

Todo lo suyo vive en ~/.wad. El instalador (instalar.sh) usa tu Node si es 22.19 o más nuevo; si no, baja el oficial y verifica su checksum. No pide sudo.

Dale plata a tu agente. No le des el control.

Un agente que maneja dinero, con una correa que él no puede aflojar. Se usa de dos maneras, según si ya tenés agente o no.

Si ya tenés uno, WAD Agent se instala como servidor MCP y entra en cualquier runtime que hable MCP: Claude Code, Cursor, Open WebUI, LibreChat, el DeepSeek Harness. Una integración, todos los destinos.

WAD_TOKEN=tu_token npx -p @grip-labs/wadington wad-agent

Si no tenés, está WAD Harness: el agente entero, con su propio harness, armado desde cero para que no pueda hacer nada que no sea manejar plata. Más abajo.

Las dos superficies leen el mismo catálogo y aplican la misma política. No pueden divergir: hay un test que lo verifica.


Por qué existe

WAD ya resuelve la mitad difícil: custodia, liquidación on-chain, política del lado del servidor. Pero el agente corre en la máquina del cliente, y entre el agente y WAD no hay nada.

WAD Agent es ese "nada". Tres cosas que solo se pueden hacer del lado del cliente:

La política vive en tu disco. Se lee entera antes de cada pago y no existe ninguna herramienta que la escriba. Un prompt malicioso puede convencer al modelo de cualquier cosa; se choca contra el archivo igual.

Un pago fuera de límite no llega al proveedor. La decisión se toma antes de la red. No reserva fondos, no deja registro ajeno, y no depende de que nadie esté de acuerdo.

Queda rastro de lo que NO se hizo. El historial de un proveedor lista lo que aceptó. El libro guarda también lo que se frenó y por qué. Eso es lo que contesta "por qué el agente no pagó" sin adivinar.


Lo que ve el agente

| Herramienta | Qué hace | |---|---| | wad_saldo | Disponible, reservado, lo que está entrando on-chain y cuánto queda de presupuesto | | wad_pagar | Paga, aplicando política antes de mover un peso | | wad_politica | Los límites vigentes y cuánto queda. Solo lectura | | wad_libro | Los movimientos, incluidos los frenados | | wad_estado_pago | Estado de un pago, con comprobante on-chain |


WAD Harness

Hay cientos de harness para agentes. Ninguno es de manejo de dinero.

Y no alcanza con agarrar uno y colgarle una herramienta de pagos, porque están construidos para lo contrario de lo que necesita la plata. Un harness de código maximiza lo que el agente alcanza — y está bien, porque ahí el peor caso es un archivo mal escrito. Con dinero el peor caso es que la plata se vaya, y eso no se revierte.

Por eso WAD Harness no se define por lo que agrega sino por lo que saca.

El perfil base típico monta shell, filesystem con escritura, web_fetch, subagentes, un loop autónomo de 64 rondas y telemetría a un tercero. Si a eso le colgás un pagar, no construiste un agente con dos herramientas: construiste uno al que alcanza con engañarlo una sola vez.

Lo que este agente NO puede hacer

| Apagado | Por qué | |---|---| | bash, pwsh | Con shell, cualquier límite se esquiva por abajo: el agente escribe su propio cliente y paga sin pasar por la política | | read, write, grep, glob | La política es un archivo. Si puede escribir, afloja su propia correa, y el libro deja de ser append-only | | web_fetch, web_search | El destino de un pago nunca puede salir de algo que el agente leyó por ahí. Esa es la forma exacta de la inyección de prompt que acá cuesta la plata | | subagent, fork, workflow | Un hijo heredaría la billetera sin heredar el contexto, y el tope por sesión es ficción cuando hay N sesiones | | ralph | 64 rondas autónomas con una billetera colgada es un loop que gasta 64 veces sin que nadie mire | | exit_plan_mode | Es para que un agente de código presente un plan antes de tocar archivos. Acá no hay archivos, y una herramienta visible que siempre se niega solo invita a intentarla | | skill | Instrucciones de terceros que el agente carga y obedece: una puerta de entrada, no una funcionalidad | | telemetría | Un agente que maneja plata ajena no le cuenta a un tercero lo que hace |

Además clava dos cosas que en el base salen de variables de entorno: hoy DSH_PERMISSION_MODE=danger-full-access apaga el pedido de aprobación humana. Acá el sandbox es read-only y la aprobación es ask, y no se configuran desde afuera del archivo de política.

Por qué no se puede deshacer

Apagar filas en el perfil es composición, y un patch posterior las puede volver a prender. Por eso hay una segunda capa que no depende de eso: una lista blanca aplicada con ctx.tools.guard(), el guard monotónico del harness.

La garantía está en el tipo, no en la documentación:

type ToolGuard = (execution) => string | undefined

No existe ningún valor de retorno que signifique permitir. Un guard solo puede negar (devolviendo el motivo) o no opinar. Por eso ningún plugin que cargue después, en ningún orden, puede convertir una negación en permiso: la operación no existe. Y como la lista es blanca, una herramienta que alguien agregue el mes que viene ya está negada sin que nadie toque el archivo.

Verificalo vos

Dos comandos. El primero prueba el piso sin levantar nada; el segundo le pide al harness que componga el perfil y verifica el resultado contra lo que este README promete, fila por fila.

npm test                                          # 60 pruebas; 7 del piso
node harness/verificar-perfil.mjs /ruta/al/deepseek-harness
node harness/verificar-perfil.mjs /ruta/al/deepseek-harness wad   # un perfil ya instalado
OK   tool-bash apagada
OK   tool-fs apagada
OK   tool-web apagada
...
OK   sandbox-policy.config.mode = read-only
OK   approval.config.policy = ask
OK   presets = read-only
OK   ninguna herramienta del harness quedo viva

El perfil cumple: 89 filas compuestas, 19 capacidades apagadas.

Esa última línea es la que importa a futuro: si una versión nueva del harness agrega una herramienta, el verificador falla en vez de dejarla aparecer sola en un agente que maneja plata. Alguien tiene que decidir a mano si entra. Encontró dos el primer día que corrió.

Usarlo

node harness/instalar.mjs /ruta/al/deepseek-harness    # perfiles + comando wad-harness
echo "<token>" > ~/.wad-token && chmod 600 ~/.wad-token

wad-harness                 # la conversacion en la terminal
wad-harness web             # la misma, en el navegador
wad-harness tarea "..."     # una tarea y sale

wad es una conversación en la terminal que se retoma: el id queda en ~/.wad/conversacion y la próxima vez sigue desde ahí. /nueva empieza de cero, /razonamiento muestra lo que piensa el modelo, Ctrl-C corta un turno.

Un pago arriba del umbral blando pregunta [s/N] en la terminal. Lo que tipeaste mientras el agente trabajaba queda en cola como próximo mensaje, pero nunca contesta una aprobación: la pregunta descarta la cola y espera una línea escrita después de verla. Algo pegado de antemano no puede aprobar un pago.

wad-tarea corre una sola tarea y sale, para scripts y crons. No tiene a quién preguntarle, así que un pago que pide aprobación no sale.

wad-web es la misma conversación en el navegador: la terminal y la web retoman la misma, y si una ya la tiene abierta la otra no arranca (en vez de empezar otra y pisar la guardada).

wad-harness web
# Abrí: http://127.0.0.1:4747/?t=...      (WAD_WEB_PUERTO cambia el puerto)

No usa la interfaz web del harness: esa es un IDE de código y con el perfil de dinero se cuelga. Es un servidor chico con una sola página, que cuida lo que importa cuando del otro lado hay una billetera:

  • escucha solo en 127.0.0.1 y rechaza cualquier otro Host (DNS rebinding);
  • se entra con el link que imprime la terminal; el token se cambia por una cookie HttpOnly; SameSite=Strict, y toda la API la exige;
  • los POST exigen JSON y una cabecera propia, que un formulario ajeno no manda;
  • CSP default-src 'self', sin nada inline, y el texto del modelo se arma con nodos del DOM: una respuesta con HTML se ve como texto;
  • un pago arriba del umbral aparece como tarjeta con Aprobar / Rechazar, y solo se puede contestar con el id que se generó al mostrarla. No existe forma de aprobarlo por adelantado.

Configuración

WAD_TOKEN=...                  # obligatorio: pareá un agente en la consola de WAD
WAD_POLITICA=~/.wad/politica.yaml
WAD_LIBRO=~/.wad/libro.jsonl
WAD_DEPOSIT_ADDRESS=0x...      # opcional, habilita ver los depósitos entrando

Copiá politica.ejemplo.yaml a ~/.wad/politica.yaml. Sin archivo, los límites por defecto son deliberadamente bajos: es preferible que el primer pago se frene a que se escape.

Los cuatro límites, y por qué no se comportan igual

| Límite | Al pasarse | ¿Una persona puede aprobarlo igual? | |---|---|---| | porPago | rechaza | no | | porDia | rechaza | no | | total | rechaza | no | | aprobacion.arribaDe | escala a una persona | sí |

Los tres primeros son duros: el pago no sale y nadie se entera. El cuarto es el único blando, y es el único que produce una pregunta.

total es el que importa y el que casi nunca está. No se renueva nunca: el diario vuelve mañana, este no vuelve. Sin él, un agente puede gastar de a poco para siempre —cada pago dentro del tope individual, cada día dentro del diario— y no pasarse jamás de nada.

Por eso, cuando un pago choca contra varios topes a la vez, se reporta el total: decirle a alguien "te pasaste del diario" cuando en realidad agotó el presupuesto de por vida lo manda a esperar hasta mañana para chocarse contra la misma pared.

Y por eso conviene no llamarle cap al umbral de aprobación: suena a límite duro, y es el único que no lo es.


Tres cosas medidas que el agente te dice y WAD no

Lo que está entrando. wad_balance devuelve cero mientras un depósito confirma — entre 14 y 17 minutos. En esa ventana un agente no distingue "no me mandaron nada" de "me mandaron y está entrando". Con tu deposit address configurada, preguntamos el saldo real a Base y lo mostramos aparte.

Cuánto se lleva la comisión. Cada liquidación arrastra ~0,004 USDC fijos de repago de gas, que no aparecen en ninguna respuesta. Al ser fija pesa 4% en un pago de 0,10 y 1,6% en uno de 0,25. El agente avisa antes, para que junte pagos en vez de hacer muchos chicos.

Lo que cuesta pedir permiso. Un pago auto-aprobado liquida en ~16 segundos; uno que pasa por aprobación humana tarda ~22 minutos. El umbral de aprobación no es solo una decisión de riesgo: también es de velocidad.


Desarrollo

npm install
npm test          # 41 pruebas, sin red, sin gastar un centavo
npm run check     # TypeScript en modo strict

La prueba contra el WAD real es aparte porque toca plata:

WAD_TOKEN=... node --import tsx/esm test/vivo.ts           # no paga nada
WAD_TOKEN=... node --import tsx/esm test/vivo.ts --pagar   # paga 0,01 USDC

Decisiones de diseño

La plata es entera, siempre. Nada de coma flotante. Todo entra a minor units en el borde y no vuelve a salir. Un monto con más decimales de los que la moneda puede representar se rechaza en vez de redondearse.

El orden de las reglas importa. Primero lo que nunca se permite, después los topes duros, y recién al final la aprobación humana — así no se molesta a una persona pidiéndole que apruebe algo que igual iba a bloquearse.

Un reintento no gasta el tope dos veces. Si mandás la misma clave de idempotencia, se excluye del acumulado. Sin eso, reintentar un timeout consume presupuesto que nunca se gastó.

Una aprobación denegada es un fracaso, no un estado intermedio. Un pago que nadie aprobó es un pago que no se hizo.

MIT.