create-harness-btp 0.2.4 → 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.
Files changed (81) hide show
  1. package/AI/VERSION +1 -1
  2. package/AI/agents/analyst.md +30 -0
  3. package/AI/agents/architect.md +29 -0
  4. package/AI/agents/backend-cap.md +19 -0
  5. package/AI/agents/deploy-cf.md +26 -0
  6. package/AI/agents/documentarian.md +20 -0
  7. package/AI/agents/e2e-fiori.md +62 -0
  8. package/AI/agents/frontend-ui5.md +20 -0
  9. package/AI/agents/harness-evolution.md +38 -0
  10. package/AI/agents/orchestrator.md +41 -0
  11. package/AI/agents/qa-review.md +28 -0
  12. package/AI/agents/researcher.md +29 -0
  13. package/AI/clients/claude/agents/analyst.md +22 -0
  14. package/AI/clients/claude/agents/architect.md +21 -0
  15. package/AI/clients/claude/agents/backend-cap.md +18 -0
  16. package/AI/clients/claude/agents/deploy-cf.md +25 -0
  17. package/AI/clients/claude/agents/documentarian.md +15 -0
  18. package/AI/clients/claude/agents/e2e-fiori.md +61 -0
  19. package/AI/clients/claude/agents/frontend-ui5.md +19 -0
  20. package/AI/clients/claude/agents/harness-evolution.md +37 -0
  21. package/AI/clients/claude/agents/orchestrator.md +40 -0
  22. package/AI/clients/claude/agents/qa-review.md +27 -0
  23. package/AI/clients/claude/agents/researcher.md +21 -0
  24. package/AI/clients/claude/commands/flow.md +16 -0
  25. package/AI/clients/claude/commands/verify.md +18 -0
  26. package/AI/clients/claude/skills/cap-cli/SKILL.md +21 -0
  27. package/AI/clients/claude/skills/cf-cli/SKILL.md +41 -0
  28. package/AI/clients/claude/skills/mta-build/SKILL.md +45 -0
  29. package/AI/clients/claude/skills/sap-verify/SKILL.md +27 -0
  30. package/AI/clients/copilot/agents/analyst.agent.md +22 -0
  31. package/AI/clients/copilot/agents/architect.agent.md +21 -0
  32. package/AI/clients/copilot/agents/backend-cap.agent.md +18 -0
  33. package/AI/clients/copilot/agents/deploy-cf.agent.md +25 -0
  34. package/AI/clients/copilot/agents/documentarian.agent.md +15 -0
  35. package/AI/clients/copilot/agents/e2e-fiori.agent.md +61 -0
  36. package/AI/clients/copilot/agents/frontend-ui5.agent.md +19 -0
  37. package/AI/clients/copilot/agents/harness-evolution.agent.md +37 -0
  38. package/AI/clients/copilot/agents/orchestrator.agent.md +40 -0
  39. package/AI/clients/copilot/agents/qa-review.agent.md +27 -0
  40. package/AI/clients/copilot/agents/researcher.agent.md +21 -0
  41. package/AI/clients/copilot/prompts/flow.prompt.md +16 -0
  42. package/AI/clients/copilot/prompts/verify.prompt.md +18 -0
  43. package/AI/clients/copilot/skills/cap-cli/SKILL.md +21 -0
  44. package/AI/clients/copilot/skills/cf-cli/SKILL.md +41 -0
  45. package/AI/clients/copilot/skills/mta-build/SKILL.md +45 -0
  46. package/AI/clients/copilot/skills/sap-verify/SKILL.md +27 -0
  47. package/AI/clients/cursor/commands/flow.md +12 -0
  48. package/AI/clients/cursor/commands/verify.md +14 -0
  49. package/AI/clients/cursor/skills/cap-cli/SKILL.md +21 -0
  50. package/AI/clients/cursor/skills/cf-cli/SKILL.md +41 -0
  51. package/AI/clients/cursor/skills/mta-build/SKILL.md +45 -0
  52. package/AI/clients/cursor/skills/sap-verify/SKILL.md +27 -0
  53. package/AI/clients/opencode/agents/analyst.md +29 -0
  54. package/AI/clients/opencode/agents/architect.md +28 -0
  55. package/AI/clients/opencode/agents/backend-cap.md +18 -0
  56. package/AI/clients/opencode/agents/deploy-cf.md +25 -0
  57. package/AI/clients/opencode/agents/documentarian.md +19 -0
  58. package/AI/clients/opencode/agents/e2e-fiori.md +61 -0
  59. package/AI/clients/opencode/agents/frontend-ui5.md +19 -0
  60. package/AI/clients/opencode/agents/harness-evolution.md +37 -0
  61. package/AI/clients/opencode/agents/orchestrator.md +40 -0
  62. package/AI/clients/opencode/agents/qa-review.md +27 -0
  63. package/AI/clients/opencode/agents/researcher.md +28 -0
  64. package/AI/clients/opencode/commands/flow.md +16 -0
  65. package/AI/clients/opencode/commands/verify.md +18 -0
  66. package/AI/clients/opencode/skills/cap-cli/SKILL.md +21 -0
  67. package/AI/clients/opencode/skills/cf-cli/SKILL.md +41 -0
  68. package/AI/clients/opencode/skills/mta-build/SKILL.md +45 -0
  69. package/AI/clients/opencode/skills/sap-verify/SKILL.md +27 -0
  70. package/AI/commands/flow.md +16 -0
  71. package/AI/commands/verify.md +18 -0
  72. package/AI/skills/cap-cli/SKILL.md +21 -0
  73. package/AI/skills/cf-cli/SKILL.md +41 -0
  74. package/AI/skills/mta-build/SKILL.md +45 -0
  75. package/AI/skills/sap-verify/SKILL.md +27 -0
  76. package/README.md +54 -16
  77. package/VERSION +1 -1
  78. package/bin/harness-btp.js +87 -3
  79. package/install.ps1 +85 -2
  80. package/install.sh +95 -5
  81. package/package.json +1 -1
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: cf-cli
3
+ description: Uso estándar del CLI de Cloud Foundry (cf)
4
+ ---
5
+
6
+ # CLI Cloud Foundry (`cf`)
7
+
8
+ El CLI de Cloud Foundry se invoca **siempre** como `cf` (instalación
9
+ estándar del CLI; adapta rutas según tu equipo). Si `cf` en tu máquina
10
+ corresponde a otra herramienta, define un alias propio y úsalo de forma
11
+ consistente donde el harness diga `cf`.
12
+
13
+ ## Lectura segura (sin secretos)
14
+
15
+ ```
16
+ cf target # endpoint / org / espacio actuales
17
+ cf api # endpoint y versión API
18
+ cf orgs # solo nombres
19
+ cf spaces # solo nombres
20
+ cf apps # estado observable (started/stopped, rutas)
21
+ cf services # instancias visibles
22
+ cf logs <app> --recent
23
+ ```
24
+
25
+ `target`, `api`, `orgs`, `spaces` y `app <nombre>` nunca muestran tokens.
26
+ Si una salida incluyera un secreto, redáctalo antes de citarla.
27
+
28
+ ## Mutaciones (solo `deploy-cf`, con destino confirmado)
29
+
30
+ - Confirmar endpoint/org/espacio contra la spec **antes** de cada despliegue.
31
+ - `cf push` para apps simples; `cf deploy <archivo>.mtar` para MTA
32
+ (requiere plugin `multiapps`, no instalado: ver skill `mta-build`).
33
+ - Verificar después: `cf apps` + `cf logs <app> --recent` + URL.
34
+
35
+ ## Denylist
36
+
37
+ - Borrar o renombrar orgs, espacios, apps o servicios fuera del MVP.
38
+ - `cf login`/re-autenticaciones no solicitadas (si la sesión caduca,
39
+ pedir al usuario el flujo interactivo, nunca credenciales en texto).
40
+ - `--var`/`--vars-file` con secretos en shell compartida; usar archivos ya
41
+ ignorados por Git y no citar sus valores.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: mta-build
3
+ description: Construir y verificar artefactos MTAR con mbt en este equipo
4
+ ---
5
+
6
+ # Build MTA (`mbt`)
7
+
8
+ `mbt` es Cloud MTA Build Tool 1.2.50 (verificado 2026-10-29). Invocarlo
9
+ siempre como `mbt`, nunca como `cf` ni rutas inventadas.
10
+
11
+ ## Flujo
12
+
13
+ ```
14
+ mbt build # requiere mta.yaml en la raíz del proyecto
15
+ ```
16
+
17
+ - El `.mtar` resultante queda en `mta_archives/` con el nombre/versión de
18
+ `mta.yaml`. Comprobar existencia y fecha antes de desplegar.
19
+ - Para módulos Node.js, `mbt` ejecuta `npm install`/`npm run build` según
20
+ `mta.yaml`; para Java necesita Maven (`mvn` no instalado: documentar como
21
+ pendiente si una spec lo exige).
22
+ - `mbt build --help` para flags (`--mtar`, `--platform=cf`).
23
+
24
+ ## Despliegue del MTAR
25
+
26
+ `cf deploy <archivo>.mtar` requiere el **plugin multiapps**. Verificar
27
+ siempre con `cf plugins` antes de asumir su ausencia (2026-10-30 resultó
28
+ ya instalado contra lo documentado). Instalarlo solo cuando un MVP necesite
29
+ despliegue MTA:
30
+
31
+ ```
32
+ cf install-plugin -r CF-Community multiapps
33
+ ```
34
+
35
+ Alternativa sin plugin para MVPs simples: `cf push` por app según plan.
36
+
37
+ ## Notas
38
+
39
+ - El binario `mbt.exe` se obtuvo con el propio `install.js` del paquete npm
40
+ (`node install.js cloud-mta-build-tool`). Si `mbt` vuelve a fallar tras
41
+ una actualización global, repetir ese comando en el directorio del paquete.
42
+ - Nunca versionar `mta_archives/*.mtar` ni `default-services.json` con claves.
43
+ - `mbt` exige `make` en `%PATH%` (ver `AGENTS.md` § Disciplina de shell y
44
+ CLIs): si falla `exec: "make": executable file not found`, anteponer el
45
+ `bin` de ezwinports/GnuWin32 al `$env:PATH` solo para el comando.
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: sap-verify
3
+ description: Clasificar disponibilidad, cuenta y coste de servicios SAP/BTP
4
+ ---
5
+
6
+ # Verificación de dependencias externas SAP
7
+
8
+ Toda afirmación sobre un servicio, plan, API o capacidad BTP se clasifica en
9
+ una de estas categorías, con fuente y fecha:
10
+
11
+ | Categoría | Significado |
12
+ |---|---|
13
+ | **Documentado** | Docs oficiales vigentes + evidencia (comando, consola o enlace con fecha). |
14
+ | **Pendiente en cuenta** | Existe en docs pero sin comprobar en la subcuenta/destino real. |
15
+ | **Coste por cotizar** | Requiere plan de pago o métrica no verificada; no activar sin confirmación. |
16
+
17
+ ## Reglas
18
+
19
+ - Desarrollo local y mocks primero; servicios reales solo con evidencia.
20
+ - Distinguir Windows local frente a BAS/dev space remoto: una instalación o
21
+ capacidad de un lado no implica la del otro.
22
+ - No afirmar que una integración está aprobada o disponible hasta comprobarla
23
+ con documentación y accesos vigentes.
24
+ - Costes: antes de activar cualquier recurso con coste, verificar precio y
25
+ documentarlo en la spec; capa gratuita por defecto.
26
+ - Bloqueos externos no paran el MVP: documentar evidencia y continuar con
27
+ mocks o adaptador local.
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Ciclo completo spec-despliegue de un MVP SAP BTP
3
+ agent: orchestrator
4
+ ---
5
+
6
+ Ejecuta el flujo sobre la especificación: $ARGUMENTS
7
+ (p. ej. `/flow specs/mi-mvp.md`).
8
+
9
+ El orquestador recorre las etapas 0–10 de `AGENTS.md` con los especialistas
10
+ adecuados (`analyst`, `researcher`, `architect`, `frontend-ui5`,
11
+ `backend-cap`, `qa-review`, `deploy-cf`, `documentarian`). En MVPs pequeños
12
+ puede saltar etapas irrelevantes y registrarlo; ningún riesgo o
13
+ incertidumbre bloquea por sí solo: se investiga, se decide con evidencia y
14
+ se continúa con lo resoluble. La puerta de despliegue (etapa 7) es
15
+ obligatoria antes de desplegar. Al cerrar: qué se hizo, verificaciones con
16
+ comandos y resultado real, y qué quedó pendiente y por qué.
@@ -0,0 +1,18 @@
1
+ ---
2
+ description: Puerta de despliegue CF sin desplegar
3
+ agent: orchestrator
4
+ ---
5
+
6
+ Ejecuta solo la puerta de despliegue (etapa 7) para $ARGUMENTS
7
+ (spec o nombre de app; si se omite, el MVP en curso).
8
+
9
+ Verificaciones (delegables en `qa-review` + `deploy-cf` en solo lectura):
10
+
11
+ 1. `cf target` coincide con el destino de la spec (endpoint/org/espacio).
12
+ 2. El artefacto existe y es reciente (`.mtar` en `mta_archives/` o bundle
13
+ para `push`).
14
+ 3. Todos los criterios de aceptación están en verde con evidencia.
15
+ 4. Diff/Git sin secretos ni archivos que debieran estar ignorados.
16
+
17
+ Veredicto: apto / no apto con motivos concretos. Este comando nunca
18
+ despliega ni muta nada en Cloud Foundry.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: cap-cli
3
+ description: Invocación verificada del CLI de CAP y facets en este equipo
4
+ ---
5
+
6
+ # CLI de CAP (`cds`)
7
+
8
+ Nombres verificados el 2026-10-29 (docs cap.cloud.sap vía `context7`;
9
+ paquete `@cap-js/cds-dk` **no existe** — el correcto es `@sap/cds-dk`):
10
+
11
+ - CLI solo vía `npx -p @sap/cds-dk cds ...` (el `node_modules` del proyecto
12
+ no incluye el ejecutable `cds`; `npx cds` a secas falla).
13
+ - Runtime del proyecto: `@sap/cds` v10 + `@cap-js/sqlite` v3 (SQLite solo
14
+ para dev local; sin persistencia en CF).
15
+ - Scaffold: `npx -p @sap/cds-dk cds init <nombre> --nodejs` (no global).
16
+ - Facets usadas en este harness: `mta xsuaa approuter html5-repo
17
+ destination ui5` (lista completa real con `cds add --help`, no de memoria).
18
+ - Tras `cds add`, siempre `npm install` antes del siguiente comando.
19
+ - `cds add` es aditivo y genera `mta.yaml`/`xs-security.json`: revisar el
20
+ diff antes de aceptar lo generado (nombres de instancia deben coincidir
21
+ con las existentes en la subcuenta).
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: cf-cli
3
+ description: Uso estándar del CLI de Cloud Foundry (cf)
4
+ ---
5
+
6
+ # CLI Cloud Foundry (`cf`)
7
+
8
+ El CLI de Cloud Foundry se invoca **siempre** como `cf` (instalación
9
+ estándar del CLI; adapta rutas según tu equipo). Si `cf` en tu máquina
10
+ corresponde a otra herramienta, define un alias propio y úsalo de forma
11
+ consistente donde el harness diga `cf`.
12
+
13
+ ## Lectura segura (sin secretos)
14
+
15
+ ```
16
+ cf target # endpoint / org / espacio actuales
17
+ cf api # endpoint y versión API
18
+ cf orgs # solo nombres
19
+ cf spaces # solo nombres
20
+ cf apps # estado observable (started/stopped, rutas)
21
+ cf services # instancias visibles
22
+ cf logs <app> --recent
23
+ ```
24
+
25
+ `target`, `api`, `orgs`, `spaces` y `app <nombre>` nunca muestran tokens.
26
+ Si una salida incluyera un secreto, redáctalo antes de citarla.
27
+
28
+ ## Mutaciones (solo `deploy-cf`, con destino confirmado)
29
+
30
+ - Confirmar endpoint/org/espacio contra la spec **antes** de cada despliegue.
31
+ - `cf push` para apps simples; `cf deploy <archivo>.mtar` para MTA
32
+ (requiere plugin `multiapps`, no instalado: ver skill `mta-build`).
33
+ - Verificar después: `cf apps` + `cf logs <app> --recent` + URL.
34
+
35
+ ## Denylist
36
+
37
+ - Borrar o renombrar orgs, espacios, apps o servicios fuera del MVP.
38
+ - `cf login`/re-autenticaciones no solicitadas (si la sesión caduca,
39
+ pedir al usuario el flujo interactivo, nunca credenciales en texto).
40
+ - `--var`/`--vars-file` con secretos en shell compartida; usar archivos ya
41
+ ignorados por Git y no citar sus valores.
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: mta-build
3
+ description: Construir y verificar artefactos MTAR con mbt en este equipo
4
+ ---
5
+
6
+ # Build MTA (`mbt`)
7
+
8
+ `mbt` es Cloud MTA Build Tool 1.2.50 (verificado 2026-10-29). Invocarlo
9
+ siempre como `mbt`, nunca como `cf` ni rutas inventadas.
10
+
11
+ ## Flujo
12
+
13
+ ```
14
+ mbt build # requiere mta.yaml en la raíz del proyecto
15
+ ```
16
+
17
+ - El `.mtar` resultante queda en `mta_archives/` con el nombre/versión de
18
+ `mta.yaml`. Comprobar existencia y fecha antes de desplegar.
19
+ - Para módulos Node.js, `mbt` ejecuta `npm install`/`npm run build` según
20
+ `mta.yaml`; para Java necesita Maven (`mvn` no instalado: documentar como
21
+ pendiente si una spec lo exige).
22
+ - `mbt build --help` para flags (`--mtar`, `--platform=cf`).
23
+
24
+ ## Despliegue del MTAR
25
+
26
+ `cf deploy <archivo>.mtar` requiere el **plugin multiapps**. Verificar
27
+ siempre con `cf plugins` antes de asumir su ausencia (2026-10-30 resultó
28
+ ya instalado contra lo documentado). Instalarlo solo cuando un MVP necesite
29
+ despliegue MTA:
30
+
31
+ ```
32
+ cf install-plugin -r CF-Community multiapps
33
+ ```
34
+
35
+ Alternativa sin plugin para MVPs simples: `cf push` por app según plan.
36
+
37
+ ## Notas
38
+
39
+ - El binario `mbt.exe` se obtuvo con el propio `install.js` del paquete npm
40
+ (`node install.js cloud-mta-build-tool`). Si `mbt` vuelve a fallar tras
41
+ una actualización global, repetir ese comando en el directorio del paquete.
42
+ - Nunca versionar `mta_archives/*.mtar` ni `default-services.json` con claves.
43
+ - `mbt` exige `make` en `%PATH%` (ver `AGENTS.md` § Disciplina de shell y
44
+ CLIs): si falla `exec: "make": executable file not found`, anteponer el
45
+ `bin` de ezwinports/GnuWin32 al `$env:PATH` solo para el comando.
@@ -0,0 +1,27 @@
1
+ ---
2
+ name: sap-verify
3
+ description: Clasificar disponibilidad, cuenta y coste de servicios SAP/BTP
4
+ ---
5
+
6
+ # Verificación de dependencias externas SAP
7
+
8
+ Toda afirmación sobre un servicio, plan, API o capacidad BTP se clasifica en
9
+ una de estas categorías, con fuente y fecha:
10
+
11
+ | Categoría | Significado |
12
+ |---|---|
13
+ | **Documentado** | Docs oficiales vigentes + evidencia (comando, consola o enlace con fecha). |
14
+ | **Pendiente en cuenta** | Existe en docs pero sin comprobar en la subcuenta/destino real. |
15
+ | **Coste por cotizar** | Requiere plan de pago o métrica no verificada; no activar sin confirmación. |
16
+
17
+ ## Reglas
18
+
19
+ - Desarrollo local y mocks primero; servicios reales solo con evidencia.
20
+ - Distinguir Windows local frente a BAS/dev space remoto: una instalación o
21
+ capacidad de un lado no implica la del otro.
22
+ - No afirmar que una integración está aprobada o disponible hasta comprobarla
23
+ con documentación y accesos vigentes.
24
+ - Costes: antes de activar cualquier recurso con coste, verificar precio y
25
+ documentarlo en la spec; capa gratuita por defecto.
26
+ - Bloqueos externos no paran el MVP: documentar evidencia y continuar con
27
+ mocks o adaptador local.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # harness-btp
2
2
 
