navori 0.2.22 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,26 @@ Multi-agent harness + SDD scaffolder for Claude Code (and other AI engines).
4
4
 
5
5
  `navori` lleva tu setup de Claude Code (agentes, skills, hooks, CLAUDE.md, AGENTS.md) a múltiples repos con un solo comando — sin perder customización local, sin sobrescribir lo que ya tenías.
6
6
 
7
+ También renderiza un harness Codex completo: `AGENTS.md`, skills en
8
+ `.agents/skills/`, agentes y hooks en `.codex/`, y MCP project-local.
9
+
10
+ ### Perfiles de engines
11
+
12
+ ```jsonc
13
+ // Paridad completa para ambos proveedores
14
+ { "engines": ["claude", "codex"] }
15
+
16
+ // Claude completo + guía AGENTS.md ligera para Codex y otras herramientas
17
+ { "engines": ["claude", "agents-md"] }
18
+
19
+ // Solo guía universal, con el menor número de archivos
20
+ { "engines": ["agents-md"] }
21
+ ```
22
+
23
+ `codex` ya incluye y administra `AGENTS.md`; no necesitas combinarlo con
24
+ `agents-md`. Si ambos aparecen en un config, el adapter Codex toma precedencia
25
+ para evitar bloques duplicados.
26
+
7
27
  ## Instalación
8
28
 
9
29
  ```bash
@@ -47,9 +67,9 @@ Y genera:
47
67
  | `add <plugin>` | Activa un plugin y opcionalmente instala la tool externa |
48
68
  | `configure <section>` | Ajusta una sección del config sin re-correr el wizard |
49
69
  | `update` | Re-detecta el repo, refresca config y corre sync en un paso |
50
- | `render` | Genera CLAUDE.md y `.claude/` desde el config (preview por default; `--apply` escribe). `--all` renderea todos los repos del registro global; `--prune` limpia los que ya no existen |
70
+ | `render` | Genera los archivos nativos de cada engine configurado (preview por default; `--apply` escribe). `--all` renderea todos los repos del registro global; `--prune` limpia los que ya no existen |
51
71
  | `registry <sub>` | Registro global de tus repos con navori, para `render --all` (`ls`, `scan <dir>`, `add`, `remove`, `prune`) |
52
- | `sync` | Refresca los managed blocks con conflict resolution + backups |
72
+ | `sync` | Refresca todos los engines configurados con conflict resolution + backups |
53
73
  | `preset init <id>` | Scaffoldea un preset local en `.navori/presets/<id>/` |
54
74
  | `scan` | Detecta workspaces nuevos en monorepos (`pnpm-workspace.yaml` / `package.json#workspaces`) |
55
75
  | `doctor` | Audita el config + drift de cada managed block (CLAUDE.md **y AGENTS.md**), orden canónico, markers malformados, desincronización de monorepo y tools externas faltantes (`--strict` para CI) |
@@ -104,7 +124,6 @@ La resolución es **local → bundled**: si tienes un preset local con el mismo
104
124
  | `gh` | GitHub Issues, PRs y workflow runs | `gh` |
105
125
  | `jscpd` | Detección de duplicación en el diff | `jscpd` (opt-in) |
106
126
  | `semgrep` | Security gate local | `semgrep` (opt-in) |
107
- | `cognitive` | Guardrails de complejidad cognitiva | (ninguna) |
108
127
 
109
128
  Activar uno:
110
129
  ```bash
@@ -212,7 +231,8 @@ Conflict in 'idioma-rol':
212
231
  - tu versión
213
232
  + versión del Core
214
233
  ```
215
- Y eliges: `skip-conflicts` (mantener tu edit), `apply-all` (pisar) o `abort`.
234
+ Y eliges `skip-conflicts`, resolución interactiva para bloques de `CLAUDE.md`, o `abort`.
235
+ Los conflictos de archivo completo nunca se pisan automáticamente.
216
236
 
217
237
  Backups automáticos en `~/.navori/backups/<timestamp>/` antes de cada `sync` (retención 30 días).
218
238
 
@@ -224,7 +244,7 @@ Cambiar una sola cosa sin re-init:
224
244
  navori configure plugins # multiselect de plugins activos
225
245
  navori configure quality-gate # nuevo comando de quality gate
226
246
  navori configure language en # switch a inglés (fallback a es)
227
- navori configure engines # multiselect: claude / agents-md / cursor / copilot
247
+ navori configure engines # multiselect: claude / codex / agents-md / cursor / copilot
228
248
  navori configure branch-base main # punto de fork / rama protegida
