@damiangilgonzalez/harness 1.3.20 → 1.3.22
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 +6 -6
- package/manifest.json +48 -3
- package/package.json +1 -1
- package/scripts/lib/domains.js +1 -1
- package/skills/hardening/SKILL.md +72 -0
- package/skills/hardening/evals/cases.yaml +32 -0
- package/skills/hardening/zonas.md +75 -0
- package/skills/pr/SKILL.md +21 -1
- package/skills/pr/evals/cases.yaml +1 -0
- package/skills/tunel-ngrok/SKILL.md +42 -0
- package/skills/tunel-ngrok/evals/cases.yaml +32 -0
- package/skills/tunel-ngrok/tunel.sh +52 -0
- package/targets/claude.js +0 -1
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ Empiezas pequeño. El resto se carga bajo demanda: el harness te propone una ski
|
|
|
107
107
|
la pide, con la evidencia que lo justifica.
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
rsc install --profile minimal # la base: orient + suggest + bro + unslop + show-me + eli5 + harness + init + teach
|
|
110
|
+
rsc install --profile minimal # la base: orient + suggest + bro + unslop + show-me + eli5 + harness + init + teach + tunel-ngrok + hardening
|
|
111
111
|
rsc install --profile core # la base + el método completo
|
|
112
112
|
rsc install --profile full # todo el catálogo
|
|
113
113
|
```
|
|
@@ -126,12 +126,12 @@ Lo que se comparte va a git; el estado de la máquina, no.
|
|
|
126
126
|
Hooks que vigilan por ti: recuerdan la cadena, piden confirmación antes de un `rm -rf` o un
|
|
127
127
|
`git push --force` y paran antes de volver a `main` sin abrir la PR.
|
|
128
128
|
|
|
129
|
-

|
|
130
130
|
|
|
131
|
-
En Claude Code quedan activados `skins`, `savvy-progress
|
|
131
|
+
En Claude Code quedan activados `skins`, `savvy-progress` y `cache-tax`
|
|
132
132
|
(mantiene caliente la caché, y eso gasta tokens). `superpowers` llega cuando el proyecto usa el método.
|
|
133
133
|
|
|
134
|
-
En cifras:
|
|
134
|
+
En cifras: 296 skills, 34 agentes y 43 entradas de comando, para 17 asistentes
|
|
135
135
|
(Claude Code, Codex, Cursor, Copilot, Gemini…). Detalle en la [referencia técnica](docs/referencia-tecnica.md).
|
|
136
136
|
|
|
137
137
|
---
|
|
@@ -249,9 +249,9 @@ Guía completa: [la memoria del harness](docs/como-funciona/memoria.md).
|
|
|
249
249
|
|
|
250
250
|
## Catálogo
|
|
251
251
|
|
|
252
|
-

