Saltar al contenido principal

Wiedii — Política de Gestión de Herramientas con mise

⚠️ Verificar versiones antes de usar — los números de versión de herramientas en esta nota pueden estar desactualizados. Usar mise ls-remote <herramienta> | tail -5 para consultar las versiones disponibles. Ver politicas-core.

mise (sitio oficial: mise.jdx.dev) es el gestor centralizado de herramientas. Toda herramienta binaria disponible en el registro de mise debe instalarse via mise. Los entornos deben ser 100% reproducibles: versiones exactas fijadas y lockfiles mise.lock son obligatorios.

1. Orden de prioridad de backends

Obligatorio: antes de agregar o actualizar cualquier herramienta en mise.toml, abrir https://mise-versions.jdx.dev/ y confirmar qué backends la soportan y qué versiones están disponibles. Nunca asumir un backend — siempre verificar.

Core tools (runtimes del lenguaje)node, bun, python, go, ruby, rust, deno, java, swift, zig, elixir, erlang — se escriben con su nombre corto, SIN prefijo (node = "24.1.0", no "core:node"). El prefijo core: es redundante; no es una "opción", es donde viven los runtimes.

Resto de herramientas (CLIs/binarios) — prioridad de backend, con prefijo OBLIGATORIO:

PrioridadBackendCuándo usarlo
aqua:Preferido siempre. Registro curado de mise con checksums verificados.
npm:CLI del ecosistema JS que NO va en package.json.
pipx:CLI de Python que NO va en pyproject.toml.
cargo:CLI de Rust no disponible en aqua.
asdf:Último recurso — plugins heredados.

Otros backends (vfox:, go:, gem:, ubi:, dotnet:…) solo si la herramienta únicamente existe ahí.

Regla del gestor nativo: si la herramienta pertenece al ecosistema del lenguaje del proyecto (prettier/eslintpackage.json, ruff/mypypyproject.toml), va en su gestor nativo, NO en mise. Excepción: las CLIs de Go siempre van en mise.toml (go.mod solo registra librerías importadas, no ejecutables).

2. Valores de versión prohibidos

latest y lts están prohibidos. Todas las versiones deben ser exactas: "X.Y.Z".

# ❌ Prohibido
bun = "latest"

# ✅ Requerido
bun = "1.3.14"

Recipe para agregar una herramienta ya fijada — nunca latest, ni siquiera para "descubrir". La tentación común es poner latest un momento para ver qué versión resuelve y luego fijarla; eso igual viola la regla y, peor, no es fiable: latest puede resolver una versión vieja (caso real: pipx:checkov resolvió 3.2.497 cuando la última publicada era 3.3.2). Descubrí la versión y fijala en un solo paso — mise ls-remote es el equivalente CLI de consultar mise-versions.jdx.dev:

mise ls-remote <backend>:<tool> | tail -5 # descubrir las últimas versiones (NUNCA poner latest)
mise use <backend>:<tool>@X.Y.Z # agregar YA fijada (actualiza mise.toml + mise.lock)

# Ejemplo (lo que faltó el día del checkov 3.2.497):
mise ls-remote pipx:checkov | tail -5
mise use pipx:checkov@3.3.2

Nota sobre bun: es un core tool nativo de mise — bun = "x.y.z" es equivalente a "core:bun" = "x.y.z". El registro de mise mapea automáticamente el alias corto. La forma sin prefijo es la canónica según los docs oficiales de mise.

3. Config global del sistema (~/.config/mise/config.toml)

El config global debe forzar el determinismo. El bloque de abajo es la plantilla base mínima — cada developer la extiende con las herramientas globales que necesite, respetando las reglas de esta sección:

[settings]
experimental = true # necesario para los [hooks] (postinstall) — NO para el lockfile
lockfile = true # habilita lectura/escritura de mise.lock (NO lo crea: usar `mise lock`)
all_compile = false # evita instalaciones implícitas por compilación

[tools]
# Herramientas globales gestionadas por mise (versiones exactas, backends explícitos).
# IMPORTANTE: las herramientas que Homebrew ya gestiona NO van aquí — evitar duplicados.
# Ejemplos: git, git-flow-next, glab → Homebrew. bun, node → mise (versiones por proyecto).
node = "24.13.0" # core tool → nombre corto, sin prefijo
bun = "1.3.14" # core tool → nombre corto, sin prefijo

4. Template estándar de mise.toml por proyecto