229
249
  navori configure pr-target develop # rama destino del PR (gh pr create --base)
230
250
  navori configure workspace bonum # asociar a un workspace
@@ -49,7 +49,7 @@ Archivo ausente, ambiguo (más de un candidato) o con veredicto/scope que no mat
49
49
 
50
50
  ### Gate: no correr de más
51
51
 
52
- Tu `git commit`/`push` dispara los hooks `PreToolUse`, que corren **mecánicamente**: `quality-gate-pre-commit` (re-corre `{{qualityGate.fast}}` y bloquea si está en rojo) + jscpd/semgrep/cognitive (duplicación/seguridad/complejidad). Ese es el enforcement que no se puede saltar. Además, el `reviewer` ya corrió `{{qualityGate.fast}}` verde sobre este mismo diff (evidencia en `review_<feature>.md`, este ciclo) y tú **no editas código**.
52
+ Tu `git commit`/`push` dispara los hooks `PreToolUse`, que corren **mecánicamente**: `quality-gate-pre-commit` (re-corre `{{qualityGate.fast}}` y bloquea si está en rojo) + jscpd/semgrep (duplicación/seguridad). Ese es el enforcement que no se puede saltar. Además, el `reviewer` ya corrió `{{qualityGate.fast}}` verde sobre este mismo diff (evidencia en `review_<feature>.md`, este ciclo) y tú **no editas código**.
53
53
 
54
54
  - ✅ **No corras `{{qualityGate.fast}}` a mano en el pre-flight.** Lo correrías dos veces sobre código ya verificado verde (tu corrida + el hook del commit). Confía en la evidencia del review para proceder; el hook del commit es el backstop mecánico.
55
55
  - ▶️ **Córrelo a mano antes de commitear** solo si dudas de que pase: el diff cambió desde el review, hubo rebase/merge, o no hay evidencia fresca del gate verde. Así evitas un commit bloqueado por el hook y el reintento.
