diff --git a/CHANGELOG.md b/CHANGELOG.md index 50bd544..ddfa063 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,25 @@ Formato basado en [Keep a Changelog](https://keepachangelog.com/) y [SemVer](htt ## [No publicado] +## [3.5.0] - 2026-11-03 + +### Notas de actualización +- `npx -y github:lacasoft/dev-starter-kit#v3.5.0 --update --yes`. Si tu proyecto vino de un `design.md` de system-design-kit ≥ 1.4, vuelve a correr `/project-context /design.md` para traer la ficha y los flujos: actualiza solo lo que vino del diseño. + +### Added +- **La ficha de responsabilidades del diseño llega al código.** `/project-context` traslada desde un `design.md`: + - la *Ficha de responsabilidades* a *Arquitectura → Responsabilidades y límites*; + - las reglas de límite (qué componente decide qué, y que ningún contexto escribe los datos de otro) a *Reglas de negocio*; + - los *Flujos críticos* a *Testing → Tests de recuperación*: uno por cada paso con efecto desconocido o con recuperación, como lista para `tdd`; + - la tabla *Contextos y propiedad* a *Modelo / dominio*, con un módulo por contexto si el repo todavía no tiene estructura. +- **Baseline §7:** respeta los límites de *Responsabilidades y límites*. Cada regla va en su dueño (no en el controlador, el adaptador ni el job) y ningún módulo escribe el estado de otro; si una tarea exige cruzar un límite, se dice antes de hacerlo. +- La plantilla de `CLAUDE.project.md` pide las responsabilidades en *Arquitectura*. + +### Fixed +- **WSL con Node de Windows:** el instalador fallaba con `EPERM` en `C:\Windows`, porque CMD no acepta la carpeta de WSL y se cambia ahí. Ahora lo detecta antes de escribir nada y explica qué hacer. +- **`project-context` en Pi:** ya no sugiere `claude --add-dir`; en Pi la ruta se lee directo. +- **En Pi, las referencias de una skill podían quedar sin leer.** Una instrucción escrita a media frase se salta: en la prueba con Sonnet, `/skill:project-context` no leyó `desde-design.md` e improvisó el mapeo, sin la ficha y con los tests de recuperación en una línea. Ahora `project-context` y `owasp-review` piden leer su referencia como paso explícito y con la ruta completa. Repetida la prueba, la ficha llegó completa y quedaron 6 tests de recuperación. + ## [3.4.0] - 2026-10-30 Completa el soporte para [Pi Agent](https://github.com/earendil-works/pi): reglas por carpeta en monorepos y `/loop-task`. Para Claude Code no cambia nada. diff --git a/README.md b/README.md index c9177a9..7a3f482 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Dentro de **cualquier proyecto** (nuevo o heredado), sin clonar nada: ```bash npx -y github:lacasoft/dev-starter-kit # interactivo npx -y github:lacasoft/dev-starter-kit --yes --all # desatendido (todo) -npx -y github:lacasoft/dev-starter-kit#v3.4.0 # fijar una versión (recomendado) +npx -y github:lacasoft/dev-starter-kit#v3.5.0 # fijar una versión (recomendado) ``` Toma siempre la última versión de `master` (o el tag indicado). Repo **público (MIT)**. @@ -158,12 +158,17 @@ claude --add-dir ../acortador-urls # para que pueda leer la carpeta del dis > /project-context ../acortador-urls/design.md ``` +En Pi Agent (instalado con `--pi`) no hace falta `--add-dir`: `/skill:project-context ../acortador-urls/design.md`. + | Del diseño | Al proyecto | | --- | --- | | Requisitos y fuera de alcance | *Visión del producto* (con "Fuera de alcance (v1)") | | Requisitos no funcionales y escala | *Atributos de calidad* con sus umbrales | | API y modelo de datos | *Modelo / dominio* y contratos en *Arquitectura* | | Arquitectura inicial y escenarios de falla | *Arquitectura* (con "Fallas previstas") y tests de regresión en *Testing* | +| Ficha de responsabilidades (system-design-kit ≥ 1.4) | *Arquitectura → Responsabilidades y límites*, y las reglas de límite en *Reglas de negocio*: el agente que programa sabe dónde va cada regla | +| Flujos críticos | *Testing → Tests de recuperación*: uno por cada paso con efecto desconocido o con recuperación, como lista para `tdd` | +| Contextos y propiedad (system-design-kit ≥ 1.5) | *Modelo / dominio*, y un módulo por contexto si el repo todavía no tiene estructura | | Decisiones clave y tradeoffs | **Un ADR por decisión** en `docs/adr/`, con la plantilla de la skill `adr` | | Supuestos sin confirmar | *Pendiente de confirmar* | @@ -287,8 +292,8 @@ modelos de varios proveedores, también locales. Con `--pi`, el kit añade una c las mismas skills, reglas y helpers: no hay una segunda copia que mantener. ```bash -npx -y github:lacasoft/dev-starter-kit#v3.4.0 --pi # proyecto nuevo -npx -y github:lacasoft/dev-starter-kit#v3.4.0 --update --pi --yes # proyecto que ya usa el kit +npx -y github:lacasoft/dev-starter-kit#v3.5.0 --pi # proyecto nuevo +npx -y github:lacasoft/dev-starter-kit#v3.5.0 --update --pi --yes # proyecto que ya usa el kit ``` **Requisitos:** Pi 1.4.0 o superior (paquete `@earendil-works/pi-coding-agent`, pide Node.js 22.19+), @@ -426,7 +431,7 @@ recibir la copia vieja. La solución buena es la misma que exige la baseline §6 versión** — y de paso hace la instalación reproducible: ```bash -npx -y github:lacasoft/dev-starter-kit#v3.4.0 --update --yes # por tag +npx -y github:lacasoft/dev-starter-kit#v3.5.0 --update --yes # por tag npx -y github:lacasoft/dev-starter-kit# --update --yes # por commit (el SHA del tag) ``` @@ -448,4 +453,4 @@ Repo **público (MIT)** distribuido por `npx github:` → la rama **`master` deb (dry-run) y en un monorepo multi-stack, en cada PR, más un job que prueba la capa de Pi dentro de Pi 1.4.0. La lista sale de `scripts/stacks.cjs`, que la deriva de `install.js`. - **Cómo añadir** agentes, skills, stacks o externos: ver [CONTRIBUTING.md](CONTRIBUTING.md). - **Versionado**: SemVer en `package.json` + `CHANGELOG.md`, con tag anotado por versión - (`v3.4.0`). Instala siempre pineando (`#v3.4.0`): es reproducible y evita la cache de npx. + (`v3.5.0`). Instala siempre pineando (`#v3.5.0`): es reproducible y evita la cache de npx. diff --git a/install.js b/install.js index f2b186c..aecc212 100644 --- a/install.js +++ b/install.js @@ -1137,7 +1137,26 @@ function summarizeProject(stacks) { } // ---------- main ---------- +// ---------- Node de Windows desde WSL ---------- +// Con WSL y Node instalado solo en Windows, npx corre en Windows: CMD no acepta la carpeta de WSL +// (\\wsl.localhost\…) y se cambia a C:\Windows, donde el kit se instalaría o fallaría con EPERM. +function windowsSystemDir(platform = process.platform, cwd = CWD, env = process.env) { + if (platform !== "win32") return false; + const sys = path.win32.resolve(env.SystemRoot || env.windir || "C:\\Windows").toLowerCase(); + const dir = path.win32.resolve(cwd).toLowerCase(); + return dir === sys || dir.startsWith(sys + "\\") || /^\\\\wsl/i.test(env.INIT_CWD || ""); +} + async function main() { + if (windowsSystemDir()) { + console.error(`❌ El instalador está corriendo con el Node de Windows en ${CWD}. + Si usas WSL: instala Node dentro de WSL (por ejemplo con nvm), comprueba que + \`command -v node npx\` muestre rutas de Linux y no /mnt/c/…, y vuelve a correrlo. + Si usas Windows: córrelo desde la carpeta de tu proyecto, no desde una carpeta del sistema.`); + closeInput(); + process.exitCode = 1; + return; + } const VERSION = (readJSON(path.join(KIT, "package.json")) || {}).version || "?"; console.log("\n╔════════════════════════════════════════════╗"); console.log(`║ Dev Starter Kit v${VERSION} — instalador `.slice(0, 45) + "║"); @@ -1359,8 +1378,12 @@ async function main() { closeInput(); } -main().catch((e) => { - console.error(e); - closeInput(); - process.exit(1); -}); +module.exports = { windowsSystemDir }; + +if (require.main === module) { + main().catch((e) => { + console.error(e); + closeInput(); + process.exit(1); + }); +} diff --git a/package.json b/package.json index 7d6c4b9..c482485 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lacasoft/dev-starter-kit", - "version": "3.4.0", + "version": "3.5.0", "private": true, "description": "Base .claude coherente (agentes, skills, helpers, orquestación multiagente nativa) instalable en cualquier proyecto lacasoft (backend/frontend/mobile/blockchain).", "bin": { diff --git a/shared/.claude/CLAUDE.base.md b/shared/.claude/CLAUDE.base.md index 646f930..67c222a 100644 --- a/shared/.claude/CLAUDE.base.md +++ b/shared/.claude/CLAUDE.base.md @@ -143,6 +143,7 @@ Esto no es solo documentación: el hook `pre-bash` (`helpers/hook-handler.cjs`) - Nada de código muerto ni comentado "por si acaso". - Manejo de errores explícito; nunca tragar excepciones en silencio. - Tests para la nueva funcionalidad y para cada regresión corregida. +- **Respeta los límites** de *Arquitectura → Responsabilidades y límites* en `CLAUDE.project.md`: cada regla de negocio va en su dueño (no en el controlador, el adaptador ni el job), y ningún módulo escribe el estado de otro. Si una tarea exige cruzar un límite, dilo antes de hacerlo. - TypeScript/tipado **strict**; evita `any` (usa `unknown` + narrowing). - **Gate de código nuevo** (*clean as you code*): lo que cambia no introduce issues nuevos de lint, tipos ni seguridad; **cobertura ≥ 80 % de las líneas nuevas o modificadas** donde se mida; duplicación nueva ≤ 3 %. La deuda heredada no bloquea el cambio, pero no se amplía. - En lógica crítica (dinero, permisos, cálculos), la cobertura no basta: **mutation testing** (Stryker, mutmut, PIT) o **property-based testing** demuestran que los tests fallan cuando el código se rompe. diff --git a/shared/.claude/skills/owasp-review/SKILL.md b/shared/.claude/skills/owasp-review/SKILL.md index 37d284e..a2246e5 100644 --- a/shared/.claude/skills/owasp-review/SKILL.md +++ b/shared/.claude/skills/owasp-review/SKILL.md @@ -19,7 +19,7 @@ Las listas completas (las 10 categorías con qué buscar, los 17 capítulos de A Antes de buscar patrones, dibuja el mapa: puntos de entrada (rutas, handlers, webhooks, jobs, CLI, mensajes de cola), fronteras de confianza, datos sensibles que cruzan cada frontera, dependencias nuevas y llamadas salientes (HTTP, shell, LLM, otras herramientas). Sin mapa, el barrido es ruido. ## 3. Barrido por categoría -Recorre A01→A10 sobre la superficie del paso 2 (tabla en `referencia.md`). Para cada sospecha, **traza fuente → sink**: de dónde viene el dato, qué validación o codificación recibe y dónde se usa. Si no puedes trazarlo, es sospecha, no hallazgo. +**Primero lee `.claude/skills/owasp-review/referencia.md`**: su tabla dice qué buscar en cada categoría. Luego recorre A01→A10 sobre la superficie del paso 2. Para cada sospecha, **traza fuente → sink**: de dónde viene el dato, qué validación o codificación recibe y dónde se usa. Si no puedes trazarlo, es sospecha, no hallazgo. Prioridades que más se escapan: - **A01**: autorización por objeto en cada acceso por id (no basta estar autenticado); SSRF también vive aquí desde 2025. @@ -27,7 +27,7 @@ Prioridades que más se escapan: - **A10**: qué pasa cuando algo falla. Un `catch` que deja pasar, un check de autorización que concede si lanza excepción, un error que filtra internals. ## 4. ASVS por tipo de cambio -Según lo que toque el cambio, verifica los capítulos correspondientes al nivel elegido (mapa en `referencia.md`): auth → V6/V7/V9/V10, permisos → V8, archivos → V5, API → V4, frontend → V3, configuración → V13, cripto → V11, logs y errores → V16. +Según lo que toque el cambio, verifica los capítulos correspondientes al nivel elegido (mapa en `.claude/skills/owasp-review/referencia.md`): auth → V6/V7/V9/V10, permisos → V8, archivos → V5, API → V4, frontend → V3, configuración → V13, cripto → V11, logs y errores → V16. ## 5. LLM y agentes (si el proyecto los usa) Si el código llama a un LLM, revisa contra el **OWASP Top 10 for LLM Applications 2026**; si construye agentes, herramientas o servidores MCP, también contra el **Top 10 for Agentic Applications 2026**. Lo mínimo: el texto que el modelo lee es dato no confiable, su salida se valida antes de tocar SQL/shell/HTML/herramientas, y lo irreversible pide confirmación humana. diff --git a/shared/.claude/skills/project-context/SKILL.md b/shared/.claude/skills/project-context/SKILL.md index a0a205e..c046bea 100644 --- a/shared/.claude/skills/project-context/SKILL.md +++ b/shared/.claude/skills/project-context/SKILL.md @@ -17,7 +17,9 @@ Las rutas que nombra esta skill (`CLAUDE.project.md`, `docs/adr/`, `.claude/…` - **Cero secretos**: nombres de variables de entorno sí; valores nunca. ## 0. Si partes de un diseño (design.md) -Si el argumento es una ruta a un `design.md` del **system-design-kit** (front matter con `language` y marcas ``), ese documento es la fuente de **lo que el repo no puede decir**: visión, requisitos, escala, decisiones y fallas. La persona ya lo pensó y lo decidió; tu trabajo es trasladarlo sin reescribirlo ni reinterpretarlo. Lee [desde-design.md](desde-design.md) y sigue su mapeo. Lo derivable del repo (stack real, comandos, estructura) sigue saliendo de los pasos 1-3: el diseño no sustituye al código. +Si el argumento es una ruta a un `design.md` del **system-design-kit** (front matter con `language` y marcas ``), ese documento es la fuente de **lo que el repo no puede decir**: visión, requisitos, escala, decisiones y fallas. La persona ya lo pensó y lo decidió; tu trabajo es trasladarlo sin reescribirlo ni reinterpretarlo. Lo derivable del repo (stack real, comandos, estructura) sigue saliendo de los pasos 1-3: el diseño no sustituye al código. + +**Antes de escribir nada, lee [desde-design.md](desde-design.md)**, que está junto a este archivo (`.claude/skills/project-context/desde-design.md`). Su tabla dice a qué sección de `CLAUDE.project.md` va cada parte del diseño, incluida la ficha de responsabilidades, que se copia tal cual, y los flujos críticos, que se vuelven tests de recuperación. Sin esa tabla, no traslades nada. ## 1. Lee lo que hay `CLAUDE.project.md` actual (si existe, **actualízalo**, no lo reescribas: conserva lo que escribió el equipo), `README`, manifiestos y lockfiles, configuración de lint/format/tests, `Makefile`/scripts, Dockerfile y compose, workflows de CI, `.env.example`, `docs/adr/`, y la estructura de primer y segundo nivel. Si el argumento nombra un área, profundiza ahí. diff --git a/shared/.claude/skills/project-context/desde-design.md b/shared/.claude/skills/project-context/desde-design.md index c07f122..6771779 100644 --- a/shared/.claude/skills/project-context/desde-design.md +++ b/shared/.claude/skills/project-context/desde-design.md @@ -11,7 +11,8 @@ reescriba requisitos ni decisiones: el diseño se **traslada**, resumido y con l `api-data-model`, `architecture`, `decisions`, `failures`, `ai-review`. - Una sección que solo tiene `_⏳ Pendiente_` / `_⏳ Pending_` está vacía: no hay nada que trasladar. - Si la ruta está fuera del proyecto, Claude Code pedirá permiso para leerla (o arranca con - `claude --add-dir `). + `claude --add-dir `). En Pi Agent no hace falta: la ruta se lee directo + (`/skill:project-context ..//design.md`). ## Mapeo a CLAUDE.project.md @@ -20,9 +21,13 @@ reescriba requisitos ni decisiones: el diseño se **traslada**, resumido y con l | título + `requirements` (funcionales) | **Visión del producto** | 2-4 líneas: qué es, para quién, los casos de uso principales | | `out-of-scope` | **Visión del producto** → línea "Fuera de alcance (v1)" | Lista corta. Es lo que más evita que el agente construya de más | | `api-data-model` (entidades, términos) | **Modelo / dominio** | Glosario de entidades y su clave de acceso | +| `api-data-model` (*Contextos y propiedad*, si existe) | **Modelo / dominio** → "Contextos y propiedad" | La tabla tal cual: contexto, reglas, dueño de los datos, contratos. Si el repo todavía no tiene estructura, en **Estructura del repositorio** sugiere un módulo por contexto, sin imponerlo | | `api-data-model` (endpoints, eventos) | **Arquitectura** → "Contratos" | Solo los de los casos de uso principales, con idempotencia y paginación si el diseño las fija | | `architecture` | **Arquitectura** | Componentes y flujo principal, síncrono y asíncrono; enlaza el diagrama del diseño en vez de copiarlo | +| `architecture` (*Ficha de responsabilidades*, si existe) | **Arquitectura** → "Responsabilidades y límites" | La tabla tal cual: componente, responsable de, no le toca, estado del que es dueño y ejecución. Son los límites que el código respeta: ahí se ve dónde va cada regla | +| `architecture` y `api-data-model` (dueños) | **Reglas de negocio (invariantes)** | Las de límite, en una línea cada una: qué componente decide qué, y que ningún contexto escribe los datos de otro | | `failures` | **Arquitectura** → "Fallas previstas" y **Testing** | Una línea por escenario (escenario → mitigación). En *Testing*, los que merecen test de regresión | +| `failures` (*Flujos críticos*, si existen) | **Testing** → "Tests de recuperación" | Uno por cada paso con efecto **desconocido** o con recuperación (duplicado, timeout, concurrencia, reinicio): qué se simula y qué evidencia de cierre se comprueba. No los escribas ahora: quedan como lista para la skill `tdd` | | `requirements` (no funcionales) + `scale` | **Atributos de calidad** | Los umbrales con número (latencia, disponibilidad, consistencia) y el orden de magnitud de carga | | `requirements` (seguridad, privacidad) | **Seguridad y compliance** | Si el diseño fija el nivel ASVS, úsalo; si no, propónlo y márcalo como pendiente | | `decisions` | **Decisiones de arquitectura** | Un ADR por decisión (abajo) y aquí solo la línea con el enlace | diff --git a/shared/templates/PROJECT.template.md b/shared/templates/PROJECT.template.md index bf1951b..5e9d26b 100644 --- a/shared/templates/PROJECT.template.md +++ b/shared/templates/PROJECT.template.md @@ -32,7 +32,9 @@ --> ## Arquitectura - + ## Reglas de negocio (invariantes)