Agentero
Connect your own Agent, keep research context in a local Vault. Seamlessly migrate from Zotero, read, understand, link, and reuse your research context.
AI translation
Colección de herramientas web rápidas, gratuitas y fáciles de usar para mejorar tu productividad y resolver tareas comunes en segundos.
Translation pending
ProductivityTypeScript · JavaScriptGitHub @herramientaswebsencillasOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Pequeña colección de utilidades web implementadas con Next.js (app dir). Cada herramienta está en app/tools/ como una página independiente.
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Pequeña colección de utilidades web implementadas con Next.js (app dir). Cada herramienta está en app/tools/ como una página independiente.
El sitio se genera como export estático (output: 'export') y se publica en GitHub Pages, así que no hay servidor: toda la lógica corre en el navegador del usuario.
.nvmrc (con nvm: nvm use) y es la que usa el workflow de CI.corepack enable; la versión está fijada en el campo packageManager de package.json.pnpm installpnpm dev — arranca el servidor en modo desarrollo (puerto 3000)pnpm build — genera el sitio estático en out/, le inserta la CSP con los hashes de cada página (scripts/csp-hashes.mjs) y escribe out/third-party-licenses.txt (scripts/third-party-licenses.mjs)pnpm start — sirve out/ en el puerto 3000 con scripts/serve-out.mjs (next start no sirve con output: 'export')pnpm lintpnpm format aplica Prettier; pnpm format:check solo comprueba, como hace el CIpnpm exec tsc --noEmitpnpm test — Vitest sobre la lógica de lib/pnpm test:apis — consulta de verdad LanguageTool, MyMemory y Frankfurter y comprueba el formato de sus respuestaspnpm test:e2e — Playwright abre cada página del build; hace falta pnpm build antes y, la primera vez, pnpm exec playwright install chromium. Con E2E_BASE_URL=https://herramientaswebsencillas.github.io pnpm test:e2e e2e/smoke.spec.ts se prueban sobre el sitio publicado, como hace el monitoreo diariopnpm size — comprueba el presupuesto de .size-limit.mjs sobre out/; hace falta pnpm build antesNota: los scripts están definidos en
package.json.pnpm exportes un alias depnpm build, ya que el build estático ya escribeout/.
app/ — directorio principal de la aplicación (Next.js app router)app/layout.tsx — layout raíz y metadatosapp/opengraph-image.png — imagen de las vistas previas en redes sociales (con su texto alternativo en opengraph-image.alt.txt)app/privacy/ — qué herramientas envían datos a servicios externosapp/terms/ — términos de uso: servicio sin garantías, resultados orientativos y servicios de tercerosapp/tools/ — cada subcarpeta contiene una herramienta con su page.tsx y el componente del formulariocomponents/ — componentes compartidos: Navbar.tsx y ErrorMessage.tsx, el mensaje de error en línea que usan las herramientas en lugar de alert()lib/tools.ts — catálogo de herramientas y categorías que se muestra en la página de iniciolib/currencies.ts — nombres de divisas en español, usados por el conversorlib/csp.mjs — la Content Security Policy del sitio (ver "Seguridad")lib/files.ts — límites de tamaño (por archivo y en total), decodificación de Base64 y descargas de las herramientas de archivoslib/base64.ts — conversión entre Base64, bytes y texto UTF-8, compartida por los conversores y el encriptadorlib/useCopy.ts — hook para copiar al portapapeles; el botón dice si se copió o si el navegador no lo permitiólib/*.ts — lógica pura de las herramientas (fechas, finanzas, romanos, aleatorios, cifrado, binario, traducción, texto a voz), separada de los componentes y probada en lib/*.test.tslib/cipher.fixtures.ts — textos cifrados fijos del formato v2:, compartidos por las pruebas unitarias y las E2E (ver "Compatibilidad")lib/external.ts — validación de las respuestas de los servicios externos; lib/external.live.test.ts los consulta de verdad para el monitoreo diarioe2e/ — pruebas con Playwright sobre el export estático: smoke.spec.ts recorre todas las páginas y tools.spec.ts prueba los flujos de archivos, de servicios externos (con respuestas simuladas), del encriptador y de la calculadora de fechas. site.ts define contra qué sitio correnscripts/serve-out.mjs — servidor estático de out/ para pnpm start y las pruebas de humoCrea app/tools/<slug>/page.tsx con su metadata y el componente del formulario al lado. Si la herramienta usa estado o APIs del navegador, el formulario lleva "use client".
Añade una entrada al array de la categoría correspondiente en lib/tools.ts:
{
slug: "<slug>",
name: "Nombre visible",
description: "Una frase; la tarjeta reserva dos líneas.",
}
La página de inicio se genera desde ese catálogo: la ruta, la tarjeta y los colores salen de ahí, y las columnas se reequilibran solas.
Si la herramienta tiene lógica no trivial, sácala a lib/ y añade sus pruebas junto a ella. Las pruebas de humo la incluyen sola, porque recorren el catálogo.
Para una categoría nueva, añade también su acento al mapa ACCENTS del mismo archivo. Las clases se escriben completas a propósito — Tailwind rastrea literales en el código, así que un nombre de clase construido en tiempo de ejecución no generaría ningún estilo.
Casi todas las herramientas funcionan íntegramente en el navegador. Las que consultan una API pública son:
| Herramienta | Servicio | Clave | Límites del plan gratuito | Condiciones que afectan al sitio |
|---|---|---|---|---|
| Corrector de texto | LanguageTool | No | 20 peticiones/min, 75 KB/min y 20 KB por petición, por IP | Enlace visible a languagetool.org sin rel="nofollow" (ya está en la herramienta) |
| Traductor | MyMemory | No | 5 000 caracteres al día por IP sin identificarse | Conserva los textos que recibe; prohíbe revender el servicio y traducir más de un párrafo por petición |
| Conversor de divisas | Frankfurter | No | Sin cuota; solo límite contra abuso | Uso comercial libre; la API v1 está deprecada (el sitio usa v2) |
Las peticiones salen del navegador de cada visitante, no de un servidor propio, así que los límites se cuentan por visitante: el tráfico total del sitio no se suma en una sola cuota. Los límites se consultaron el 2026-09-28 y los servicios pueden cambiarlos sin aviso.
Si un servicio falla o cambia. Las respuestas pasan por los validadores de lib/external.ts antes de llegar a la interfaz. Como React muestra todo como texto y la CSP solo admite scripts propios, una respuesta maliciosa no puede ejecutar código. Lo peor que puede hacer es traer datos falsos, y los mal formados se descartan: tasas no positivas, correcciones que apuntan fuera del texto o avisos de cuota disfrazados de traducción. Si un servicio cae, solo su herramienta muestra un error; el resto del sitio sigue igual.
El workflow .github/workflows/external-apis.yml consulta cada día los tres servicios (pnpm test:apis lo hace en local) y pasa las pruebas de humo sobre el sitio publicado, que abren cada página con su JavaScript y fallan ante cualquier error, violación de CSP o fallo de SRI. Si algo falla, avisa por correo. Ante un fallo:
Mira qué prueba falló en el registro del workflow. Si fue algo pasajero, la siguiente ejecución diaria pasará sola.
La prueba de MyMemory se omite (no falla) cuando responde con la cuota agotada. Esa cuota se cuenta por IP, y los runners de GitHub comparten IPs con otros proyectos que pueden haberla gastado antes. No afecta a los visitantes, porque cada uno consulta desde su propia IP. Si se omite varios días seguidos, conviene revisarlo con pnpm test:apis en local.
Si el servicio cambió su formato, ajusta el validador de lib/external.ts y la herramienta con la respuesta nueva.
Si el servicio desaparece, hay alternativas: Frankfurter se puede alojar por cuenta propia con Docker; LanguageTool también, aunque necesita un servidor y GitHub Pages no lo ofrece; para traducción, LibreTranslate es una alternativa de código abierto.
Si el monitoreo deja de ejecutarse. GitHub desactiva los workflows programados de un repositorio público (este y el análisis semanal de CodeQL) tras 60 días sin actividad, y avisa antes por correo. Si el sitio pasa una temporada sin cambios, revisa en Actions que External APIs y CodeQL sigan activos y, si no, actívalos con Enable workflow. Integrar los PR semanales de Dependabot cuenta como actividad.
Cada petición a un servicio externo se corta a los 15 segundos (EXTERNAL_TIMEOUT_MS en lib/external.ts) y la herramienta muestra su mensaje de error, en lugar de quedarse cargando.
Al añadir una herramienta que llame a un servicio externo hay que incluir su dominio en connect-src, dentro de la CSP de lib/csp.mjs, y listarla en la página de Privacidad (app/privacy/page.tsx) y en "Servicios de terceros" de los Términos de uso (app/terms/page.tsx). Sin lo primero el navegador bloquea las peticiones y las pruebas de humo fallan con la violación de CSP.
Dos cosas que la gente guarda o comparte no pueden cambiar sin romperse:
v2:, definido en lib/cipher.ts. Cambiar el algoritmo, las iteraciones de PBKDF2 o el orden de los bytes exige un prefijo nuevo (v3:) y seguir descifrando v2:. Una prueba de lib/cipher.test.ts descifra un texto v2: fijo para detectarlo; no se regenera para que pase.Si un pull request cambia alguno, su descripción empieza con ⚠ Compatibilidad y explica qué enlaces o textos cifrados dejan de funcionar. El historial de esos avisos se consulta en los pull request cerrados.
El formato anterior del encriptador, de CryptoJS (empieza por U2FsdGVkX1), dejó de admitirse: la herramienta lo reconoce y explica que ya no se puede abrir.
La calculadora de tiempo entre fechas lee su estado de la barra de direcciones, así que un rango se puede consultar con un enlace. Son enlaces que la gente comparte y guarda, de modo que este contrato no se puede cambiar sin romperlos:
| Parámetro | Formato | Ausente |
|---|---|---|
desde | dd/mm/aaaa | Se completa con hoy |
hasta | dd/mm/aaaa | Se completa con hoy |
Un valor que no exista como fecha (31/02/2024) se ignora y cae en el valor por defecto. Sin ningún parámetro se muestra el rango del año en curso.
Que el extremo ausente sea hoy es lo que hace útil al enlace corto: ?hasta=25/12/2026 cuenta lo que falta para esa fecha y se recalcula en cada visita, en vez de quedar congelado en el día de quien lo compartió. Por eso, al escribir la URL, el extremo que coincide con hoy se omite en lugar de fijarse.
Cada push a main dispara el workflow de GitHub Actions. Instala con pnpm install --frozen-lockfile, ejecuta lint, la comprobación de formato, pnpm audit, las pruebas unitarias, pnpm build, el presupuesto de peso (pnpm size) y las pruebas E2E, y solo si todo pasa publica out/ en GitHub Pages. En los pull request se ejecutan las mismas verificaciones sin publicar. Cada publicación deja además un SBOM (inventario de dependencias en formato CycloneDX) como artefacto de la ejecución, en la pestaña Actions.
Las acciones de los workflows se fijan por SHA, con la versión en un comentario. Dependabot las actualiza igual que las dependencias.
Si una publicación rompe algo, lo más rápido es revertir el commit en una rama y abrir un pull request, porque main no admite pushes directos. Al integrarlo, el workflow publica de nuevo:
git switch -c correccion/revertir-<tema> main
git revert <commit>
git push -u origin correccion/revertir-<tema>
Si hace falta volver ya, en la pestaña Actions abre la ejecución de un commit anterior que funcionaba y usa Re-run all jobs: vuelve a construir y publicar ese commit.
Si la auditoría de dependencias bloquea la vuelta atrás. Los dos caminos pasan por pnpm audit --audit-level=high. Si el motivo del rollback es justo una dependencia con un aviso nuevo, el aviso hará fallar el build:
auditConfig.ignoreGhsas de pnpm-workspace.yaml en el mismo PR, con la fecha, el motivo ("rollback de emergencia") y la condición para quitarlo. Es el camino preferido: el check build es obligatorio para integrar en main, y la excepción queda en el historial.main sin la auditoría, en Actions → Deploy Next.js site to Pages → Run workflow marca Omitir la auditoría de dependencias. Construye y publica la punta de main con el resto de verificaciones. Sirve cuando main ya tiene el código correcto pero el aviso apareció después de integrarlo. La ejecución queda registrada con la casilla marcada. No sirve para el Re-run de una ejecución anterior, que usa el workflow de su propio commit.pnpm audit --audit-level=high corre en cada pull request, antes de cada publicación y cada día en external-apis.yml. Un aviso alto bloquea el despliegue. Para resolverlo:
vite para vitest, no se actualizan con pnpm update; por eso vite está declarada en devDependencies.overrides de pnpm-workspace.yaml, con el aviso y el camino por el que llega en un comentario. Quita el override cuando la dependencia directa ya la traiga.auditConfig.ignoreGhsas con el motivo y la condición para quitarlo.Las versiones nuevas no se adoptan en cuanto salen: pnpm no instala nada publicado hace menos de 3 días (minimumReleaseAge en pnpm-workspace.yaml) y Dependabot espera 7 días, o 14 en las versiones mayores de npm (cooldown en .github/dependabot.yml). Así un paquete comprometido tiene tiempo de detectarse y retirarse antes de llegar al sitio. Si un aviso de seguridad obliga a adoptar antes una versión, se añade a minimumReleaseAgeExclude con el aviso en un comentario.
@cantoo/pdf-lib es a propósito el fork mantenido de pdf-lib, que dejó de publicar versiones en 2022.
Para reportar una vulnerabilidad, o si el sitio se ve comprometido, consulta SECURITY.md.
GitHub Pages no permite configurar cabeceras HTTP, así que la CSP va en una etiqueta <meta>. Eso no puede aplicar frame-ancestors, X-Frame-Options ni reportar violaciones; para eso haría falta un host que sirva cabeceras.
Sin frame-ancestors, otro sitio puede mostrar estas páginas dentro de un iframe (clickjacking). Es un riesgo aceptado: el sitio no tiene sesiones ni acciones que cambien algo en un servidor, y la página que lo incrusta no puede leer lo que se escribe en él. Si alguna vez se agrega algo así, hay que migrar a un host con cabeceras (Cloudflare Pages o Netlify, con un archivo _headers) y servir frame-ancestors 'none', X-Content-Type-Options: nosniff y la CSP como cabecera.
La política se define en lib/csp.mjs. Next.js mete el payload de hidratación en <script> inline y, sin servidor, no hay nonces. Por eso:
scripts/csp-hashes.mjs inserta la CSP al principio del <head> de cada HTML de out/ y autoriza sus scripts inline por hash. No hay 'unsafe-inline' en script-src, así que un script inyectado o una URL javascript: quedan bloqueados. Las pruebas de humo lo comprueban.pnpm dev), app/layout.tsx renderiza la misma CSP con 'unsafe-inline', porque los scripts cambian con cada recarga.Toda herramienta que reciba texto para convertirlo en un archivo o enlace debe decodificarlo a un Blob (ver lib/files.ts), nunca asignarlo a un href.
scripts/csp-hashes.mjs — inserta la CSP con hashes en cada HTML de out/ después de next buildscripts/third-party-licenses.mjs — reúne en out/third-party-licenses.txt las licencias de las dependencias de producción, que el minificador quita del JavaScript; lo enlazan "Acerca de" y los Términos de usonext.config.ts, package.json, tsconfig.json — configuración del proyectopnpm-workspace.yaml — ajustes de pnpm (antigüedad mínima de las versiones, overrides de seguridad, avisos de pnpm audit ignorados con su motivo y scripts de instalación permitidos).github/workflows/nextjs.yml — verificación en cada pull request, y verificación y despliegue a GitHub Pages en cada push a main.github/workflows/codeql.yml, .github/dependabot.yml — análisis de seguridad y actualizaciones automáticas de dependencias.github/workflows/external-apis.yml — monitoreo diario del sitio publicado, de los servicios externos y de los avisos de seguridad de las dependencias.size-limit.mjs — presupuesto de peso del JavaScript publicadoCONTRIBUTING.md — cómo proponer un cambio