@@ -70,7 +70,6 @@ run_gate() {
70
70
  # standalone, so there is no shared lib to import):
71
71
  # plugins/jscpd/scripts/check-jscpd.sh
72
72
  # plugins/semgrep/scripts/check-semgrep.sh
73
- # plugins/cognitive/scripts/check-cognitive.sh
74
73
  is_git_commit() {
75
74
  local input="$1" segment
76
75
  # FIX B: join `\<newline>` continuations into a space FIRST, so a command
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: new-resource
3
+ description: Crear un recurso/feature de punta a punta en Next.js App Router (tipo → validación → datos → adapter → UI → ruta). Aplica al dar de alta un recurso nuevo; para modificar uno existente, espeja su patrón en vez de rehacerlo.
4
+ type: reference
5
+ maxWords: 800
6
+ ---
7
+
8
+ # new-resource — recurso/feature end-to-end (Next.js App Router)
9
+
10
+ ## Cuándo usar
11
+
12
+ Al dar de alta un recurso o feature nuevo de punta a punta (datos → UI → ruta). Para tocar uno que ya existe, sigue su patrón; no lo rehagas.
13
+
14
+ ## 0. Antes de crear: reusa y sé consistente (esto primero)
15
+
16
+ - **Busca un recurso similar YA en el repo y espéjalo**: estructura de carpetas, naming, capa de datos, manejo de estado. Consistencia con el repo > preferencia personal.
17
+ - **Reusa antes de crear**: ¿ya hay un componente / hook / util (el UI kit del repo, `shared/`) que sirve? Úsalo. Crea algo nuevo solo si de verdad no existe uno equivalente.
18
+ - **Sigue el theme / design system**: usa los tokens y componentes de la lib del repo; nada de estilos hardcodeados ni UI fuera de tema.
19
+ - **Una fuente de verdad**: deriva tipos, labels y estados de donde ya viven; no dupliques enums ni constantes.
20
+
21
+ ## Estructura — feature-based + colocación
22
+
23
+ - Todo lo del recurso **junto, colocado a su feature/ruta** (`_components`, `_lib` privados en App Router — el prefijo `_` los excluye del routing). No lo esparzas en `/components` o `/utils` globales.
24
+ - **Regla shared**: si UN feature lo usa → vive dentro del feature; si DOS o más lo usan → promuévelo a `shared/`. Los features **no se importan entre sí** (si hace falta, compón en la page o sube la pieza a shared).
25
+ - Nesting 2-3 niveles máx. Empieza simple; agregas estructura cuando el recurso realmente crece.
26
+
27
+ ## Pasos (orden estricto — de adentro hacia afuera)
28
+
29
+ Cada paso depende del anterior; verifica que compila antes de seguir.
30
+
31
+ 1. **Tipo de dominio** — el modelo del recurso en tu capa de tipos, agnóstico del backend o de tipos generados. Enums + sus labels/variants derivados aquí (fuente única).
32
+ 2. **Validación en la frontera** — schema (zod) para todo input externo (form, params, respuesta de red). Los DTOs salen del schema (`z.infer`), no se escriben a mano.
33
+ 3. **Acceso a datos (server)** — la query/mutation por tu capa de datos: fetch en un Server Component, un Server Action o un route handler. Secretos y sesión quedan en el server.
34
+ 4. **Adapter** (solo si hay tipos generados / GraphQL) — mapea el tipo crudo del backend al tipo de dominio y normaliza enums desconocidos a un valor seguro. La UI consume **dominio**, nunca tipos generados.
35
+ 5. **UI** — un Server Component que fetchea y compone; empuja `"use client"` a las **hojas** (interactividad, estado, browser APIs), lo más abajo posible. Pasa props serializables hacia abajo y reusa el UI kit.
36
+ 6. **Routing / nav** — la page/segment en App Router y su entrada de navegación. Sin esto, el recurso no es accesible.
37
+
38
+ ## Server vs Client (App Router)
39
+
40
+ - **Server Component por default**: data, secretos, composición. Fetchea en el server y evita el API ping-pong (no re-traigas en el cliente lo que ya trajo el server).
41
+ - **Client Component** (`"use client"`) solo para interacción, estado local o browser APIs, y siempre lo más abajo posible en el árbol.
42
+
43
+ ## Qué NO hacer (evita over-engineering)
44
+
45
+ - Nada de hexagonal / DDD / CQRS ni capas de abstracción especulativas para un CRUD. Layered simple alcanza.
46
+ - Sin interface o helper genérico con un solo caller, ni parametrización "por si acaso".
47
+ - Sin dependencia nueva para lo que el repo, la plataforma o una lib ya instalada resuelven en unas líneas.
48
+ - No dupliques un componente que ya existe con otro nombre (rompe la fuente única y el theme).
49
+
50
+ ## Antes de declarar listo
51
+
52
+ - `{{qualityGate.fast}}` en verde.
53
+ - El recurso es accesible (page + entrada de nav) y el golden path anda; el input inválido se rechaza en la frontera (zod).
54
+ - Reusaste lo que existía y seguiste el patrón + theme del repo — no inventaste una variante.
55
+ - La UI consume tipos de dominio (no generados) y `"use client"` está solo donde hace falta.
56
+
57
+ <!-- navori:user-section -->
58
+ ## Convenciones de este repo
59
+
60
+ <!-- user: documenta aquí lo específico de tu stack para que el scaffold sea exacto:
61
+ - Rutas exactas donde viven tipos, schemas, capa de datos, adapters y features/UI.
62
+ - Tu UI kit / design system y dónde está el theme (tokens, componentes base a reusar).
63
+ - Si usas GraphQL + codegen: el comando (ej. `bun run codegen`) y de dónde salen los tipos generados.
64
+ - El helper de validación y el contrato de respuestas/errores.
65
+ - Un recurso EJEMPLO ya hecho que sirva de molde a espejar.
66
+ -->
@@ -21,6 +21,11 @@
21
21
  "id": "nextjs-data-fetching",
22
22
  "relPath": "presets/nextjs/skills/nextjs-data-fetching.md",
23
23
  "destRelPath": ".claude/skills/nextjs-data-fetching.md"
24
+ },
25
+ {
26
+ "id": "new-resource",
27
+ "relPath": "presets/nextjs/skills/new-resource.md",
28
+ "destRelPath": ".claude/skills/new-resource.md"
24
29
  }
25
30
  ],
26
31
  "hooks": []
@@ -40,6 +40,8 @@
40
40
  "Bash(stat:*)",
41
41
  "Bash(tree:*)",
42
42
  "Bash(grep:*)",
43
+ "Bash(sg:*)",
44
+ "Bash(ast-grep:*)",
43
45
  "Bash(jq:*)",
44
46
  "Bash(diff:*)",
