Mascota virtual que prospera cuando te enfocas. Tamagotchi meets productivity.
  • JavaScript 90%
  • TypeScript 6.9%
  • CSS 1%
  • Python 0.8%
  • Shell 0.8%
  • Other 0.5%
Find a file
monyi 8ad69134d1
All checks were successful
ci / validate (push) Successful in 1m45s
fix(ui): icono de tema invisible y pistas de control como losas grises
Dos regresiones visuales que destapó la subida de contraste de los tokens v2:

- Los <button> no heredan color: el UA pone ButtonText (negro), así que el SVG
  del botón de tema (stroke=currentColor) se veía casi negro sobre el panel
  oscuro. Se declara color en .theme-btn/#theme-btn y hover a --text.
- Las pistas de sliders y barras de progreso usaban var(--border) como relleno
  del box, que tras pasar a 3:1 se convirtió en una losa gris de 32px de alto.
  Ahora la pista se dibuja fina (4px) con --border-subtle y el contraste lo
  aporta el thumb en --accent; el área táctil sigue siendo 32px.
2026-10-25 14:17:52 +01:00
.gitea/workflows feat(sidepanel): migra la UI de popup a panel lateral 2026-10-21 23:50:05 +02:00
.meta feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
.specify feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
docs docs: add compact popup layout pattern reference 2026-07-06 16:23:56 +02:00
presets/d0a1-strict feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
protocols feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
public fix(fonts): autohospedar Inter y quitar Google Fonts 2026-10-22 09:33:40 +02:00
scripts feat(a11y): tokens GS v2 (WCAG 2.1 AA) y gate de contraste 2026-10-25 10:35:22 +01:00
specs feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
src fix(ui): icono de tema invisible y pistas de control como losas grises 2026-10-25 14:17:52 +01:00
tests feat(v0.3.1): iconos reales, i18n completo EN/ES y ayuda "Cómo funciona" 2026-10-22 00:28:43 +02:00
.editorconfig feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
.gitignore chore(repo): .gitignore completo (.pnpm-store, dist, .wxt, .env) 2026-10-25 06:16:27 +01:00
AGENTS.md feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
biome.json feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
commitlint.config.cjs feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
CONSTITUTION.md feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
DESIGN.md Diseño: contrato DESIGN.md, pie canónico y cero ko-fi 2026-10-16 00:25:46 +02:00
grill-decisions.md feat: bootstrap from sdd-init-tpl @ 308738a 2026-07-09 19:51:09 +02:00
lefthook.yml feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
LICENSE feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
package.json feat(a11y): tokens GS v2 (WCAG 2.1 AA) y gate de contraste 2026-10-25 10:35:22 +01:00
pnpm-lock.yaml feat: FocusPet AI v0.2.0 — on-device sentiment analysis + contextual pet messages 2026-07-12 14:14:38 +02:00
pnpm-workspace.yaml feat: bootstrap saas-tpl-chrome-ext sub-template 2026-07-05 19:15:07 +02:00
README.md feat(v0.3.2): distracciones explicadas y mascota estable 2026-10-22 01:06:09 +02:00
tsconfig.json feat: FocusPet AI v0.2.0 — on-device sentiment analysis + contextual pet messages 2026-07-12 14:14:38 +02:00
wxt.config.ts chore(release): una sola fuente de version (package.json) y gate del ZIP 2026-10-23 00:46:38 +02:00

saas-tpl-chrome-ext

Chrome MV3 extension sub-template for d0a1 SDD. WXT 0.20.27, TypeScript strict, Biome 2.x, Vitest.

Instanciado vía sdd-init-tpl:

bash scripts/assemble.sh install chrome-extension my-extension

Stack

Layer Tool Version
Build WXT 0.20.27
Language TypeScript 6.0.3 (strict)
Lint/Format Biome 2.5.1 (no ESLint/Prettier)
Testing Vitest 4.1.9
Validation Zod 4.4.3
Commits commitlint 21.1.0
Hooks lefthook 2.1.9 (Go binary)

Develop

pnpm install
pnpm wxt prepare
pnpm dev   # launches WXT dev browser

Build

pnpm build
# Load .output/chrome-mv3 as unpacked extension in Chrome

Validate

pnpm validate  # typecheck + lint + test

License

Apache-2.0

Iconos

public/icons/icon-{16,32,48,128}.png se generan con python3 scripts/generate_icons.py (Pillow):

python3 scripts/generate_icons.py          # escribe public/icons/

Un solo diseño para los cuatro tamaños: cuadro redondeado oscuro con degradado vertical y halo cálido, y un único glifo — la cabeza del gato pixel-art (orejas, ojos y hocico) en naranja GS. Sin texto: a 16 px es ilegible y parece un placeholder. Los cuatro PNG salen del mismo máster de 1024 px con LANCZOS, así que no hay cuatro dibujos distintos. No editar los PNG a mano.

Internacionalización (i18n)

Inglés por defecto (default_locale: "en") y castellano completo, mismo juego de claves en public/_locales/{en,es}/messages.json. Nada de texto de UI hardcodeado en HTML o TS.

  • El HTML marca los elementos con data-i18n, data-i18n-aria-label o data-i18n-title.
  • applyI18n() en src/entrypoints/sidepanel/main.ts rellena textos y atributos, y fija <html lang> al idioma del navegador (chrome.i18n.getUILanguage()).
  • Regla dura: cada clave usada existe en los dos ficheros; una clave ausente se renderiza vacía sin lanzar error, así que se revisa en el PR.
  • Valores con número van por plantilla ($1): xpProgress, xpMax, minutesShort.

Onboarding y ayuda

El panel incluye <details id="how-section"> con cinco puntos: la mascota nace como huevo y evoluciona por 6 etapas con XP; 2 XP por minuto de foco; el pomodoro completo da +50 XP y sube salud (abandonarlo cuesta 10 XP); la salud baja al distraerse; la racha cuenta sesiones de foco completadas seguidas y se reinicia con una distracción; una distracción es cambiar de pestaña en menos de 30 s. Cierra con la nota de privacidad: el Modo IA analiza el texto en el dispositivo.

Se abre solo la primera vez (flag gs-how-seen en browser.storage.local) y queda accesible después desde el propio panel.

v0.3.2 — aclaraciones de UX y mascota estable

  • Bajo "Distracciones" hay un subtítulo: qué cuenta como distracción (−5 XP, −3 salud) y sobre qué pestaña se mide (título de la pestaña activa) o, si el navegador no la expone, que no hay pestaña objetivo fija y se mide la pestaña en la que estás.
  • "Cómo funciona" añade ese mismo detalle y el modelo implícito: no hay pestaña fija, se mide la pestaña activa (5+ min en ella dan XP).
  • La mascota ya no se repinta en cada ciclo: el canvas solo se redibuja si cambian etapa o ánimo, y cada nodo se escribe solo cuando su valor cambia. Al tocarla hace un rebote (respeta prefers-reduced-motion) y nunca se desmonta.