3
- [![version](https://img.shields.io/badge/version-v0.2.4-blue)](https://github.com/horangelmillan/harness-btp/releases/tag/v0.2.4)
3
+ [![version](https://img.shields.io/badge/version-v0.3.0-blue)](https://github.com/horangelmillan/harness-btp/releases/tag/v0.3.0)
4
4
  [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
5
5
  [![platform](https://img.shields.io/badge/platform-windows%20%7C%20linux%20%7C%20macos-lightgrey)](https://github.com/horangelmillan/harness-btp)
6
6
  [![agent](https://img.shields.io/badge/agent-any%20AGENTS.md--compatible-purple)](https://github.com/horangelmillan/harness-btp)
@@ -18,6 +18,7 @@ Para quien construye MVPs SAP BTP y quiere empezar cada proyecto con el mismo fl
18
18
  - [Instalación asistida por agente](#instalación-asistida-por-agente)
19
19
  - [Actualizar y desinstalar](#actualizar-y-desinstalar)
20
20
  - [Adaptadores opcionales](#adaptadores-opcionales)
21
+ - [Multi-cliente](#multi-cliente)
21
22
  - [Estructura del repo](#estructura-del-repo)
22
23
  - [Cómo lo descubre el agente](#cómo-lo-descubre-el-agente)
23
24
  - [Troubleshooting](#troubleshooting)
@@ -55,7 +56,7 @@ El camino de 30 segundos en un proyecto nuevo. Elige tu shell:
55
56
  PowerShell (Windows):
56
57
 
57
58
  ```powershell
58
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
59
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
59
60
  powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
60
61
  Remove-Item -Recurse -Force AI-tmp
61
62
  ```
@@ -63,7 +64,7 @@ Remove-Item -Recurse -Force AI-tmp
63
64
  bash (Linux, macOS o Git Bash):
64
65
 
65
66
  ```bash
66
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
67
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
67
68
  sh AI-tmp/install.sh --dest .
68
69
  rm -rf AI-tmp
69
70
  ```
@@ -79,7 +80,7 @@ Descarga solo lo necesario, sin historial git:
79
80
  PowerShell:
80
81
 
81
82
  ```powershell
82
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
83
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
83
84
  powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
84
85
  Remove-Item -Recurse -Force AI-tmp
85
86
  ```
@@ -87,7 +88,7 @@ Remove-Item -Recurse -Force AI-tmp
87
88
  bash:
88
89
 
89
90
  ```bash
90
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
91
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
91
92
  sh AI-tmp/install.sh --dest .
92
93
  rm -rf AI-tmp
93
94
  ```
@@ -99,7 +100,7 @@ Clon superficial anclado al tag:
99
100
  PowerShell:
100
101
 
101
102
  ```powershell
102
- git clone --branch v0.2.4 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
103
+ git clone --branch v0.3.0 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
103
104
  powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
104
105
  Remove-Item -Recurse -Force AI-tmp
105
106
  ```
@@ -107,7 +108,7 @@ Remove-Item -Recurse -Force AI-tmp
107
108
  bash:
108
109
 
109
110
  ```bash
110
- git clone --branch v0.2.4 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
111
+ git clone --branch v0.3.0 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
111
112
  sh AI-tmp/install.sh --dest .
112
113
  rm -rf AI-tmp
113
114
  ```
@@ -117,22 +118,25 @@ rm -rf AI-tmp
117
118
  Sin descargas manuales (requiere publicar `create-harness-btp` en el registry). Igual en todos los SO:
118
119
 
119
120
  ```bash
120
- pnpm dlx create-harness-btp@0.2.4 --dest .
121
+ pnpm dlx create-harness-btp@0.3.0 --dest .
121
122
  ```
122
123
 
123
124
  ### Qué hace el instalador
124
125
 
125
126
  - `CREATE: AI/` o `SKIP: AI/ ya existe` (solo lo reemplaza con `-Force` / `--force`, con backup a `AI.bak`).
126
127
  - `CREATE: AGENTS.md` o `SKIP: AGENTS.md ya existe` (tu `AGENTS.md` propio se conserva; con `-Force` / `--force` se respalda a `AGENTS.md.bak`).
128
+ - Fusiona el árbol del cliente agéntico (`--client`, por defecto `auto`) desde `AI/clients/<cliente>/` en la raíz (ver [Multi-cliente](#multi-cliente)): sin fuerza solo copia los archivos que falten (`SKIP: <dir>/<ruta> ya existe` por cada uno conservado); con `-Force` / `--force` respalda cada dir a `<dir>.bak` (`BACKUP: <dir>/ -> <dir>.bak`) y copia todo.
127
129
  - Fusiona `.gitignore`: añade las líneas que falten, sin duplicar ni borrar las tuyas.
128
130
  - **No toca** `package.json` ni `mta.yaml` de tu proyecto, nunca.
129
131
 
130
132
  Salida típica en proyecto nuevo:
131
133
 
132
134
  ```text
133
- CREATE: AI/
135
+ CREATE: AI/ (v0.3.0)
134
136
  CREATE: AGENTS.md
135
- OK: harness v0.2.4 instalado
137
+ CLIENT: auto -> opencode
138
+ CREATE: .opencode/ (+17 archivos)
139
+ OK: harness v0.3.0 instalado
136
140
  ```
137
141
 
138
142
  ## Instalación asistida por agente
@@ -152,7 +156,7 @@ Vale para proyecto nuevo (con URL), existente, Windows/Linux/macOS y cualquier c
152
156
  PowerShell:
153
157
 
154
158
  ```powershell
155
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
159
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
156
160
  powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest . -Force
157
161
  Remove-Item -Recurse -Force AI-tmp
158
162
  # tu versión anterior queda en AI.bak por si quieres comparar
@@ -161,7 +165,7 @@ Remove-Item -Recurse -Force AI-tmp
161
165
  bash:
162
166
 
163
167
  ```bash
164
- npx -p degit degit horangelmillan/harness-btp#v0.2.4 AI-tmp -- AI-tmp
168
+ npx -p degit degit horangelmillan/harness-btp#v0.3.0 AI-tmp -- AI-tmp
165
169
  sh AI-tmp/install.sh --dest . --force
166
170
  rm -rf AI-tmp
167
171
  # tu versión anterior queda en AI.bak por si quieres comparar
@@ -192,9 +196,32 @@ El harness funciona con **cualquier** cliente agéntico que lea `AGENTS.md`. Est
192
196
  - **`AI/.opencode/`** — agentes, comandos y skills de ejemplo con el layout de OpenCode. Si tu cliente usa otro layout, ignóralos o adaptalos: el flujo vive en `AI/AGENTS.md`, `AI/INICIO.md`, `AI/docs/` y `AI/scripts/`, que son Markdown + shell portátil.
193
197
  - **`AI/opencode.fragment.jsonc`** — fragmento de ejemplo para fusionar en tu `opencode.jsonc` (p. ej. el bloque MCP `graphify-code`, deshabilitado por defecto). Solo aplica a OpenCode; otros clientes lo ignoran sin efecto.
194
198
  - **`install.ps1` / `install.sh`** — elige el de tu shell; ambos aplican la misma lógica idempotente. Los scripts de `AI/scripts/` también vienen en par `.ps1` / `.sh`.
199
+ - **Multi-cliente:** desde v0.3.0 la fuente única es `AI/agents/`, `AI/commands/`, `AI/skills/` y cada cliente recibe su árbol renderizado en `AI/clients/<cliente>/` (ver [Multi-cliente](#multi-cliente)). `AI/.opencode/` se conserva intacto por compatibilidad.
195
200
 
196
201
  Nada del núcleo exige OpenCode, Windows ni ningún modelo concreto.
197
202
 
203
+ ## Multi-cliente
204
+
205
+ El harness se configura para el cliente agéntico de turno desde UNA sola definición canónica:
206
+
207
+ - **Canónico (`AI/`):** `AI/agents/*.md` (11 agentes), `AI/commands/*.md` (`flow`, `verify`), `AI/skills/*/SKILL.md` (4 skills). Es la única fuente que se edita a mano.
208
+ - **Render (`AI/clients/`):** generado con `node scripts/render-clients.js` (sin dependencias); `node scripts/render-clients.js --check` solo verifica. El CI lo exige en verde antes de publicar (ver `.github/workflows/publish.yml`). No edites `AI/clients/` a mano: tus cambios se pierden en el próximo render.
209
+
210
+ | Cliente | `--client` | Rutas generadas en la raíz | Adaptación |
211
+ |---|---|---|---|
212
+ | OpenCode | `opencode` | `.opencode/agents/`, `.opencode/commands/`, `.opencode/skills/` | copia exacta de `AI/.opencode/` |
213
+ | Claude Code | `claude` | `.claude/agents/`, `.claude/commands/`, `.claude/skills/` | agents con `{name,description}` (sin `mode`) |
214
+ | Cursor | `cursor` | `.cursor/commands/`, `.agents/skills/` | commands sin frontmatter (solo cuerpo) |
215
+ | Copilot | `copilot` | `.github/agents/*.agent.md`, `.github/prompts/*.prompt.md`, `.github/skills/` | renombrados a su convención |
216
+ | Aider (y genéricos) | `aider` | nada que generar | usan el `AGENTS.md` raíz |
217
+
218
+ Flag `--client` en `install.ps1` (`-Client`), `install.sh` y `bin/harness-btp.js`:
219
+
220
+ - `auto` (defecto): detecta por huellas (`CLAUDE.md`/`.claude`→claude, `.cursor`→cursor, `.github`→copilot, `opencode.json*`/`.opencode`→opencode); sin huellas usa opencode por compatibilidad histórica. Si hay huellas de varios clientes, fusiona los detectados.
221
+ - `all`: fusiona los cuatro árboles.
222
+ - Lista explícita (`-Client claude,cursor` / `--client claude,cursor`): solo esos.
223
+ - Fusión idempotente con mensajes `CREATE:`/`SKIP:` por archivo y `BACKUP` a `<dir>.bak` con fuerza (mismo patrón que `AI/`).
224
+
198
225
  ## Estructura del repo
199
226
 
200
227
  ```text
@@ -202,18 +229,24 @@ harness-btp/
202
229
  ├── AI/ # lo que queda instalado en tu proyecto
203
230
  │ ├── AGENTS.md # reglas del harness (parametrizado, sin rutas absolutas)
204
231
  │ ├── INICIO.md # punto de entrada para el agente
232
+ │ ├── agents/ # CANÓNICO: 11 agentes (única fuente, se edita a mano)
233
+ │ ├── commands/ # CANÓNICO: flow + verify (única fuente)
234
+ │ ├── skills/ # CANÓNICO: 4 skills (única fuente)
235
+ │ ├── clients/ # RENDERIZADO por scripts/render-clients.js (no editar a mano)
205
236
  │ ├── opencode.fragment.jsonc# ADAPTER opcional: ejemplo para opencode.jsonc
206
- │ ├── .opencode/ # ADAPTER opcional: agents + commands + skills de ejemplo
237
+ │ ├── .opencode/ # ADAPTER opcional: se conserva intacto (compatibilidad)
207
238
  │ ├── scripts/ # pares .ps1 / .sh + provision-espacio.template.ps1
208
239
  │ ├── docs/ # flujo-etapas, cf-safe, habilitacion-trial
209
240
  │ ├── specs/ # plantilla _template.md
210
241
  │ └── .gitignore.fragment # líneas a fusionar en tu .gitignore
242
+ ├── scripts/
243
+ │ └── render-clients.js # genera AI/clients/ desde el canónico (--check en CI)
211
244
  ├── templates/
212
245
  │ └── AGENTS.pointer.md # plantilla del puntero AGENTS.md raíz
213
246
  ├── install.ps1 / install.sh # instaladores idempotentes (SKIP / CREATE / BACKUP / OK)
214
247
  ├── bin/ # ejecutable de create-harness-btp (pnpm dlx)
215
248
  ├── package.json # name create-harness-btp
216
- └── VERSION # 0.2.4
249
+ └── VERSION # 0.3.0
217
250
  ```
218
251
 
219
252
  ## Cómo lo descubre el agente
@@ -230,12 +263,14 @@ Tú no configuras nada: el agente se adapta solo.
230
263
  | Problema | Causa | Comando |
231
264
  |---|---|---|
232
265
  | `SKIP: AI/ ya existe` y quería actualizar | reinstalación sin fuerza conserva lo existente | repite con `-Force` (`.ps1`) o `--force` (`.sh`); guarda `AI.bak` |
266
+ | No aparece `orchestrator` / no existe `/flow` | fusión a `.opencode/` raíz ausente (OpenCode solo descubre `.opencode/` en la raíz del proyecto, no `AI/.opencode/`) | reinstala sin fuerza (copia solo faltantes) o copia `AI/.opencode/` a `.opencode/` en la raíz sin pisar archivos propios |
233
267
  | Mi `AGENTS.md` propio desapareció | se instaló con fuerza | recupera `AGENTS.md.bak` |
234
268
  | Líneas duplicadas en `.gitignore` | edición manual tras la fusión | el instalador fusiona sin duplicar; borra el duplicado a mano |
235
269
  | `ExecutionPolicy` bloquea `install.ps1` | política de PowerShell | `powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .` (o usa `install.sh` en Git Bash) |
236
270
  | `ABORT: opción desconocida` en `install.sh` | flag inexistente | `sh install.sh --help` lista `--dest`, `--force` |
237
- | `degit` falla sin Node | `degit` corre sobre Node 18+ | instala Node o usa `git clone --branch v0.2.4` |
271
+ | `degit` falla sin Node | `degit` corre sobre Node 18+ | instala Node o usa `git clone --branch v0.3.0` |
238
272
  | Tu cliente no lee los agentes de `.opencode/` | layout específico de OpenCode | son un adapter opcional; el flujo está en `AI/AGENTS.md` + `AI/INICIO.md` |
273
+ | Mi cliente no ve los agentes (claude/cursor/copilot) | instalaste sin el `--client` que usa tu proyecto (`auto` no encontró sus huellas) | reinstala sin fuerza con `--client <tu-cliente>` (p. ej. `--client claude`) y verifica la tabla de [Multi-cliente](#multi-cliente): `.claude/`, `.cursor/commands/` + `.agents/skills/`, o `.github/agents\|prompts\|skills` según cliente; si sigue sin verlos, revisa la fusión y no dupliques archivos a mano |
239
274
  | No se deja borrar la carpeta del proyecto ("Carpeta en uso") | procesos huérfanos parados dentro (shells/MCPs de una sesión ya cerrada) | resmon → CPU → Identificadores asociados → busca la carpeta y termina solo esos PIDs; nunca fueron del instalador (solo copia archivos y termina) |
240
275
 
241
276
  ## Compatibilidad
@@ -262,8 +297,11 @@ MIT. Haz lo que quieras con el harness; sin garantía.
262
297
 
263
298
  ## Changelog
264
299
 
300
+ - **v0.3.0** — multi-cliente: definición canónica única en `AI/agents/`, `AI/commands/`, `AI/skills/`; render a `AI/clients/<cliente>/` con `scripts/render-clients.js` (opencode byte-idéntico a `AI/.opencode/`, que se conserva intacto); instaladores con flag `--client auto|all|<lista>` (detección por huellas, fusión idempotente con `SKIP`/`BACKUP` por dir); `prompts/setup.md` pregunta el cliente si es ambiguo y verifica adopción por cliente; CI exige `render-clients.js --check` antes de la guardia de versiones.
301
+
302
+ - **v0.3.0** — fusión a `.opencode/` raíz: el instalador sincroniza `AI/.opencode/` (agents + commands + skills) en `.opencode/` del proyecto para que OpenCode descubra `orchestrator` y `/flow` (SKIP sin fuerza, `.opencode.bak` con fuerza); `prompts/setup.md` verifica adopción y fusiona el fragmento MCP.
265
303
  - **v0.2.4** — estilo Neon: una línea que lee `prompts/setup.md` (versionado, siempre al día) en vez de un bloque que caduca.
266
304
  - **v0.2.3** — prompt universal todo-en-uno: clona + instala con la versión que indique el README (nunca caduca), verifica AI/VERSION instalado.
267
305
  - **v0.2.2** — anti-huérfanos: bloque de agente con regla de cierre limpio (no dejar servidores corriendo, no borrar carpetas con procesos dentro) + troubleshooting de carpeta bloqueada (resmon → Identificadores asociados).
268
306
  - **v0.2.1** — trazabilidad y versión visible: `AI/VERSION` viaja en el paquete, los instaladores imprimen la versión (`OK: harness vX.Y.Z…`, `BACKUP` con vieja→nueva) y el workflow exige que `package.json`, `VERSION` y `AI/VERSION` coincidan. Comandos fijados a `@0.2.1` / `#v0.2.1` / `--branch v0.2.1`.
269
- - **v0.2.0** — versión inicial: carpeta `AI/` parametrizada, instaladores idempotentes `install.ps1` / `install.sh`, `create-harness-btp` vía `pnpm dlx`, plantilla de puntero, docs de flujo / cf-safe / habilitación trial, plantilla de spec.
307
+ - **v0.2.0** — versión inicial: carpeta `AI/` parametrizada, instaladores idempotentes `install.ps1` / `install.sh`, `create-harness-btp` vía `pnpm dlx`, plantilla de puntero, docs de flujo / cf-safe / habilitación trial, plantilla de spec.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.4
1
+ 0.3.0
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
- // harness-btp init --dest <dir> [--force] [--ref <tag>]
3
- // Copia AI/, crea AGENTS.md puntero y fusiona .gitignore. Sin secretos.
2
+ // harness-btp init --dest <dir> [--force] [--ref <tag>] [--client auto|all|opencode,claude,...]
3
+ // Copia AI/, crea AGENTS.md puntero, fusiona el árbol del cliente agéntico
4
+ // desde AI/clients/<cliente>/ en la raíz (solo faltantes; con --force hace
5
+ // backup a <dir>.bak) y fusiona .gitignore. Sin secretos.
4
6
  // No toca package.json ni mta.yaml del proyecto.
5
7
  const fs = require("fs");
6
8
  const path = require("path");
@@ -18,10 +20,11 @@ if (!cmd || cmd.startsWith("-")) {
18
20
  const dest = arg("--dest", ".");
19
21
  const force = process.argv.includes("--force");
20
22
  const ref = arg("--ref", null);
23
+ const clientSpec = arg("--client", "auto");
21
24
  const src = path.join(__dirname, "..");
22
25
 
23
26
  if (cmd !== "init") {
24
- console.log("Uso: harness-btp init --dest <dir> [--force] [--ref <tag>]");
27
+ console.log("Uso: harness-btp init --dest <dir> [--force] [--ref <tag>] [--client auto|all|opencode,claude,...]");
25
28
  process.exit(1);
26
29
  }
27
30
  if (ref) console.log("REF: " + ref + " (el paquete incluye su propia versión; ver VERSION)");
@@ -61,6 +64,87 @@ if (fs.existsSync(agentsDst)) {
61
64
  console.log("CREATE: AGENTS.md (puntero a AI/AGENTS.md)");
62
65
  }
63
66
 
67
+ const KNOWN = ["opencode", "claude", "cursor", "copilot", "aider"];
68
+ function resolveClients(spec, destDir) {
69
+ const s = (spec + "").trim().toLowerCase();
70
+ if (s === "auto") {
71
+ const d = [];
72
+ if (fs.existsSync(path.join(destDir, "CLAUDE.md")) || fs.existsSync(path.join(destDir, ".claude"))) d.push("claude");
73
+ if (fs.existsSync(path.join(destDir, ".cursor"))) d.push("cursor");
74
+ if (fs.existsSync(path.join(destDir, ".github"))) d.push("copilot");
75
+ if (fs.readdirSync(destDir, { withFileTypes: true }).some((e) => e.isFile() && e.name.startsWith("opencode.json")) || fs.existsSync(path.join(destDir, ".opencode"))) d.push("opencode");
76
+ if (!d.length) d.push("opencode");
77
+ console.log("CLIENT: auto -> " + d.join(","));
78
+ return d;
79
+ }
80
+ if (s === "all") return ["opencode", "claude", "cursor", "copilot"];
81
+ const list = s.split(",").map((x) => x.trim().toLowerCase()).filter(Boolean);
82
+ for (const c of list) {
83
+ if (!KNOWN.includes(c)) {
84
+ console.log("ABORT: cliente desconocido '" + c + "' (usa auto|all|opencode,claude,cursor,copilot,aider)");
85
+ process.exit(1);
86
+ }
87
+ }
88
+ if (!list.length) {
89
+ console.log("ABORT: --client vacío (usa auto|all|opencode,claude,cursor,copilot,aider)");
90
+ process.exit(1);
91
+ }
92
+ return list;
93
+ }
94
+
95
+ function mergeTree(treeSrc, treeDst, label) {
96
+ if (!fs.existsSync(treeSrc)) {
97
+ console.log("AVISO: no existe " + treeSrc + " (regenera con node scripts/render-clients.js)");
98
+ return;
99
+ }
100
+ const bakLabel = label.replace(/\/$/, "") + ".bak";
101
+ if (force) {
102
+ if (fs.existsSync(treeDst)) {
103
+ const bak = treeDst + ".bak";
104
+ fs.rmSync(bak, { recursive: true, force: true });
105
+ fs.renameSync(treeDst, bak);
106
+ console.log("BACKUP: " + label + " -> " + bakLabel);
107
+ }
108
+ fs.cpSync(treeSrc, treeDst, { recursive: true });
109
+ console.log("CREATE: " + label + " (+" + listFilesRec(treeDst, treeDst).length + " archivos)");
110
+ } else {
111
+ let count = 0;
112
+ for (const rel of listFilesRec(treeSrc, treeSrc)) {
113
+ const tgt = path.join(treeDst, rel);
114
+ if (fs.existsSync(tgt)) {
115
+ console.log("SKIP: " + label + rel.split(path.sep).join("/") + " ya existe");
116
+ } else {
117
+ fs.mkdirSync(path.dirname(tgt), { recursive: true });
118
+ fs.copyFileSync(path.join(treeSrc, rel), tgt);
119
+ count++;
120
+ }
121
+ }
122
+ console.log("CREATE: " + label + " (+" + count + " archivos)");
123
+ }
124
+ }
125
+
126
+ const clientsSrc = path.join(src, "AI", "clients");
127
+ for (const c of resolveClients(clientSpec, dest)) {
128
+ if (c === "opencode") mergeTree(path.join(clientsSrc, "opencode"), path.join(dest, ".opencode"), ".opencode/");
129
+ else if (c === "claude") mergeTree(path.join(clientsSrc, "claude"), path.join(dest, ".claude"), ".claude/");
130
+ else if (c === "cursor") {
131
+ mergeTree(path.join(clientsSrc, "cursor", "commands"), path.join(dest, ".cursor", "commands"), ".cursor/commands/");
132
+ mergeTree(path.join(clientsSrc, "cursor", "skills"), path.join(dest, ".agents", "skills"), ".agents/skills/");
133
+ } else if (c === "copilot") {
134
+ mergeTree(path.join(clientsSrc, "copilot", "agents"), path.join(dest, ".github", "agents"), ".github/agents/");
135
+ mergeTree(path.join(clientsSrc, "copilot", "skills"), path.join(dest, ".github", "skills"), ".github/skills/");
136
+ mergeTree(path.join(clientsSrc, "copilot", "prompts"), path.join(dest, ".github", "prompts"), ".github/prompts/");
137
+ } else if (c === "aider") console.log("SKIP: aider usa AGENTS.md raiz (nada que fusionar)");
138
+ }
139
+ function listFilesRec(dir, base) {
140
+ let out = [];
141
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
142
+ const p = path.join(dir, e.name);
143
+ if (e.isDirectory()) out = out.concat(listFilesRec(p, base));
144
+ else out.push(path.relative(base, p));
145
+ }
146
+ return out;
147
+ }
64
148
  const frag = fs.readFileSync(path.join(src, "AI", ".gitignore.fragment"), "utf8")
65
149
  .split(/\r?\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
66
150
  let cur = [];