45
47
  "Bash(cut:*)",
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: debug-error
3
+ description: Usar cuando un comando (tsc, lint, build, test) o el runtime escupe un muro de errores. Antes de tocar código: filtra el ruido, clasifica el tipo de error, y arregla la CAUSA RAÍZ, no los síntomas en cascada. Los patrones de error de tu stack van en la user-section.
4
+ type: behavior
5
+ maxWords: 600
6
+ ---
7
+
8
+ # Debug error — triage antes de arreglar
9
+
10
+ Cuando un comando falla con muchas líneas, el error es reaccionar al primero (o al más ruidoso) y tirar un fix. Este skill fuerza el triage previo.
11
+
12
+ ## El protocolo (en orden)
13
+
14
+ 1. **Filtra el ruido.** Aísla los errores reales del chatter de la herramienta: líneas de progreso/éxito (`compiled`, `generating…`), warnings (no son errores) y logs sin stack. Quédate solo con las líneas que son un error de verdad.
15
+ 2. **Clasifica el tipo.** Antes de arreglar, identifica la categoría — cada una tiene una forma de causa distinta:
16
+ - **Tipos / compilador** (tsc): tipo esperado vs recibido; a menudo un tipo desactualizado o una regeneración pendiente (codegen / schema).
17
+ - **Lint**: mecánico, casi siempre auto-fixable; no lo trates como bug de lógica.
18
+ - **Build**: config, env, o boundary (server/client, dynamic) — no es el código de negocio.
19
+ - **Runtime**: `undefined` / `null` no manejado, red, o auth / sesión.
20
+ 3. **Encuentra la causa RAÍZ.** Un solo error raíz suele cascadear en 10-20 downstream (un import o tipo faltante rompe todo lo que lo usa). **Arregla la raíz, re-corre y RE-CLASIFICA** — no dispares varios fixes a la vez contra los síntomas.
21
+ 4. **Reporta / arregla** con el formato de `formato-respuesta` (`CAUSA` + `archivo:línea` + `FIX` mínimo). Sin preámbulo.
22
+
23
+ ## Reglas
24
+
25
+ - **Un fix a la vez** contra la raíz, luego re-corre. Si el mismo error persiste tras el fix → cambia a `loop-back-debug` (re-valida la hipótesis, no sigas patcheando).
26
+ - **No arregles síntomas** que van a desaparecer solos al arreglar la raíz.
27
+ - **Warning ≠ error** — un warning no bloquea; no gastes el turno en él salvo que lo pidan.
28
+
29
+ <!-- navori:user-section -->
30
+ ## Patrones de error de tu stack
31
+
32
+ <!-- user: documenta aquí los errores recurrentes de TU toolchain y su fix, para triage instantáneo. Sugerencias:
33
+ - Filtros de ruido específicos (líneas del build/runner que NO son errores).
34
+ - Errores típicos con su causa + fix (ej. codegen no corrido, boundary server/client, import path/alias, env faltante).
35
+ - Comandos de regeneración/validación (codegen, migrations) que resuelven categorías enteras de errores.
36
+ -->
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: security-guidance
3
+ description: Usar al correr /security-review o al auditar seguridad. Documenta las invariantes de seguridad de NEGOCIO que el scanner estático (semgrep) y el review built-in no infieren del código solo — autorización server-side, acceso a objetos (IDOR), secretos y env expuesto al cliente, fronteras de confianza, PII en logs. El esqueleto es universal; las reglas de tu stack van en la user-section.
4
+ type: reference
5
+ maxWords: 1200
6
+ ---
7
+
8
+ # Security guidance — capa de seguridad de negocio
9
+
10
+ Alimenta el flujo `/security-review`. Los patrones genéricos de vuln web (XSS, SSRF, secretos hardcodeados, deserialización insegura, inyección) ya los cubren semgrep y el reviewer built-in. Aquí va lo que el modelo **no puede inferir del código solo**: las invariantes de autorización y confianza que dependen del dominio.
11
+
12
+ Reporta con severidad `[CRÍTICO]`/`[ALTO]`/`[MEDIO]` y `archivo:línea`, como en `review-diff`. Un bypass de autorización o un secreto expuesto es CRÍTICO.
13
+
14
+ ## 1. Autorización — se enforcea en el servidor
15
+
16
+ - Toda ruta / endpoint / acción que expone datos o efectos protegidos DEBE verificar el rol o permiso **en el servidor**, antes de la query o el efecto. Falta de guard server-side = **bypass de autorización, CRÍTICO**.
17
+ - Los guards de cliente (render condicional, checks en el componente, un `useAuth()`) **nunca alcanzan solos** — son UX, no enforcement. Una vista protegida que solo confía en el cliente es CRÍTICO.
18
+ - La config de navegación / UI (menús, un `allowedRoles` en el array de nav) filtra la UI, **no** controla acceso. Agregar una entrada ahí sin el guard server-side correspondiente es un hallazgo.
19
+ - El guard debe **fallar cerrado**: sin sesión o backend caído → deniega / redirige, nunca "deja pasar por las dudas". No agregues un path que corte en error hacia el lado permisivo.
20
+
21
+ ## 2. Acceso a objetos (IDOR)
22
+
23
+ - Un id que viene del input (URL, body, query) NO autoriza por existir. La **propiedad / alcance se verifica server-side** (idealmente en el backend o la capa de acceso), no en el cliente.
24
+ - Una vista que trae un registro por id-de-URL debe confiar en el error de acceso del backend (`ACCESS_DENIED` / 403), no inventar su propio check de ownership ni asumir que el id es válido.
25
+ - Las listas de entidades sensibles nunca se consultan desde el cliente con filtros amplios — van por el servidor con la sesión autenticada.
26
+
27
+ ## 3. Manejo de errores de auth
28
+
29
+ - Los errores de autenticación / autorización (sesión expirada, cuenta bloqueada, 401/403) se manejan **de forma global y fail-closed** (logout / redirect), no se tragan localmente ni se muestran inline como error de formulario.
30
+ - Define el contrato de códigos de error del backend (ej. 401 sesión, 423 bloqueo, 429 rate-limit) y respétalo. Manejo custom de esos códigos en un componente puntual es un hallazgo.
31
+
32
+ ## 4. Secretos y variables de entorno
33
+
34
+ - Cero secretos / tokens / URLs internas hardcodeados — **incluido tests y archivos `.env.example`** (usa placeholders). Un secreto en código es CRÍTICO.
35
+ - Las vars que se **bundlean al cliente** (prefijos como `NEXT_PUBLIC_`, `VITE_`, `PUBLIC_`) DEBEN ser seguras de filtrar: nada de API keys, tokens ni URLs internas detrás de ese prefijo. Poner un valor sensible ahí es CRÍTICO.
36
+
37
+ ## 5. Fronteras de confianza / flujo de datos
38
+
39
+ - Todo dato de fuente externa (backend, red, input) se **valida y normaliza en la frontera** antes de entrar al dominio. No pases valores crudos del backend directo a la UI.
40
+ - Fallbacks de enums / estados desconocidos → a un valor seguro conocido, nunca passthrough crudo ni throw (un enum no confiable crudo en la UI = confusión de estado o potencial XSS).
41
+ - Respeta las fronteras arquitectónicas que declare el repo (qué capa puede importar tipos generados o hablar con qué backend).
42
+
43
+ ## 6. Logging y PII
44
+
45
+ - Nada de `console.log` / print de datos de usuario, tokens, cookies de sesión o PII (email, teléfono, documentos) en paths de producción. Logs de debug solo detrás de un guard de entorno (ej. `NODE_ENV === 'development'`).
46
+
47
+ ## Cómo usarlo en el review
48
+
49
+ 1. Recorre el diff o el área con estas 6 categorías como checklist.
50
+ 2. Reporta con severidad y `archivo:línea`.
51
+ 3. Cruza con las **reglas específicas de tu stack** (abajo): los nombres concretos de tus guards, códigos de error y prefijos de env viven ahí — sin eso, el review solo cubre la capa universal.
52
+
53
+ <!-- navori:user-section -->
54
+ ## Invariantes de seguridad de tu stack
55
+
56
+ <!-- user: documenta aquí lo que el modelo NO puede inferir del código — las reglas concretas de TU dominio. Sugerencias:
57
+ - AUTORIZACIÓN: nombre y firma del guard server-side obligatorio (ej. `requireRole([...])`), dónde va, sus paths terminales, y qué rutas lo exigen.
58
+ - IDOR: cómo se identifican los recursos (UUID / CUID / slug), el helper de validación, y qué entidades son sensibles.
59
+ - ERRORES: el contrato exacto de códigos de tu backend (401/403/423/429…) y el handler global.
60
+ - ENV: el gestor de secretos (Infisical / Vault / …), el prefijo de vars cliente de tu framework, y qué NUNCA lleva ese prefijo.
61
+ - FRONTERAS: qué capa puede importar qué (tipos generados, clientes de backend), reglas de adapters y sanitización.
62
+ - Anti-patterns de tu repo que son auto-CRÍTICO.
63
+ -->
@@ -0,0 +1,69 @@
1
+ ---
2
+ name: structural-search
3
+ description: Usar cuando necesitas localizar formas sintácticas, relaciones estructurales o hacer un refactor multi-sitio; escala desde engram y Grep hacia ast-grep solo con triggers explícitos.
4
+ type: reference
5
+ ---
6
+
7
+ # structural-search — leer lo mínimo correcto
8
+
9
+ Encuentra primero la región correcta y abre solo el span confirmado. Las herramientas de precisión verifican una hipótesis; no la forman.
10
+
11
+ ## Escalera Rung 0–2
12
+
13
+ ### Rung 0 — orientación con engram
14
+
15
+ Antes de buscar, consulta memoria para preguntas durables: dónde vive un módulo, entry points, capas, convenciones y decisiones. Usa el resultado como **hipótesis de scope**, nunca como fuente de verdad para líneas, firmas o call sites.
16
+
17
+ Confirma cada puntero con una búsqueda barata. Si el código contradice la memoria, corrige la observación de inmediato. Guarda punteros estructurales, no snapshots volátiles.
18
+
19
+ ### Rung 1 — texto con Grep/ripgrep (default)
20
+
21
+ Úsalo cuando conoces un token literal: nombre, import, config key, string de error.
22
+
23
+ 1. Empieza estrecho: archivo, directorio o tipo obtenido en Rung 0.
24
+ 2. Pide primero archivos (`rg -l`) o `file:line` con máximo dos líneas de contexto.
25
+ 3. Deduplica antes de leer.
26
+ 4. Abre únicamente el span que confirma el hit.
27
+
28
+ Escala a Rung 2 solo si ocurre uno:
29
+
30
+ - cero resultados después de dos patrones razonables;
31
+ - los resultados son puro ruido;
32
+ - estás escribiendo regex para aproximar sintaxis;
33
+ - necesitas un refactor estructural multi-sitio.
34
+
35
+ ### Rung 2 — estructura con ast-grep
36
+
37
+ Usa `sg` o `ast-grep` para formas del AST:
38
+
39
+ ```bash
40
+ sg -p 'async function $N($$$) { $$$ }' -l ts src/
41
+ ast-grep -p 'useAuth($$$)' -l tsx apps/
42
+ ```
43
+
44
+ Para reescribir, prueba primero el patrón sin `--rewrite`, limita paths/lenguaje y revisa el diff antes de aplicar. Un nombre literal sigue siendo Rung 1; una pregunta conceptual vuelve a Rung 0.
45
+
46
+ Si ninguno de los binarios existe, cae a Grep y lectura puntual: **no bloquees la tarea** ni inventes sintaxis de ast-grep.
47
+
48
+ ## Mapa rápido
49
+
50
+ | Necesidad | Rung |
51
+ |---|---:|
52
+ | Dónde vive un adapter o convención | 0 |
53
+ | Import, símbolo o mensaje conocido | 1 |
54
+ | Hooks/componentes con una forma concreta | 2 |
55
+ | Codemod multi-sitio | 2 |
56
+ | Semántica cross-file con tipos | lectura manual del span confirmado |
57
+
58
+ ## Límites
59
+
60
+ - No leas archivos completos por reflejo.
61
+ - No corras grep ancho sin scope.
62
+ - No uses regex como AST.
63
+ - Si la búsqueda consume ~15% del contexto, detente: reduce scope o actúa con la evidencia disponible.
64
+ - No montes LSP/Serena; este harness termina en Rung 2.
65
+
66
+ <!-- navori:user-section -->
67
+ ## Patrones estructurales del proyecto
68
+
69
+ <!-- user: documenta aquí patrones sg/ast-grep comprobados, lenguajes y paths frecuentes. Guarda patrones reutilizables; no pegues resultados ni líneas actuales. -->
@@ -1,6 +1,9 @@
1
1
  ## Engram