|
|
253
253
|
|
|
254
|
-
|
|
254
|
+
296 skills en 25 dominios: software, negocio, contenido, datos e IA.
|
|
255
255
|
Cada una se activa sola cuando la tarea encaja.
|
|
256
256
|
|
|
257
257
|
**[Ver el catálogo completo →](docs/catalogo.md)** · [Referencia técnica](docs/referencia-tecnica.md) ·
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.
|
|
2
|
+
"version": "1.3.22",
|
|
3
3
|
"counts": {
|
|
4
|
-
"skills":
|
|
4
|
+
"skills": 296,
|
|
5
5
|
"agents": 34,
|
|
6
6
|
"commands": 43,
|
|
7
7
|
"fixedCommands": 10
|
|
@@ -2341,6 +2341,31 @@
|
|
|
2341
2341
|
"full"
|
|
2342
2342
|
]
|
|
2343
2343
|
},
|
|
2344
|
+
{
|
|
2345
|
+
"id": "hardening",
|
|
2346
|
+
"description": "Use when the user asks for hardening, a security or privacy audit of the product, or aligning it with SOC 2, ISO 27001 or ISO 27701: audits by zones with read-only subagents, checks every finding by hand, gives the list by severity, the user decides, and the chosen fixes go to spec and tickets. NOT a quick scan of a diff (that is `security-scan`), NOT secure-coding rules while writing code (that is `secure-coding`).",
|
|
2347
|
+
"tags": [
|
|
2348
|
+
"security",
|
|
2349
|
+
"hardening",
|
|
2350
|
+
"soc2",
|
|
2351
|
+
"iso27001",
|
|
2352
|
+
"iso27701",
|
|
2353
|
+
"privacy",
|
|
2354
|
+
"audit"
|
|
2355
|
+
],
|
|
2356
|
+
"recommends": [
|
|
2357
|
+
"to-spec",
|
|
2358
|
+
"to-tickets",
|
|
2359
|
+
"write-adr",
|
|
2360
|
+
"implement-spec"
|
|
2361
|
+
],
|
|
2362
|
+
"profiles": [
|
|
2363
|
+
"minimal",
|
|
2364
|
+
"core",
|
|
2365
|
+
"ui",
|
|
2366
|
+
"full"
|
|
2367
|
+
]
|
|
2368
|
+
},
|
|
2344
2369
|
{
|
|
2345
2370
|
"id": "harness",
|
|
2346
2371
|
"description": "Use when governing a workspace's control plane, code or not — the `01-TOOLS/` tooling layer, the `docs/` chaos→knowledge wiki, the root Knowledge map. Audits it, migrates legacy `XX-*` folders, scaffolds provider tooling, sweeps the inbox, writes root CLAUDE.md/AGENTS.md. NOT the bootstrap front door (that is `init`, which hands off here).",
|
|
@@ -3805,7 +3830,7 @@
|
|
|
3805
3830
|
},
|
|
3806
3831
|
{
|
|
3807
3832
|
"id": "pr",
|
|
3808
|
-
"description": "Use when writing a PR body or opening a PR: a visual summary, before/after evidence, the merge danger (one-way or two-way door, blast radius), and a title checked against the repo's CI title rule before `gh pr create`.",
|
|
3833
|
+
"description": "Use when writing a PR body or opening a PR: a short plain-language story of what was broken or missing and why it changed, a visual summary, before/after evidence, the merge danger (one-way or two-way door, blast radius), and a title checked against the repo's CI title rule before `gh pr create`.",
|
|
3809
3834
|
"tags": [
|
|
3810
3835
|
"pull-request",
|
|
3811
3836
|
"review",
|
|
@@ -5351,6 +5376,26 @@
|
|
|
5351
5376
|
],
|
|
5352
5377
|
"profiles": []
|
|
5353
5378
|
},
|
|
5379
|
+
{
|
|
5380
|
+
"id": "tunel-ngrok",
|
|
5381
|
+
"description": "Use when the user wants to open a local project's frontend on their phone without deploying, share the local environment through a public URL, get HTTPS for the microphone or camera, or set up ngrok in a project. One ngrok tunnel to the frontend port; the frontend proxies the API so the phone sees a single HTTPS origin. NOT deploying to a real host (that is `deployment`).",
|
|
5382
|
+
"tags": [
|
|
5383
|
+
"ngrok",
|
|
5384
|
+
"tunnel",
|
|
5385
|
+
"mobile",
|
|
5386
|
+
"https",
|
|
5387
|
+
"local-dev"
|
|
5388
|
+
],
|
|
5389
|
+
"recommends": [
|
|
5390
|
+
"deployment"
|
|
5391
|
+
],
|
|
5392
|
+
"profiles": [
|
|
5393
|
+
"minimal",
|
|
5394
|
+
"core",
|
|
5395
|
+
"ui",
|
|
5396
|
+
"full"
|
|
5397
|
+
]
|
|
5398
|
+
},
|
|
5354
5399
|
{
|
|
5355
5400
|
"id": "typescript",
|
|
5356
5401
|
"description": "Use when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the build toolchain. NOT runtime code, fs/streams/http (that is `nodejs`); NOT component/route typing (that is `react`/`nextjs`); NOT ORM type-gen (that is `drizzle-orm`).",
|
package/package.json
CHANGED
package/scripts/lib/domains.js
CHANGED
|
@@ -27,7 +27,7 @@ export const DOMAINS = [
|
|
|
27
27
|
{ title: 'Motion & interface craft', ids: ['motion-craft', 'ui-engineering', 'variant-explorer'] },
|
|
28
28
|
{ title: 'Design & content craft', ids: ['design-loop', 'design', 'design-dna', 'presentations', 'course-storytelling', 'course-builder', 'technical-writing', 'translation-l10n'] },
|
|
29
29
|
{ title: 'Knowledge & meta', ids: ['knowledge-ops', 'codebase-onboarding', 'research-ops', 'continuous-learning', 'skill-scout', 'context-budget', 'roast-me', 'show-me', 'eli5', 'fable-operator'] },
|
|
30
|
-
{ title: 'Personal catalog — workflow (Spanish)', ids: ['grill-me', 'grill-with-docs', 'grilling', 'wayfinder', 'to-spec', 'to-tickets', 'to-questionnaire', 'implement', 'implement-spec', 'pr', 'retro', 'revision-de-cambios', 'code-review', 'research', 'prototype', 'domain-modeling', 'handoff', 'write-adr', 'wait-what', 'writing-for-agents', 'claude-project-setup', 'muscle-memory', 'teach'] },
|
|
30
|
+
{ title: 'Personal catalog — workflow (Spanish)', ids: ['grill-me', 'grill-with-docs', 'grilling', 'wayfinder', 'to-spec', 'to-tickets', 'to-questionnaire', 'implement', 'implement-spec', 'pr', 'retro', 'revision-de-cambios', 'code-review', 'research', 'prototype', 'domain-modeling', 'handoff', 'write-adr', 'wait-what', 'writing-for-agents', 'claude-project-setup', 'muscle-memory', 'teach', 'tunel-ngrok', 'hardening'] },
|
|
31
31
|
{ title: 'Personal catalog — interface design (Spanish)', ids: ['flujo-interfaz', 'animar', 'diseno-apple', 'diseno-landing', 'ingeniero-diseno-web', 'leyes-de-percepcion', 'leyes-de-retencion', 'mejor-accesibilidad', 'mejor-colores', 'mejor-layout', 'mejor-redaccion', 'mejor-tipografia', 'mejor-ui', 'sitios-calidad-premio', 'tastemaker', 'video-a-superprompt', 'vocabulario-animacion', 'revision-interfaz'] },
|
|
32
32
|
];
|
|
33
33
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hardening
|
|
3
|
+
description: "Use when the user asks for hardening, a security or privacy audit of the product, or aligning it with SOC 2, ISO 27001 or ISO 27701: audits by zones with read-only subagents, checks every finding by hand, gives the list by severity, the user decides, and the chosen fixes go to spec and tickets. NOT a quick scan of a diff (that is `security-scan`), NOT secure-coding rules while writing code (that is `secure-coding`)."
|
|
4
|
+
tags: [security, hardening, soc2, iso27001, iso27701, privacy, audit]
|
|
5
|
+
recommends: [to-spec, to-tickets, write-adr, implement-spec]
|
|
6
|
+
profiles: [minimal, core, ui, full]
|
|
7
|
+
origin: damiangil
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Hardening
|
|
11
|
+
|
|
12
|
+
Proceso de cinco pasos: alcance, auditoría, comprobación, lista y decisión, y arreglo. El usuario dicta por voz y quiere frases cortas y sin jerga. Cada decisión es suya; la gravedad y el arreglo son propuestas.
|
|
13
|
+
|
|
14
|
+
## 1. Alcance
|
|
15
|
+
|
|
16
|
+
Pregunta todo de una vez, con opciones:
|
|
17
|
+
|
|
18
|
+
- **Normas.** El dictado deforma los números («ISO 27101» era 27701). Confirma cuáles son.
|
|
19
|
+
- **Qué cubre.** Solo el producto (código, base, accesos, secretos, registros, dependencias, contenedores, CI) o también las políticas de empresa.
|
|
20
|
+
- **Qué entregar.** Auditar y luego arreglar lo que elija (recomendado), solo auditar, o arreglarlo todo.
|
|
21
|
+
|
|
22
|
+
**Hecho cuando** las tres respuestas son del usuario.
|
|
23
|
+
|
|
24
|
+
## 2. Auditoría en tres zonas
|
|
25
|
+
|
|
26
|
+
Lee primero el documento de estado del proyecto (el que diga su `AGENTS.md` o `CLAUDE.md`): manda sobre lo que encuentren los agentes. Lanza **tres subagentes en paralelo, solo de lectura**, uno por zona, con el encargo de [`zonas.md`](zonas.md). Mientras trabajan, crea un worktree para el informe si otra sesión usa la carpeta.
|
|
27
|
+
|
|
28
|
+
**Hecho cuando** las tres zonas han devuelto sus hallazgos con evidencia `fichero:línea`.
|
|
29
|
+
|
|
30
|
+
## 3. Comprobación a mano
|
|
31
|
+
|
|
32
|
+
Un agente auditor se equivoca con el mismo aplomo con que acierta. Abre tú el código de **cada hallazgo alto o crítico y de cada medio**, y contrasta cada uno con el estado del proyecto. Ejemplo real: un agente dio por vivas dos tablas que una migración ya había borrado.
|
|
33
|
+
|
|
34
|
+
- Se confirma: márcalo con ✔ en el informe.
|
|
35
|
+
- No se sostiene: corrígelo o quítalo, y dile al usuario qué cambió.
|
|
36
|
+
- El mismo fallo en dos zonas: une los hallazgos en uno.
|
|
37
|
+
|
|
38
|
+
**Hecho cuando** cada hallazgo medio o superior está confirmado, corregido o quitado.
|
|
39
|
+
|
|
40
|
+
## 4. Informe y lista
|
|
41
|
+
|
|
42
|
+
Escribe el informe en la wiki o en `docs/` del proyecto (por ejemplo, `docs/wiki/seguridad/auditoria-hardening.md`, o con fecha si ya existe) y enlázalo desde su índice. Lleva lo siguiente:
|
|
43
|
+
|
|
44
|
+
- resumen;
|
|
45
|
+
- hallazgos por gravedad, cada uno con controles, evidencia, escenario y arreglo;
|
|
46
|
+
- «Bien hecho» y «No aplica todavía»;
|
|
47
|
+
- inventario de datos personales.
|
|
48
|
+
|
|
49
|
+
Al usuario dale **la lista entera, numerada, de más a menos grave**, cada hallazgo en una o dos frases llanas: qué pasa y qué podría hacer alguien con ello. Que la conteste a su manera, punto por punto. Si un punto no se entiende, explica qué programa es y cómo pasa, con una imagen cotidiana.
|
|
50
|
+
|
|
51
|
+
**Hecho cuando** el usuario ha respondido a cada número o lo ha dejado expresamente para después.
|
|
52
|
+
|
|
53
|
+
## 5. Decisión y arreglo
|
|
54
|
+
|
|
55
|
+
Dale a cada número un destino y escríbelo en «Decisión del usuario», con fecha, en el informe:
|
|
56
|
+
|
|
57
|
+
| Destino | Qué haces |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Se arregla | Entra en la tanda de arreglos |
|
|
60
|
+
| Anotado | Una fila en el roadmap del proyecto con «Anotado, sin preocupar por ahora» |
|
|
61
|
+
| Pendiente que ya existía | Busca su ticket abierto (`gh issue list --search`); si no lo hay, créalo y enlázalo en el roadmap |
|
|
62
|
+
| Aceptado o descartado | Una línea con su razón |
|
|
63
|
+
|
|
64
|
+
La tanda de arreglos sigue la cadena del proyecto, en una rama aparte:
|
|
65
|
+
|
|
66
|
+
1. Spec y tickets (`to-spec` y `to-tickets`), con un ticket por arreglo independiente.
|
|
67
|
+
2. Un ADR (`write-adr`) para lo difícil de revertir, como los roles de la base.
|
|
68
|
+
3. Desarrollo con agentes en paralelo (`implement-spec`). Cada arreglo lleva su prueba, que falla antes del arreglo y pasa después.
|
|
69
|
+
|
|
70
|
+
La PR queda sin fusionar.
|
|
71
|
+
|
|
72
|
+
**Hecho cuando** cada número tiene su destino escrito y la tanda está en tickets.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
skill: hardening
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Haz un hardening del producto."
|
|
5
|
+
why: "Disparador directo de hardening."
|
|
6
|
+
- prompt: "Audita la seguridad y la privacidad de la aplicacion."
|
|
7
|
+
why: "Disparador directo de hardening."
|
|
8
|
+
- prompt: "Quiero alinear el producto con SOC 2 e ISO 27001."
|
|
9
|
+
why: "Disparador directo de hardening."
|
|
10
|
+
- prompt: "Run a security and privacy audit against ISO 27701."
|
|
11
|
+
why: "Disparador directo de hardening."
|
|
12
|
+
- prompt: "Revisa por zonas que fallos de seguridad tiene el proyecto y dame la lista por gravedad."
|
|
13
|
+
why: "Disparador directo de hardening."
|
|
14
|
+
|
|
15
|
+
should_not_trigger:
|
|
16
|
+
- prompt: "Abre el front en el movil con ngrok."
|
|
17
|
+
route_to: "tunel-ngrok"
|
|
18
|
+
why: "Abrir el front en el movil es el trabajo de tunel-ngrok, no de hardening."
|
|
19
|
+
- prompt: "Documenta la decision de arquitectura."
|
|
20
|
+
route_to: "write-adr"
|
|
21
|
+
why: "Documentar una decision de arquitectura es el trabajo de write-adr, no de hardening."
|
|
22
|
+
- prompt: "Parte esta spec en tickets."
|
|
23
|
+
route_to: "to-tickets"
|
|
24
|
+
why: "Partir una spec en tickets es el trabajo de to-tickets, no de hardening."
|
|
25
|
+
- prompt: "Configura el pipeline de CI para que pase los tests en cada push."
|
|
26
|
+
route_to: "github-actions"
|
|
27
|
+
why: "Montar la CI es el trabajo de github-actions, no de hardening."
|
|
28
|
+
|
|
29
|
+
capability:
|
|
30
|
+
- scenario: "El usuario pide una auditoria de seguridad del producto."
|
|
31
|
+
must_include:
|
|
32
|
+
- "gravedad"
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Zonas de la auditoría
|
|
2
|
+
|
|
3
|
+
Encargo de cada subagente del paso 2 de [`SKILL.md`](SKILL.md). Copia el **marco común** en los tres encargos y añade la zona.
|
|
4
|
+
|
|
5
|
+
## Marco común
|
|
6
|
+
|
|
7
|
+
- Auditoría **solo de lectura**. Prohibido modificar ficheros.
|
|
8
|
+
- Prohibido lanzar pruebas o comandos que rehagan bases compartidas. Busca en el proyecto cuáles son y nómbralas en el encargo (por ejemplo, los tests de la base y `supabase db reset`).
|
|
9
|
+
- De `.env` y de los secretos, solo si la variable existe. Nunca su valor.
|
|
10
|
+
- Cada hallazgo, con evidencia `fichero:línea`. Lo que esté bien, una línea en «Bien hecho».
|
|
11
|
+
- Formato de cada hallazgo:
|
|
12
|
+
- título;
|
|
13
|
+
- gravedad (crítica, alta, media o baja);
|
|
14
|
+
- controles afectados;
|
|
15
|
+
- evidencia;
|
|
16
|
+
- escenario concreto de ataque o de fallo;
|
|
17
|
+
- arreglo en una o dos líneas.
|
|
18
|
+
- Hallazgos de más a menos grave, y después «Bien hecho» y «No aplica todavía (sin despliegue)».
|
|
19
|
+
|
|
20
|
+
## Zona 1. Identidad, autenticación y autorización
|
|
21
|
+
|
|
22
|
+
**Controles.**
|
|
23
|
+
- SOC 2: CC6.1, CC6.2, CC6.3, CC6.6 y CC6.7.
|
|
24
|
+
- ISO 27001: 5.15, 5.16, 5.17, 5.18, 8.2, 8.3, 8.4 y 8.5.
|
|
25
|
+
- ISO 27701: el acceso a datos personales.
|
|
26
|
+
|
|
27
|
+
**Qué revisar.**
|
|
28
|
+
- Rutas sin sesión.
|
|
29
|
+
- El rol, comprobado en el servidor en cada ruta.
|
|
30
|
+
- Acceso a registros ajenos (IDOR).
|
|
31
|
+
- Rutas de desarrollo o dobles que una variable de entorno pueda activar.
|
|
32
|
+
- RLS, `GRANT` y roles de la base, `SECURITY DEFINER` sin `search_path` y el uso de `service_role`.
|
|
33
|
+
- Fuentes externas que deban ser de solo lectura.
|
|
34
|
+
- Configuración de Auth: registro abierto, contraseñas, MFA y duración de los tokens.
|
|
35
|
+
- Registro de los accesos rechazados.
|
|
36
|
+
|
|
37
|
+
## Zona 2. Datos personales, retención y registros
|
|
38
|
+
|
|
39
|
+
**Controles.**
|
|
40
|
+
- ISO 27701: minimización, finalidad, retención y borrado, subencargados, transferencias y derechos del interesado.
|
|
41
|
+
- SOC 2: C1.1, C1.2, la serie P y CC7.2.
|
|
42
|
+
- ISO 27001: 5.12, 5.33, 5.34, 8.10, 8.11, 8.12, 8.15 y 8.24.
|
|
43
|
+
|
|
44
|
+
**Qué revisar.**
|
|
45
|
+
- Qué datos personales hay: voz, nombres, texto libre y conversación.
|
|
46
|
+
- Qué se manda a terceros (proveedores de IA), con `store` o la retención que se pida.
|
|
47
|
+
- Qué se escribe en los registros: trazas con variables locales, tokens, frases y ficheros de depuración.
|
|
48
|
+
- Si se puede borrar o caduca.
|
|
49
|
+
- Cifrado en tránsito.
|
|
50
|
+
- Si la pista de auditoría es de verdad inmutable.
|
|
51
|
+
- `.gitignore` y `git ls-files`, por si se ha colado algo sensible.
|
|
52
|
+
|
|
53
|
+
**Además entrega** la tabla «Inventario de datos personales»: dato, dónde vive, a qué tercero va y cuánto se guarda.
|
|
54
|
+
|
|
55
|
+
## Zona 3. Desarrollo seguro, secretos, dependencias y CI
|
|
56
|
+
|
|
57
|
+
**Controles.**
|
|
58
|
+
- SOC 2: CC6.8, CC7.1 y CC8.1.
|
|
59
|
+
- ISO 27001: 8.4, 8.7, 8.8, 8.9, 8.20, 8.25, 8.26, 8.27, 8.28, 8.29, 8.31 y 8.32.
|
|
60
|
+
|
|
61
|
+
**Qué revisar.**
|
|
62
|
+
- Secretos en git, también en el historial.
|
|
63
|
+
- Entrada no confiable:
|
|
64
|
+
- subidas: tamaño, tipo y ruta;
|
|
65
|
+
- SQL construido a mano;
|
|
66
|
+
- longitud de los textos;
|
|
67
|
+
- inyección de prompt con efecto en las herramientas;
|
|
68
|
+
- fórmulas en el Excel.
|
|
69
|
+
- Límite de peticiones y de gasto.
|
|
70
|
+
- Errores que filtran detalles internos, cabeceras, CSP y CORS.
|
|
71
|
+
- Front: `innerHTML` y dónde se guarda la sesión.
|
|
72
|
+
- Dependencias: si están fijadas y si algo las escanea. `npm audit` se puede lanzar porque solo lee.
|
|
73
|
+
- Docker: si corre como administrador, imágenes sin digest y puertos abiertos a `0.0.0.0`.
|
|
74
|
+
- CI: permisos del token, acciones sin SHA, Dependabot, SAST y búsqueda de secretos.
|
|
75
|
+
- SSH sin verificar la clave del servidor.
|
package/skills/pr/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pr
|
|
3
|
-
description: "Use when writing a PR body or opening a PR: a visual summary, before/after evidence, the merge danger (one-way or two-way door, blast radius), and a title checked against the repo's CI title rule before `gh pr create`."
|
|
3
|
+
description: "Use when writing a PR body or opening a PR: a short plain-language story of what was broken or missing and why it changed, a visual summary, before/after evidence, the merge danger (one-way or two-way door, blast radius), and a title checked against the repo's CI title rule before `gh pr create`."
|
|
4
4
|
tags: ["pull-request", "review", "evidence", "risk"]
|
|
5
5
|
profiles: [core, ui, full]
|
|
6
6
|
origin: damiangil
|
|
@@ -15,6 +15,10 @@ metadata:
|
|
|
15
15
|
Usa esta plantilla para escribir el cuerpo de la PR:
|
|
16
16
|
|
|
17
17
|
```markdown
|
|
18
|
+
## La historia
|
|
19
|
+
|
|
20
|
+
<tres a cinco frases, en coloquial: qué fallaba o faltaba, qué se ha hecho y qué cambia ahora>
|
|
21
|
+
|
|
18
22
|
## Resumen
|
|
19
23
|
|
|
20
24
|
<diagrama, esbozo de diff o árbol>
|
|
@@ -39,6 +43,22 @@ Usa esta plantilla para escribir el cuerpo de la PR:
|
|
|
39
43
|
|
|
40
44
|
Sáltate los preámbulos y deja la prosa breve. Usa el lenguaje del dominio del usuario que está en `GLOSSARY.md`.
|
|
41
45
|
|
|
46
|
+
### La historia
|
|
47
|
+
|
|
48
|
+
Va siempre, la primera. Cuenta el porqué y el qué como se lo contarías a un amigo que no ha visto el código: cercano, coloquial y entendible de un vistazo. Tres a cinco frases que siguen este hilo:
|
|
49
|
+
|
|
50
|
+
1. El problema: qué fallaba o qué faltaba, y a quién le afectaba.
|
|
51
|
+
2. Lo que se ha hecho, en palabras de la calle.
|
|
52
|
+
3. Cómo queda ahora.
|
|
53
|
+
|
|
54
|
+
Habla de lo que nota quien usa el producto. Los nombres de ficheros, funciones y la jerga técnica van en las secciones de abajo.
|
|
55
|
+
|
|
56
|
+
Ejemplo del tono:
|
|
57
|
+
|
|
58
|
+
> Vamos a ver: cuando alguien guardaba un formulario dos veces seguidas, se creaban dos pedidos iguales y luego tocaba borrarlos a mano. Lo que pasaba es que el botón no se bloqueaba mientras se guardaba. Ahora el botón se desactiva hasta que termina, y si aun así llega un pedido repetido, se ignora. Resultado: un clic, un pedido.
|
|
59
|
+
|
|
60
|
+
**Hecha cuando** alguien que no ha visto el código entiende, solo con leerla, qué pasaba y qué cambia.
|
|
61
|
+
|
|
42
62
|
### Resumen
|
|
43
63
|
|
|
44
64
|
Elige la vista más pequeña que deje clara la idea clave.
|
|
@@ -31,6 +31,7 @@ should_not_trigger:
|
|
|
31
31
|
capability:
|
|
32
32
|
- scenario: "El usuario quiere el cuerpo de una PR que se revise de un vistazo."
|
|
33
33
|
must_include:
|
|
34
|
+
- "La historia"
|
|
34
35
|
- "Peligro de fusión"
|
|
35
36
|
- "Radio de impacto"
|
|
36
37
|
- scenario: "El repo tiene un check de título de PR en sus workflows."
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tunel-ngrok
|
|
3
|
+
description: "Use when the user wants to open a local project's frontend on their phone without deploying, share the local environment through a public URL, get HTTPS for the microphone or camera, or set up ngrok in a project. One ngrok tunnel to the frontend port; the frontend proxies the API so the phone sees a single HTTPS origin. NOT deploying to a real host (that is `deployment`)."
|
|
4
|
+
tags: [ngrok, tunnel, mobile, https, local-dev]
|
|
5
|
+
recommends: [deployment]
|
|
6
|
+
profiles: [minimal, core, ui, full]
|
|
7
|
+
origin: damiangil
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Túnel ngrok al front
|
|
11
|
+
|
|
12
|
+
**Un solo túnel, al puerto del front.** El front reenvía la API (y el login, si va por el mismo servidor) a sus destinos, así que el móvil ve un único origen HTTPS: sin CORS, sin IPs, sin certificados.
|
|
13
|
+
|
|
14
|
+
## Pasos
|
|
15
|
+
|
|
16
|
+
1. **Explora y enseña el plan antes de tocar nada.** Localiza y anota:
|
|
17
|
+
- el servidor del front y su puerto: Vite, Angular, Next, o un nginx/Caddy en Docker que sirve el build;
|
|
18
|
+
- el prefijo de la API (`/api`…) y de cualquier otra ruta del backend (`/auth/v1`, `/ws`…);
|
|
19
|
+
- dónde define el front la URL de la API;
|
|
20
|
+
- si ya existe un reenvío (`server.proxy` de Vite, `proxyConfig` de Angular, `rewrites` de Next, `location` de nginx);
|
|
21
|
+
- si el login usa un proveedor externo con lista de redirecciones (Supabase OAuth, Auth0, Google…);
|
|
22
|
+
- si hay otro ngrok abierto: `curl -s http://127.0.0.1:4040/api/tunnels`.
|
|
23
|
+
Termina con la lista de ficheros que tocarás y sus riesgos, y espera el visto bueno.
|
|
24
|
+
2. **Reenvío en el front**, solo si falta. El destino sale de una variable de entorno (reusa la que tenga el proyecto; si no hay, `API_PROXY_TARGET`): dentro de Docker, el nombre del servicio (`http://backend:8000`); en el host, el puerto publicado. Incluye cada prefijo del backend que llame el navegador, websockets con `ws: true`.
|
|
25
|
+
3. **URL relativa solo en desarrollo:** el front llama a `'/api'`. Producción queda como está.
|
|
26
|
+
4. **CORS intacto:** con un solo origen sobra; ningún dominio de ngrok entra en la lista.
|
|
27
|
+
5. **Script del túnel:** copia [`tunel.sh`](tunel.sh) a donde el proyecto guarde sus scripts (por defecto `scripts/dev/tunel-movil.sh`) y ajusta `DEFAULT_PORT` y los mensajes de cómo levantar el front. Respeta las reglas del repo sobre dónde van los scripts y regístralo donde se listen.
|
|
28
|
+
6. **Login externo:** si hay redirecciones de OAuth o enlaces mágicos, dile al usuario que añada el dominio de ngrok a la lista del proveedor, y recomienda `NGROK_DOMAIN` (dominio fijo gratuito) para añadirlo una sola vez. Con usuario y contraseña no hace falta nada.
|
|
29
|
+
7. **Documenta** en dos líneas cómo usarlo, donde el proyecto explique el entorno local, avisando de que la URL es pública mientras está abierta.
|
|
30
|
+
8. **Verifica**; el trabajo está hecho cuando todo esto da lo esperado:
|
|
31
|
+
- `curl localhost:<puerto>/api/...` responde el backend (un 401 en JSON del backend vale);
|
|
32
|
+
- con el túnel abierto, `curl -H 'ngrok-skip-browser-warning: 1' <url-ngrok>/` da 200 y `<url-ngrok>/api/...` responde el backend;
|
|
33
|
+
- si hay login, un login real por la URL de ngrok devuelve token y una ruta protegida responde con él;
|
|
34
|
+
- el script falla con mensaje claro si ya hay otro ngrok abierto y si el front no responde.
|
|
35
|
+
|
|
36
|
+
## Trampas
|
|
37
|
+
|
|
38
|
+
- **Host desconocido:** Vite (`server.allowedHosts`), Angular y webpack rechazan el dominio de ngrok. `--host-header=rewrite` lo resuelve sin tocar la configuración.
|
|
39
|
+
- **Un túnel por cuenta gratuita:** si hay otro abierto, ciérralo solo con permiso del usuario.
|
|
40
|
+
- **Aviso de ngrok:** el navegador ve una página intermedia la primera vez («Visit Site»); `curl` la salta con `ngrok-skip-browser-warning: 1`.
|
|
41
|
+
- **Micrófono, cámara o ubicación** necesitan HTTPS: ngrok lo da, la IP local por HTTP no.
|
|
42
|
+
- **Windows:** el script es bash para Git Bash; lánzalo con `bash ruta/al/script.sh`.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
skill: tunel-ngrok
|
|
2
|
+
|
|
3
|
+
should_trigger:
|
|
4
|
+
- prompt: "Quiero probar el front desde el movil sin desplegar."
|
|
5
|
+
why: "Disparador directo de tunel-ngrok."
|
|
6
|
+
- prompt: "Monta ngrok en este proyecto."
|
|
7
|
+
why: "Disparador directo de tunel-ngrok."
|
|
8
|
+
- prompt: "Necesito HTTPS en local para que el microfono funcione en el movil."
|
|
9
|
+
why: "Disparador directo de tunel-ngrok."
|
|
10
|
+
- prompt: "Open my local frontend on my phone through a public URL."
|
|
11
|
+
why: "Disparador directo de tunel-ngrok."
|
|
12
|
+
- prompt: "Comparte mi entorno local con una URL publica para ensenarselo a alguien."
|
|
13
|
+
why: "Disparador directo de tunel-ngrok."
|
|
14
|
+
|
|
15
|
+
should_not_trigger:
|
|
16
|
+
- prompt: "Despliega la app en produccion."
|
|
17
|
+
route_to: "deployment"
|
|
18
|
+
why: "Desplegar de verdad es el trabajo de deployment, no de tunel-ngrok."
|
|
19
|
+
- prompt: "Configura los registros DNS de mi dominio."
|
|
20
|
+
route_to: "domains-dns"
|
|
21
|
+
why: "El DNS de un dominio propio es el trabajo de domains-dns, no de tunel-ngrok."
|
|
22
|
+
- prompt: "Haz una auditoria de seguridad del producto."
|
|
23
|
+
route_to: "hardening"
|
|
24
|
+
why: "Auditar la seguridad es el trabajo de hardening, no de tunel-ngrok."
|
|
25
|
+
- prompt: "Configura el pipeline de CI para que pase los tests en cada push."
|
|
26
|
+
route_to: "github-actions"
|
|
27
|
+
why: "Montar la CI es el trabajo de github-actions, no de tunel-ngrok."
|
|
28
|
+
|
|
29
|
+
capability:
|
|
30
|
+
- scenario: "El usuario quiere abrir el front local en el movil."
|
|
31
|
+
must_include:
|
|
32
|
+
- "ngrok"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Front local en el móvil por un túnel de ngrok, sin desplegar nada. Un solo túnel al puerto del front:
|
|
3
|
+
# el front reenvía la API a su destino, así que todo va por el mismo origen y no hace falta CORS.
|
|
4
|
+
# ngrok da HTTPS, que el micrófono y la cámara exigen.
|
|
5
|
+
#
|
|
6
|
+
# bash scripts/dev/tunel-movil.sh # puerto por defecto (DEFAULT_PORT o FRONT_PORT)
|
|
7
|
+
# bash scripts/dev/tunel-movil.sh 5173 # otro puerto
|
|
8
|
+
#
|
|
9
|
+
# NGROK_DOMAIN (entorno o .env de la raíz) fija un dominio propio de ngrok. Ctrl+C cierra el túnel.
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
DEFAULT_PORT=5173 # AJUSTAR: el puerto del front del proyecto
|
|
13
|
+
PORT="${1:-${FRONT_PORT:-$DEFAULT_PORT}}"
|
|
14
|
+
INSPECT="http://127.0.0.1:4040"
|
|
15
|
+
ENV_FILE="${ENV_FILE:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/.env}"
|
|
16
|
+
|
|
17
|
+
fail() { echo "✗ $*" >&2; exit 1; }
|
|
18
|
+
|
|
19
|
+
command -v ngrok >/dev/null || fail "ngrok no está instalado: https://ngrok.com/download"
|
|
20
|
+
ngrok config check >/dev/null 2>&1 || fail "ngrok no tiene configuración válida: ngrok config add-authtoken <TOKEN>"
|
|
21
|
+
grep -q "authtoken" "$(ngrok config check 2>&1 | sed -n 's/.*file at //p')" 2>/dev/null \
|
|
22
|
+
|| fail "ngrok no tiene authtoken: ngrok config add-authtoken <TOKEN>"
|
|
23
|
+
|
|
24
|
+
curl -s -o /dev/null -m 3 "http://localhost:$PORT/" || fail "El front no responde en localhost:$PORT. Levántalo:
|
|
25
|
+
AJUSTAR: el comando que levanta el front del proyecto"
|
|
26
|
+
|
|
27
|
+
if curl -s -m 2 "$INSPECT/api/tunnels" >/dev/null 2>&1; then
|
|
28
|
+
fail "Ya hay otro ngrok abierto ($INSPECT). Ciérralo antes; el plan gratuito admite uno."
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
if [ -z "${NGROK_DOMAIN:-}" ] && [ -f "$ENV_FILE" ]; then
|
|
32
|
+
NGROK_DOMAIN="$(sed -n 's/^NGROK_DOMAIN=//p' "$ENV_FILE" | tr -d '"\r' | tail -n 1)"
|
|
33
|
+
fi
|
|
34
|
+
ARGS=(http "$PORT" --host-header=rewrite --log=stdout --log-level=warn)
|
|
35
|
+
[ -n "${NGROK_DOMAIN:-}" ] && ARGS+=("--url=https://$NGROK_DOMAIN")
|
|
36
|
+
|
|
37
|
+
ngrok "${ARGS[@]}" >/dev/null &
|
|
38
|
+
NGROK_PID=$!
|
|
39
|
+
trap 'kill "$NGROK_PID" 2>/dev/null; echo; echo "Túnel cerrado."' EXIT INT TERM
|
|
40
|
+
|
|
41
|
+
URL=""
|
|
42
|
+
for _ in $(seq 1 30); do
|
|
43
|
+
URL="$(curl -s -m 2 "$INSPECT/api/tunnels" 2>/dev/null | grep -o '"public_url":"https://[^"]*' | head -n 1 | cut -d'"' -f4 || true)"
|
|
44
|
+
[ -n "$URL" ] && break
|
|
45
|
+
kill -0 "$NGROK_PID" 2>/dev/null || fail "ngrok se cerró al arrancar; lánzalo a mano para ver el error: ngrok ${ARGS[*]}"
|
|
46
|
+
sleep 1
|
|
47
|
+
done
|
|
48
|
+
[ -n "$URL" ] || fail "ngrok no dio una dirección pública en 30 s."
|
|
49
|
+
|
|
50
|
+
echo "✓ En el móvil: $URL"
|
|
51
|
+
echo " La primera vez ngrok enseña un aviso: pulsa «Visit Site». Ctrl+C para cerrar."
|
|
52
|
+
wait "$NGROK_PID"
|
package/targets/claude.js
CHANGED
|
@@ -14,7 +14,6 @@ const SHELL_TOOLS = 'Bash|PowerShell';
|
|
|
14
14
|
export const CLAUDE_CODE_MODS = Object.freeze([
|
|
15
15
|
{ id: 'skins@hellosverre-mods', marketplace: 'hellosverre-mods', repo: 'hellosverre/claude-skins' },
|
|
16
16
|
{ id: 'savvy-progress@claude-kit', marketplace: 'claude-kit', repo: 'johnnyvizz/claude-kit' },
|
|
17
|
-
{ id: 'filetree@claude-code-filetree', marketplace: 'claude-code-filetree', repo: 'data-goblin/claude-code-filetree' },
|
|
18
17
|
{ id: 'cache-tax@claude-code-mods', marketplace: 'claude-code-mods', repo: 'karanb192/claude-code-mods' },
|
|
19
18
|
]);
|
|
20
19
|
|