Cada proyecto debe tener un mise.toml en la raíz con:

  • Prefijos de backend explícitos
  • Versiones exactas fijadas
  • Bloque [env] para variables de entorno del proyecto
  • [hooks] para instalar lefthook automáticamente tras mise install
  • [tasks.setup] para onboarding reproducible
[tools]
bun = "1.3.14"
"aqua:evilmartians/lefthook" = "2.1.9"
# git-flow-next es GLOBAL — no agregar aquí; ver ~/.config/mise/config.toml
"aqua:tamasfe/taplo" = "0.10.0"
"aqua:hadolint/hadolint" = "2.14.0"
"aqua:mvdan/sh" = "3.13.1" # shfmt
"aqua:koalaman/shellcheck" = "0.11.0"
# Agregar según stack:
# "aqua:astral-sh/ruff" = "0.4.5" # Python
# "pipx:mypy" = "1.10.0" # tipos estáticos Python (Python NO va en mise si ya está en pyproject.toml)
# "aqua:golangci/golangci-lint" = "1.59.0" # Go
# "aqua:aquasecurity/trivy" = "0.52.0" # escaneo de seguridad
# "aqua:snyk/snyk" = "1.1295.0" # seguridad de dependencias

[env]
# variables de entorno a nivel de proyecto
# NODE_ENV = "development"

[hooks]
# postinstall es un hook experimental de mise — no requiere mise activate
# CI=true lo setean GitLab CI, GitHub Actions y la mayoría de sistemas CI
# En local $CI está vacío → lefthook install corre normalmente
postinstall = "[ -z \"$CI\" ] && lefthook install || true"

[tasks.setup]
description = "Setup completo: herramientas, lock, hooks y dependencias"
# ⚠️ Una sola cadena con && (NO array): el hook `toml` con reorder_arrays=true reordenaría
# alfabéticamente los pasos al commitear y rompería el orden de ejecución. Ver [[mise]] y [[wiedii-configs]].
# ⚠️ La tarea NO empieza con `mise trust`: mise no ejecuta tareas de un config no confiable,
# así que en un clon nuevo hay que correr `mise trust` ANTES (ver sección 11). Meterlo aquí sería circular.
run = "mise install --yes && mise lock && pkg=$(find . -maxdepth 2 -name 'package.json' ! -path '*/node_modules/*' | head -1) && { [ -n \"$pkg\" ] && bun install --cwd \"$(dirname \"$pkg\")\" || true; }"

5. Requisito de lockfile

Verificar antes de fijar: antes de commitear cualquier versión en mise.toml, confirmar que la versión existe para el backend elegido en https://mise-versions.jdx.dev/.

⚠️ El lockfile NO se crea solo. lockfile = true solo le dice a mise que lea y escriba mise.lock: mantiene actualizado un archivo que ya exista, pero NO lo genera. Hay que crearlo una vez con mise lock y commitearlo. (El setting experimental no tiene que ver con el lock — es para los [hooks].)

Al crear el repo (una vez): generar el lock y commitearlo.

mise lock # crea mise.lock para la plataforma actual
# Reproducibilidad mac (dev) + linux (CI/Docker): fijar ambas plataformas
mise lock --platform macos-arm64,linux-x64
git add mise.toml mise.lock

Después, el lock se mantiene solo en cada cambio de herramienta:

mise use aqua:tool/name@x.y.z # cambia mise.toml y actualiza mise.lock
mise install # instala y actualiza mise.lock (si ya existe)
mise upgrade # sube versiones dentro del rango + actualiza el lock
git add mise.toml mise.lock

mise install y mise use solo actualizan un mise.lock existente; no lo crean. Por eso el mise lock inicial es obligatorio. El mise run setup de Wiedii ya incluye mise lock para que el archivo nunca falte.

6. Comandos de auditoría y limpieza

mise ls # listar herramientas instaladas y su backend
mise outdated # identificar herramientas con actualizaciones disponibles vs. versión fijada
mise prune # eliminar binarios huérfanos que no están en el lockfile

7. Resolución de conflictos (mise.toml vs mise.lock)

  1. Cambio solicitado por el usuario: actualizar mise.toml, luego regenerar con mise install.
  2. Sin instrucción de cambio: respetar mise.lock — no modificar el entorno.
  3. Siempre reportar si se usó un backend de menor prioridad cuando uno de mayor prioridad estaba disponible.

8. Reglas de invocación de herramientas

Tipo de herramientaCómo invocarEjemplo
Binarios gestionados por misemise exec -- <tool>mise exec -- taplo fmt file.toml
Paquetes instalados por bunbun <package>bun eslint src/
Paquetes puntuales (no instalados)bunxbunx --yes some-package