2
2
 
3
- - `mem_save` proactivo tras decisión / bug-fix-con-root-cause / convención / discovery / preferencia confirmada.
4
- - `mem_search` al inicio si el primer mensaje referencia el proyecto. Verificar en código que lo recordado siga existiendo antes de afirmarlo.
5
- - Lo recordado es una foto de cuando se guardó, no un hecho vigente. Si el sistema expone vigencia (`active` / `needs_review`), trata `needs_review` como contexto stale: avisa al usuario y verifícalo contra el código actual antes de apoyarte en eso.
3
+ - **Arranque de sesión (primer paso, obligatorio):** llama `mem_context` al inicio de CADA sesión para recuperar decisiones, discoveries y trabajo de sesiones previas — no esperes a que el usuario lo pida. En hosts que NO cargan la memoria con un hook de arranque (p.ej. Codex), esta llamada explícita ES el arranque de la memoria; no la omitas.
4
+ - **Pre-flight:** `mem_search` con keywords de la tarea para orientar dónde/por qué vive algo antes de buscar código. La memoria da una región e hipótesis; confirma firma, línea y call sites con Grep/structural-search antes de actuar.
5
+ - **Guarda solo lo durable:** decisiones, arquitectura, convenciones, root causes y punteros de módulo. Nunca persistir líneas, firmas actuales, listas de call sites ni estado temporal.
6
+ - `mem_save` proactivo con `topic_key` estable por tema. Reutiliza el mismo key para evolucionar una observación mediante upsert, en vez de crear snapshots repetidos.
7
+ - **Write-back:** si el código contradice una memoria, corrígela con `mem_update`/`mem_save` de inmediato. Trata `needs_review` como contexto stale.
6
8
  - `mem_session_summary` obligatorio antes de "listo": Goal · Discoveries · Accomplished · Next Steps · Relevant Files.
9
+ - **Curación al cerrar:** tras guardar el summary, revisa lo creado en la sesión. Consolida duplicados bajo su `topic_key`, asciende lo durable y elimina solo observaciones claramente volátiles o ya cubiertas por el summary. No hagas borrado agresivo ni borres una decisión durable.
@@ -19,6 +19,10 @@
19
19
  },
20
20
  "postInstall": "claude plugin install engram"
21
21
  },
22
+ "mcpServer": {
23
+ "command": "engram",
24
+ "args": ["mcp", "--tools=agent"]
25
+ },
22
26
  "skills": [
23
27
  {
24
28
  "id": "engram-leader-extension",
@@ -8,7 +8,7 @@ type: behavior
8
8
 
9
9
  Antes de descomponer trabajo: **busca contexto** con `mem_search` usando keywords del ticket. Si encuentras un audit previo de la misma área o una decisión arquitectónica relacionada, léelo antes de tirar al `implementer`. No re-descubrir lo que ya está guardado.
10
10
 
11
- Después de cada decisión arquitectónica, plugin nuevo o convención establecida en la sesión: `mem_save` proactivo con tipo apropiado (`decision`, `convention`, `pattern`, `bugfix`). Encabeza con qué decisión + por qué + dónde aplica.
11
+ Después de cada decisión arquitectónica, plugin nuevo o convención establecida en la sesión: `mem_save` proactivo con tipo apropiado (`decision`, `convention`, `pattern`, `bugfix`) y un `topic_key` estable. Reutiliza el key para evolucionar el tema sin acumular snapshots. Guarda punteros durables; líneas, firmas y call sites se verifican en código y no se persisten.
12
12
 
13
13
  Antes de cerrar la sesión: `mem_session_summary` obligatorio con:
14
14
 
@@ -17,3 +17,5 @@ Antes de cerrar la sesión: `mem_session_summary` obligatorio con:
17
17
  - `accomplished` — qué quedó hecho.
18
18
  - `next_steps` — qué falta (con paths concretos).
19
19
  - `relevant_files` — paths que un futuro agente debería leer primero.
20
+
21
+ Después del summary, cura la sesión: consolida duplicados, corrige memorias contradichas y elimina solo contenido claramente volátil o redundante. Nunca hagas pruning agresivo de decisiones durables.
@@ -30,7 +30,7 @@
30
30
  {
31
31
  "event": "PreToolUse",
32
32
  "matcher": "Bash",
33
- "command": "bash .claude/scripts/check-jscpd.sh",
33
+ "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/scripts/check-jscpd.sh\"",
34
34
  "timeout": 180,
35
35
  "statusMessage": "navori/jscpd: dup check"
36
36
  }
@@ -34,7 +34,7 @@ cmd=$(extract_cmd)
34
34
  # space. Because it matches a segment START, a quoted `echo "git commit"` does
35
35
  # NOT trigger it. Known limitation: it cannot see through `sh -c`, `eval`, or
36
36
  # obfuscation — a seatbelt, not a sandbox. Body duplicated across the navori quality hooks (they render standalone — no
37
- # shared lib). The quality-gate/jscpd/cognitive copies gate `git commit` ONLY;
37
+ # shared lib). The quality-gate/jscpd copies gate `git commit` ONLY;
38
38
  # the semgrep copy also gates `git push` and `gh pr create` (remote-push
39
39
  # security backstop). Keep in sync.
40
40
  is_git_commit() {
@@ -87,8 +87,19 @@ if [ -n "$cmd" ] && ! is_git_commit "$cmd"; then
87
87
  exit 0
88
88
  fi
89
89
 
90
- if ! command -v jscpd >/dev/null 2>&1; then
91
- echo "⊘ jscpd no instalado localmente skip (install: pnpm add -g jscpd)" >&2
90
+ # Resolve jscpd: prefer the repo-pinned binary (node_modules/.bin) over a global
91
+ # one. A global jscpd can be a DIFFERENT major (e.g. 4.x vs the repo's 5.x) whose
92
+ # tokenizer reports different duplication than `pnpm run dup`, so the commit gate
93
+ # would measure something other than what the repo declares. Local-first fixes it.
94
+ JSCPD_BIN=""
95
+ _repo_root="$(git rev-parse --show-toplevel 2>/dev/null || true)"
96
+ if [ -n "$_repo_root" ] && [ -x "$_repo_root/node_modules/.bin/jscpd" ]; then
97
+ JSCPD_BIN="$_repo_root/node_modules/.bin/jscpd"
98
+ elif command -v jscpd >/dev/null 2>&1; then
99
+ JSCPD_BIN="jscpd"
100
+ fi
101
+ if [ -z "$JSCPD_BIN" ]; then
102
+ echo "⊘ jscpd no disponible (ni pinneado en el repo ni instalado global) — skip (install: pnpm add -D jscpd)" >&2
92
103
  exit 0
93
104
  fi
94
105
 
@@ -121,7 +132,7 @@ echo "▶ jscpd: ${#files[@]} archivo(s) modificados vs {{branchBase}}" >&2
121
132
  tmpdir=$(mktemp -d)
122
133
  trap 'rm -rf "$tmpdir"' EXIT
123
134
 
124
- jscpd \
135
+ "$JSCPD_BIN" \
125
136
  --min-tokens 100 \
126
137
  --min-lines 10 \
127
138
  --mode strict \
@@ -29,7 +29,7 @@
29
29
  {
30
30
  "event": "PreToolUse",
31
31
  "matcher": "Bash",
32
- "command": "bash .claude/scripts/check-semgrep.sh",
32
+ "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/scripts/check-semgrep.sh\"",
33
33
  "timeout": 180,
34
34
  "statusMessage": "navori/semgrep: security scan"
35
35
  }
@@ -1,8 +1,14 @@
1
1
  #!/usr/bin/env bash
2
2
  # Generated by @navori/plugin-semgrep. Runs semgrep over TS/TSX files changed
3
- # vs `{{branchBase}}` with the `auto` ruleset. Skips silently if semgrep or
3
+ # vs `{{branchBase}}` with the `p/default` ruleset. Skips silently if semgrep or
4
4
  # git are absent — the tool is optional.
5
5
  #
6
+ # NOTE: `p/default` (not `auto`) on purpose. `--config=auto` is INCOMPATIBLE
7
+ # with `--metrics=off` in semgrep >=1.x ("Cannot create auto config when metrics
8
+ # are off") because auto uploads project metadata to fetch tailored rules. A
9
+ # static ruleset keeps telemetry off AND runs deterministically — better for a
10
+ # gate anyway (same rules on every machine).
11
+ #
6
12
  # Triggered as a PreToolUse(Bash) hook (gated to git commit / push / gh pr create) and as a
7
13
  # Stop hook (runs unconditionally at session close).
8
14
 
@@ -35,7 +41,7 @@ cmd=$(extract_cmd)
35
41
  # space. Because it matches a segment START, a quoted `echo "git commit"` does
36
42
  # NOT trigger it. Known limitation: it cannot see through `sh -c`, `eval`, or
37
43
  # obfuscation — a seatbelt, not a sandbox. Body duplicated across the navori quality hooks (they render standalone — no
38
- # shared lib). The quality-gate/jscpd/cognitive copies gate `git commit` ONLY;
44
+ # shared lib). The quality-gate/jscpd copies gate `git commit` ONLY;
39
45
  # the semgrep copy also gates `git push` and `gh pr create` (remote-push
40
46
  # security backstop). Keep in sync.
41
47
  is_scan_trigger() {
@@ -120,7 +126,7 @@ fi
120
126
  echo "▶ semgrep: ${#files[@]} archivo(s) modificados vs {{branchBase}}" >&2
121
127
 
122
128
  semgrep scan \
123
- --config=auto \
129
+ --config=p/default \
124
130
  --error \
125
131
  --metrics=off \
126
132
  "${files[@]}"