Nunca usar bunx para paquetes instalados en node_modules.

9. package.json en repos JS/TS

Con wietoo (commits nativos vía mise, sin Node), el package.json ya no necesita script commit ni devDependencies de commitlint/czg. Un package.json de un repo JS/TS Wiedii se ve así:

{
"type": "module",
"engines": {
"bun": "1.3.14",
"node": "Please use Bun instead of Node to install dependencies",
"npm": "Please use Bun instead of NPM to install dependencies",
"pnpm": "Please use Bun instead of PNPM to install dependencies",
"yarn": "Please use Bun instead of Yarn to install dependencies"
}
}
  • "type": "module" — todos los repos nuevos en Wiedii usan ESM (p. ej. eslint.config.mjs usa import/export default). ⚠️ Excepción monorepo Nx: el package.json de la RAÍZ de un workspace Nx NO debe llevar "type": "module" (rompe los generators/migraciones de Nx). En ese caso, dejar la raíz sin type, declarar "type": "module" solo en cada packages/*, y usar extensión .mjs/.cjs explícita para las configs de la raíz. Ver [[nx-monorepo#⚠️ "type": "module" NO va en el package.json raíz del workspace]].
  • Commits: se hacen con wietoo commit (binario nativo instalado por mise) — no hay script "commit" ni devDependencies de commitlint/czg en package.json. Ver wietoo-cli.
  • engines — patrón Wiedii: mensajes de error en los campos de versión hacen explícito que solo se usa Bun.
  • lefthook install no va en package.json — se gestiona exclusivamente via [hooks].postinstall en mise.toml. Esto garantiza que los hooks se instalan en cualquier proyecto, sea Node o no, y nunca en CI.

10. Herramientas que son SIEMPRE globales (no agregar al mise.toml del proyecto)

Estas herramientas nunca van en el mise.toml de un proyecto individual porque son transversales a todos los repos o las gestiona Homebrew:

HerramientaGestorMotivo
gitHomebrewHerramienta base del sistema
git-flow-nextHomebrewBranching cross-proyecto — brew install git-flow-next
glabHomebrewCLI de GitLab — brew install glab
docker / docker composeOrbStack (Homebrew)Runtime de contenedores
miseHomebrewNo puede gestionarse a sí mismo
CLIs de IA (claude, claude-code)HomebrewHerramientas de desarrollo global

Regla: si una herramienta ya está en Homebrew y se usa en todos los proyectos, no duplicarla en mise. Si mise es el gestor correcto (versiones por proyecto, como bun o node), entonces sí va en el config global de mise — pero nunca en el mise.toml del proyecto individual.

11. Setup inicial tras clonar

En un clon nuevo el mise.toml aún no es de confianza, y mise no ejecuta tareas de un config no confiable. Por eso el primer comando confía el config y luego corre la tarea:

mise trust && mise run setup
# `mise run setup` ejecuta:
# mise install --yes → instala herramientas + ejecuta lefthook install (si no es CI)
# mise lock → crea/actualiza mise.lock (commitearlo al repo)
# bun install → solo si existe package.json

El mise trust va ANTES, no dentro de la tarea. Como la tarea setup vive en el mise.toml, mise no la ejecuta hasta que el config sea de confianza — incluir mise trust dentro sería circular (nunca se alcanzaría en la primera corrida). En CI mise asume confianza automáticamente, así que ahí mise run setup corre sin el mise trust previo.

lefthook install se ejecuta una sola vez, via [hooks].postinstall de mise, después de mise install --yes. No se ejecuta en entornos CI ($CI=true). No depende de que el proyecto use Node.

El trust aplica a TODO comando que ejecute código del config, no solo a mise run setup. mise exec -- <bin> y mise run <task> requieren por igual un mise.toml de confianza. Caso concreto: la capa determinista de /audit-project (skill audit-static-checks, que corre su fact-collector vía mise exec -- bun run …) falla en silencio sobre un config no confiable — reporta audit_static_checks: unavailable (el error real Config files … are not trusted. Trust them with 'mise trust' queda oculto) y la auditoría degrada a modo manual sin avisar la causa. Como un repo recién creado/clonado es no confiable por defecto, hay que correr mise trust antes de auditar. Fix de fondo pendiente en el plugin (issue de feedback registrado): que el runner corra mise trust o reporte la causa explícitamente en vez del unavailable genérico.

Referencias