create-harness-btp 0.1.1 → 0.2.1
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/AI/.opencode/agents/deploy-cf.md +7 -7
- package/AI/.opencode/agents/orchestrator.md +1 -1
- package/AI/.opencode/commands/verify.md +1 -1
- package/AI/.opencode/skills/cf-cli/SKILL.md +41 -0
- package/AI/.opencode/skills/mta-build/SKILL.md +4 -4
- package/AI/AGENTS.md +22 -21
- package/AI/INICIO.md +34 -15
- package/AI/VERSION +1 -0
- package/AI/docs/cf-safe.md +5 -5
- package/AI/docs/flujo-etapas.md +1 -1
- package/AI/docs/fuentes-oficiales.md +27 -0
- package/AI/docs/habilitacion-trial.md +2 -2
- package/AI/docs/prerequisitos.md +60 -0
- package/AI/scripts/cf-safe.ps1 +14 -14
- package/AI/scripts/check-docs.ps1 +78 -0
- package/AI/scripts/check-docs.sh +42 -0
- package/AI/scripts/check-prereqs.ps1 +129 -0
- package/AI/scripts/check-prereqs.sh +136 -0
- package/AI/scripts/provision-espacio.template.ps1 +10 -10
- package/README.md +119 -41
- package/VERSION +1 -1
- package/bin/harness-btp.js +10 -4
- package/install.ps1 +18 -4
- package/install.sh +24 -6
- package/package.json +1 -1
- package/AI/.opencode/skills/sap-cf-cli/SKILL.md +0 -41
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# harness-btp
|
|
2
2
|
|
|
3
|
-
[](https://github.com/horangelmillan/harness-btp/releases/tag/v0.2.1)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](https://github.com/horangelmillan/harness-btp)
|
|
6
|
-
[](https://github.com/horangelmillan/harness-btp)
|
|
6
|
+
[](https://github.com/horangelmillan/harness-btp)
|
|
7
7
|
|
|
8
|
-
Reglas, agentes y scripts reutilizables para llevar un MVP SAP de la especificación al despliegue en Cloud Foundry con
|
|
8
|
+
Reglas, agentes y scripts reutilizables para llevar un MVP SAP de la especificación al despliegue en Cloud Foundry, con cualquier cliente agéntico que lea `AGENTS.md`.
|
|
9
9
|
|
|
10
|
-
Para quien construye MVPs SAP BTP
|
|
10
|
+
Para quien construye MVPs SAP BTP y quiere empezar cada proyecto con el mismo flujo probado, sin copiar y pegar. Funciona en Windows, Linux y macOS, con OpenCode, Claude Code o cualquier otro cliente que lea `AGENTS.md` y ejecute scripts del proyecto.
|
|
11
11
|
|
|
12
12
|
## Contenidos
|
|
13
13
|
|
|
@@ -15,7 +15,9 @@ Para quien construye MVPs SAP BTP en equipo Windows con OpenCode y quiere empeza
|
|
|
15
15
|
- [Requisitos](#requisitos)
|
|
16
16
|
- [Quickstart](#quickstart)
|
|
17
17
|
- [Instalación](#instalación)
|
|
18
|
+
- [Instalación asistida por agente](#instalación-asistida-por-agente)
|
|
18
19
|
- [Actualizar y desinstalar](#actualizar-y-desinstalar)
|
|
20
|
+
- [Adaptadores opcionales](#adaptadores-opcionales)
|
|
19
21
|
- [Estructura del repo](#estructura-del-repo)
|
|
20
22
|
- [Cómo lo descubre el agente](#cómo-lo-descubre-el-agente)
|
|
21
23
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -27,71 +29,101 @@ Para quien construye MVPs SAP BTP en equipo Windows con OpenCode y quiere empeza
|
|
|
27
29
|
## Features
|
|
28
30
|
|
|
29
31
|
- **Carpeta `AI/` sin envolver:** se instala dentro de tu proyecto (nuevo o existente) sin mover ni renombrar nada de lo que ya tienes.
|
|
30
|
-
- **Idempotente con `SKIP` / `-Force` + backup:** repetir la instalación no pisa nada; solo reemplaza con `-Force` y guarda copia en `AI.bak`.
|
|
32
|
+
- **Idempotente con `SKIP` / `-Force` + backup:** repetir la instalación no pisa nada; solo reemplaza con `-Force` (`.ps1`) o `--force` (`.sh`) y guarda copia en `AI.bak`.
|
|
31
33
|
- **Sin secretos:** el repo no contiene credenciales, tokens ni rutas de máquina; solo nombres y placeholders por paisaje.
|
|
32
34
|
- **Tres formas de instalar:** `degit`, `git clone` o `pnpm dlx`, todas ancladas a un tag versionado.
|
|
33
35
|
- **Versionado por tags:** cada versión es un tag `vX.Y.Z`; actualizar es repetir el comando contra el tag nuevo.
|
|
34
|
-
- **
|
|
36
|
+
- **Instaladores pares:** `install.ps1` (PowerShell) e `install.sh` (bash/sh) con la misma lógica (`SKIP` / `CREATE` / `BACKUP` / `OK`). Elige el de tu shell.
|
|
37
|
+
- **Agnóstico al cliente:** el núcleo es Markdown + shell (`AI/AGENTS.md`, `AI/INICIO.md`, `AI/docs/`, `AI/scripts/`). `AI/.opencode/` y `AI/opencode.fragment.jsonc` son adaptadores opcionales de ejemplo, no requisitos (ver [Adaptadores opcionales](#adaptadores-opcionales)).
|
|
38
|
+
- **El agente se adapta solo:** deja un puntero `AGENTS.md` en la raíz y el cliente encuentra `AI/AGENTS.md`, `INICIO.md`, agentes, skills y plantilla de spec.
|
|
35
39
|
|
|
36
40
|
## Requisitos
|
|
37
41
|
|
|
38
42
|
| Necesitas | Versión | Para qué |
|
|
39
43
|
|---|---|---|
|
|
40
|
-
|
|
|
44
|
+
| PowerShell 5.1+ o bash/sh | incluido en el SO | ejecutar `install.ps1` / `install.sh` |
|
|
41
45
|
| Node.js 18+ | solo si usas `degit` o `pnpm dlx` | descargar e instalar el harness |
|
|
42
46
|
| `gh` (opcional) | cualquiera reciente | clonar repo privado o crear PRs |
|
|
43
|
-
|
|
|
47
|
+
| Cliente agéntico | cualquiera reciente que lea `AGENTS.md` (OpenCode, Claude Code, etc.) | leer `AGENTS.md` y orquestar el flujo |
|
|
44
48
|
|
|
45
49
|
> Sin Node también puedes instalar vía `git clone`, que no lo necesita.
|
|
46
50
|
|
|
47
51
|
## Quickstart
|
|
48
52
|
|
|
49
|
-
El camino de 30 segundos en un proyecto nuevo
|
|
53
|
+
El camino de 30 segundos en un proyecto nuevo. Elige tu shell:
|
|
54
|
+
|
|
55
|
+
PowerShell (Windows):
|
|
50
56
|
|
|
51
57
|
```powershell
|
|
52
|
-
npx -p degit degit horangelmillan/harness-btp#v0.1
|
|
58
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
53
59
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
54
60
|
Remove-Item -Recurse -Force AI-tmp
|
|
55
61
|
```
|
|
56
62
|
|
|
57
|
-
|
|
63
|
+
bash (Linux, macOS o Git Bash):
|
|
58
64
|
|
|
59
|
-
|
|
65
|
+
```bash
|
|
66
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
67
|
+
sh AI-tmp/install.sh --dest .
|
|
68
|
+
rm -rf AI-tmp
|
|
69
|
+
```
|
|
60
70
|
|
|
61
|
-
|
|
71
|
+
Eso es todo. Abre el proyecto en tu cliente agéntico y el agente ya sabe qué hacer: lee `AGENTS.md` → `AI/AGENTS.md` → `AI/INICIO.md`.
|
|
72
|
+
|
|
73
|
+
## Instalación
|
|
62
74
|
|
|
63
75
|
### Opción 1 — degit (recomendado)
|
|
64
76
|
|
|
65
77
|
Descarga solo lo necesario, sin historial git:
|
|
66
78
|
|
|
79
|
+
PowerShell:
|
|
80
|
+
|
|
67
81
|
```powershell
|
|
68
|
-
npx -p degit degit horangelmillan/harness-btp#v0.1
|
|
82
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
69
83
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
70
84
|
Remove-Item -Recurse -Force AI-tmp
|
|
71
85
|
```
|
|
72
86
|
|
|
87
|
+
bash:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
91
|
+
sh AI-tmp/install.sh --dest .
|
|
92
|
+
rm -rf AI-tmp
|
|
93
|
+
```
|
|
94
|
+
|
|
73
95
|
### Opción 2 — git clone
|
|
74
96
|
|
|
75
97
|
Clon superficial anclado al tag:
|
|
76
98
|
|
|
99
|
+
PowerShell:
|
|
100
|
+
|
|
77
101
|
```powershell
|
|
78
|
-
git clone --branch v0.1
|
|
102
|
+
git clone --branch v0.2.1 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
|
|
79
103
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
80
104
|
Remove-Item -Recurse -Force AI-tmp
|
|
81
105
|
```
|
|
82
106
|
|
|
107
|
+
bash:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git clone --branch v0.2.1 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
|
|
111
|
+
sh AI-tmp/install.sh --dest .
|
|
112
|
+
rm -rf AI-tmp
|
|
113
|
+
```
|
|
114
|
+
|
|
83
115
|
### Opción 3 — pnpm dlx
|
|
84
116
|
|
|
85
|
-
Sin descargas manuales (requiere publicar `create-harness-btp` en el registry):
|
|
117
|
+
Sin descargas manuales (requiere publicar `create-harness-btp` en el registry). Igual en todos los SO:
|
|
86
118
|
|
|
87
|
-
```
|
|
88
|
-
pnpm dlx create-harness-btp --dest .
|
|
119
|
+
```bash
|
|
120
|
+
pnpm dlx create-harness-btp@0.2.1 --dest .
|
|
89
121
|
```
|
|
90
122
|
|
|
91
123
|
### Qué hace el instalador
|
|
92
124
|
|
|
93
|
-
- `CREATE: AI/` o `SKIP: AI/ ya existe` (solo lo reemplaza con `-Force`, con backup a `AI.bak`).
|
|
94
|
-
- `CREATE: AGENTS.md` o `SKIP: AGENTS.md ya existe` (tu `AGENTS.md` propio se conserva; con `-Force` se respalda a `AGENTS.md.bak`).
|
|
125
|
+
- `CREATE: AI/` o `SKIP: AI/ ya existe` (solo lo reemplaza con `-Force` / `--force`, con backup a `AI.bak`).
|
|
126
|
+
- `CREATE: AGENTS.md` o `SKIP: AGENTS.md ya existe` (tu `AGENTS.md` propio se conserva; con `-Force` / `--force` se respalda a `AGENTS.md.bak`).
|
|
95
127
|
- Fusiona `.gitignore`: añade las líneas que falten, sin duplicar ni borrar las tuyas.
|
|
96
128
|
- **No toca** `package.json` ni `mta.yaml` de tu proyecto, nunca.
|
|
97
129
|
|
|
@@ -100,29 +132,67 @@ Salida típica en proyecto nuevo:
|
|
|
100
132
|
```text
|
|
101
133
|
CREATE: AI/
|
|
102
134
|
CREATE: AGENTS.md
|
|
103
|
-
OK: harness v0.1
|
|
135
|
+
OK: harness v0.2.1 instalado
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Instalación asistida por agente
|
|
139
|
+
|
|
140
|
+
Si prefieres que tu agente lo instale por ti, pégale este bloque:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
Pégale esto a tu agente: Instala el harness BTP versión 0.2.1 en la raíz del proyecto: 1) Lee el README del repo harness-btp (opción pnpm). 2) Ejecuta EXACTAMENTE pnpm dlx create-harness-btp@0.2.1 --dest . (sin --force salvo que AI/ ya exista y yo lo autorice; con --force verifica BACKUP primero). 3) PROHIBIDO pisar o borrar: AGENTS.md raíz existente, package.json, mta.yaml, lockfiles. 4) Verifica lo INSTALADO (no vale pnpm view): AI/VERSION debe decir 0.2.1. 5) Si migraste npm→pnpm con import+install+test en verde, borra package-lock.json. 6) Corre AI/scripts/check-prereqs y reporta faltantes. 7) Si hay placeholders por adaptar, dímelos antes de desplegar. Sin secretos en el reporte. Repórtame: comando, salida del instalador, contenido de AI/VERSION, git status y pendientes.
|
|
104
144
|
```
|
|
105
145
|
|
|
106
146
|
## Actualizar y desinstalar
|
|
107
147
|
|
|
108
|
-
**Actualizar:** repite el mismo comando de instalación contra el tag nuevo. Sin `-Force` lo existente se conserva (`SKIP:`); con
|
|
148
|
+
**Actualizar:** repite el mismo comando de instalación contra el tag nuevo. Sin `-Force` / `--force` lo existente se conserva (`SKIP:`); con fuerza se reemplaza con backup:
|
|
149
|
+
|
|
150
|
+
PowerShell:
|
|
109
151
|
|
|
110
152
|
```powershell
|
|
111
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
153
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
112
154
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest . -Force
|
|
113
155
|
Remove-Item -Recurse -Force AI-tmp
|
|
114
156
|
# tu versión anterior queda en AI.bak por si quieres comparar
|
|
115
157
|
```
|
|
116
158
|
|
|
159
|
+
bash:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.1 AI-tmp -- AI-tmp
|
|
163
|
+
sh AI-tmp/install.sh --dest . --force
|
|
164
|
+
rm -rf AI-tmp
|
|
165
|
+
# tu versión anterior queda en AI.bak por si quieres comparar
|
|
166
|
+
```
|
|
167
|
+
|
|
117
168
|
**Desinstalar:** borra la carpeta y el puntero. No deja servicios ni hooks:
|
|
118
169
|
|
|
170
|
+
PowerShell:
|
|
171
|
+
|
|
119
172
|
```powershell
|
|
120
173
|
Remove-Item -Recurse -Force AI
|
|
121
174
|
Remove-Item -Force AGENTS.md # solo si es el puntero al harness
|
|
122
175
|
```
|
|
123
176
|
|
|
177
|
+
bash:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
rm -rf AI
|
|
181
|
+
rm -f AGENTS.md # solo si es el puntero al harness
|
|
182
|
+
```
|
|
183
|
+
|
|
124
184
|
> Si tu `AGENTS.md` tenía contenido propio antes del harness, el instalador lo respaldó en `AGENTS.md.bak`: restáuralo en vez de borrarlo.
|
|
125
185
|
|
|
186
|
+
## Adaptadores opcionales
|
|
187
|
+
|
|
188
|
+
El harness funciona con **cualquier** cliente agéntico que lea `AGENTS.md`. Estos archivos son ayudas para un cliente concreto, no requisitos:
|
|
189
|
+
|
|
190
|
+
- **`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.
|
|
191
|
+
- **`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.
|
|
192
|
+
- **`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`.
|
|
193
|
+
|
|
194
|
+
Nada del núcleo exige OpenCode, Windows ni ningún modelo concreto.
|
|
195
|
+
|
|
126
196
|
## Estructura del repo
|
|
127
197
|
|
|
128
198
|
```text
|
|
@@ -130,9 +200,9 @@ harness-btp/
|
|
|
130
200
|
├── AI/ # lo que queda instalado en tu proyecto
|
|
131
201
|
│ ├── AGENTS.md # reglas del harness (parametrizado, sin rutas absolutas)
|
|
132
202
|
│ ├── INICIO.md # punto de entrada para el agente
|
|
133
|
-
│ ├── opencode.fragment.jsonc#
|
|
134
|
-
│ ├── .opencode/ #
|
|
135
|
-
│ ├── scripts/ #
|
|
203
|
+
│ ├── opencode.fragment.jsonc# ADAPTER opcional: ejemplo para opencode.jsonc
|
|
204
|
+
│ ├── .opencode/ # ADAPTER opcional: agents + commands + skills de ejemplo
|
|
205
|
+
│ ├── scripts/ # pares .ps1 / .sh + provision-espacio.template.ps1
|
|
136
206
|
│ ├── docs/ # flujo-etapas, cf-safe, habilitacion-trial
|
|
137
207
|
│ ├── specs/ # plantilla _template.md
|
|
138
208
|
│ └── .gitignore.fragment # líneas a fusionar en tu .gitignore
|
|
@@ -141,15 +211,15 @@ harness-btp/
|
|
|
141
211
|
├── install.ps1 / install.sh # instaladores idempotentes (SKIP / CREATE / BACKUP / OK)
|
|
142
212
|
├── bin/ # ejecutable de create-harness-btp (pnpm dlx)
|
|
143
213
|
├── package.json # name create-harness-btp
|
|
144
|
-
└── VERSION # 0.1
|
|
214
|
+
└── VERSION # 0.2.1
|
|
145
215
|
```
|
|
146
216
|
|
|
147
217
|
## Cómo lo descubre el agente
|
|
148
218
|
|
|
149
|
-
1.
|
|
150
|
-
2. El puntero lo lleva a `AI/AGENTS.md`: reglas, herramientas (`
|
|
151
|
-
3. Desde ahí sigue a `AI/INICIO.md` para el flujo por etapas (`/flow`), descubre agentes en `.opencode/`, skills y scripts, y usa `AI/specs/_template.md` para nuevas especificaciones.
|
|
152
|
-
4. Antes del primer despliegue adapta los dos placeholders a tu
|
|
219
|
+
1. Tu cliente agéntico abre el proyecto y lee `AGENTS.md` en la raíz (el puntero que deja el instalador).
|
|
220
|
+
2. El puntero lo lleva a `AI/AGENTS.md`: reglas, herramientas (`cf`, `mbt`) y presupuestos.
|
|
221
|
+
3. Desde ahí sigue a `AI/INICIO.md` para el flujo por etapas (`/flow`), descubre los agentes de ejemplo en `.opencode/`, skills y scripts, y usa `AI/specs/_template.md` para nuevas especificaciones.
|
|
222
|
+
4. Antes del primer despliegue adapta los dos placeholders a tu destino (ver `AI/INICIO.md`).
|
|
153
223
|
|
|
154
224
|
Tú no configuras nada: el agente se adapta solo.
|
|
155
225
|
|
|
@@ -157,24 +227,31 @@ Tú no configuras nada: el agente se adapta solo.
|
|
|
157
227
|
|
|
158
228
|
| Problema | Causa | Comando |
|
|
159
229
|
|---|---|---|
|
|
160
|
-
| `SKIP: AI/ ya existe` y quería actualizar | reinstalación sin
|
|
161
|
-
| Mi `AGENTS.md` propio desapareció | se instaló con
|
|
230
|
+
| `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` |
|
|
231
|
+
| Mi `AGENTS.md` propio desapareció | se instaló con fuerza | recupera `AGENTS.md.bak` |
|
|
162
232
|
| Líneas duplicadas en `.gitignore` | edición manual tras la fusión | el instalador fusiona sin duplicar; borra el duplicado a mano |
|
|
163
|
-
| `ExecutionPolicy` bloquea `install.ps1` | política de PowerShell | `powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .` |
|
|
164
|
-
| `
|
|
233
|
+
| `ExecutionPolicy` bloquea `install.ps1` | política de PowerShell | `powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .` (o usa `install.sh` en Git Bash) |
|
|
234
|
+
| `ABORT: opción desconocida` en `install.sh` | flag inexistente | `sh install.sh --help` lista `--dest`, `--force` |
|
|
235
|
+
| `degit` falla sin Node | `degit` corre sobre Node 18+ | instala Node o usa `git clone --branch v0.2.1` |
|
|
236
|
+
| 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` |
|
|
165
237
|
|
|
166
238
|
## Compatibilidad
|
|
167
239
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
240
|
+
Matriz honesta cliente × SO (`verificado` = probado con evidencia; `esperado` = sin bloqueo conocido, pendiente de evidencia):
|
|
241
|
+
|
|
242
|
+
| Cliente agéntico | Windows | Linux | macOS |
|
|
243
|
+
|---|---|---|---|
|
|
244
|
+
| OpenCode | verificado | esperado (`install.sh` par verificado en Git Bash) | esperado |
|
|
245
|
+
| Claude Code, otros que lean `AGENTS.md` | esperado | esperado | esperado |
|
|
246
|
+
|
|
247
|
+
- Instaladores y `check-prereqs` / `check-docs` verificados en Windows (`.ps1` nativo, `.sh` vía Git Bash, paridad CREATE/SKIP/BACKUP/OK + mismos `exit`).
|
|
171
248
|
- SAP BTP Cloud Foundry solo cuando el MVP lo pida: el harness no crea cuentas ni espacios por sí solo.
|
|
172
249
|
|
|
173
250
|
## Contribuir
|
|
174
251
|
|
|
175
252
|
- Abre un issue antes que un PR si el cambio afecta reglas o scripts.
|
|
176
253
|
- PRs pequeños, en español, con evidencia del comando corrido.
|
|
177
|
-
- Versionado semver: los cambios se publican como tags `vX.Y.Z` (`VERSION` + `
|
|
254
|
+
- Versionado semver: los cambios se publican como tags `vX.Y.Z` (`package.json` + `VERSION` + `AI/VERSION` + tag git coinciden; el workflow lo verifica).
|
|
178
255
|
|
|
179
256
|
## Licencia
|
|
180
257
|
|
|
@@ -182,4 +259,5 @@ MIT. Haz lo que quieras con el harness; sin garantía.
|
|
|
182
259
|
|
|
183
260
|
## Changelog
|
|
184
261
|
|
|
185
|
-
- **v0.1
|
|
262
|
+
- **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`.
|
|
263
|
+
- **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.
|
|
1
|
+
0.2.1
|
package/bin/harness-btp.js
CHANGED
|
@@ -29,22 +29,28 @@ if (!fs.existsSync(path.join(src, "AI"))) {
|
|
|
29
29
|
console.log("ABORT: no se encontró AI/ junto al paquete");
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
|
+
function readVer(p) {
|
|
33
|
+
try {
|
|
34
|
+
return fs.readFileSync(p, "utf8").split(/\r?\n/)[0].trim() || "desconocida";
|
|
35
|
+
} catch { return "desconocida"; }
|
|
36
|
+
}
|
|
37
|
+
const harnessVersion = readVer(path.join(src, "AI", "VERSION"));
|
|
32
38
|
|
|
33
39
|
const aiDst = path.join(dest, "AI");
|
|
34
40
|
if (fs.existsSync(aiDst)) {
|
|
35
41
|
if (force) {
|
|
42
|
+
const oldVersion = readVer(path.join(aiDst, "VERSION"));
|
|
36
43
|
const bak = path.join(dest, "AI.bak");
|
|
37
44
|
fs.rmSync(bak, { recursive: true, force: true });
|
|
38
45
|
fs.renameSync(aiDst, bak);
|
|
39
|
-
console.log("BACKUP: AI/ -> AI.bak");
|
|
40
46
|
fs.cpSync(path.join(src, "AI"), aiDst, { recursive: true });
|
|
41
|
-
console.log("CREATE: AI/ (
|
|
47
|
+
console.log("BACKUP: AI/ (v" + oldVersion + ") -> AI.bak; CREATE: AI/ (v" + harnessVersion + ")");
|
|
42
48
|
} else {
|
|
43
49
|
console.log("SKIP: AI/ ya existe (usa --force para reinstalar con backup .bak)");
|
|
44
50
|
}
|
|
45
51
|
} else {
|
|
46
52
|
fs.cpSync(path.join(src, "AI"), aiDst, { recursive: true });
|
|
47
|
-
console.log("CREATE: AI/");
|
|
53
|
+
console.log("CREATE: AI/ (v" + harnessVersion + ")");
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
const agentsDst = path.join(dest, "AGENTS.md");
|
|
@@ -67,4 +73,4 @@ if (missing.length === 0) {
|
|
|
67
73
|
fs.appendFileSync(giDst, (cur.length ? "" : "") + missing.join("\n") + "\n");
|
|
68
74
|
console.log("CREATE: .gitignore (+" + missing.length + " líneas)");
|
|
69
75
|
}
|
|
70
|
-
console.log("OK: harness instalado en " + dest + " (package.json y mta.yaml intactos)");
|
|
76
|
+
console.log("OK: harness v" + harnessVersion + " instalado en " + dest + " (package.json y mta.yaml intactos)");
|
package/install.ps1
CHANGED
|
@@ -16,21 +16,29 @@ $TplPointer = Join-Path $Src "templates\AGENTS.pointer.md"
|
|
|
16
16
|
|
|
17
17
|
if (-not (Test-Path $AiSrc)) { Write-Output "ABORT: no se encontró AI/ junto a install.ps1"; exit 1 }
|
|
18
18
|
|
|
19
|
+
$HarnessVersion = "desconocida"
|
|
20
|
+
$VersionFile = Join-Path $AiSrc "VERSION"
|
|
21
|
+
if (Test-Path $VersionFile) { $HarnessVersion = ((Get-Content $VersionFile | Select-Object -First 1) + "").Trim() }
|
|
22
|
+
if (-not $HarnessVersion) { $HarnessVersion = "desconocida" }
|
|
23
|
+
|
|
19
24
|
$AiDst = Join-Path $Dest "AI"
|
|
20
25
|
if (Test-Path $AiDst) {
|
|
21
26
|
if ($Force) {
|
|
27
|
+
$OldVersion = "desconocida"
|
|
28
|
+
$DstVersionFile = Join-Path $AiDst "VERSION"
|
|
29
|
+
if (Test-Path $DstVersionFile) { $OldVersion = ((Get-Content $DstVersionFile | Select-Object -First 1) + "").Trim() }
|
|
30
|
+
if (-not $OldVersion) { $OldVersion = "desconocida" }
|
|
22
31
|
$Bak = Join-Path $Dest "AI.bak"
|
|
23
32
|
if (Test-Path $Bak) { Remove-Item $Bak -Recurse -Force }
|
|
24
33
|
Rename-Item $AiDst "AI.bak"
|
|
25
|
-
Write-Output "BACKUP: AI/ -> AI.bak"
|
|
26
34
|
Copy-Item $AiSrc $AiDst -Recurse -Force
|
|
27
|
-
Write-Output "
|
|
35
|
+
Write-Output "BACKUP: AI/ (v$OldVersion) -> AI.bak; CREATE: AI/ (v$HarnessVersion)"
|
|
28
36
|
} else {
|
|
29
37
|
Write-Output "SKIP: AI/ ya existe (usa -Force para reinstalar con backup .bak)"
|
|
30
38
|
}
|
|
31
39
|
} else {
|
|
32
40
|
Copy-Item $AiSrc $AiDst -Recurse -Force
|
|
33
|
-
Write-Output "CREATE: AI/"
|
|
41
|
+
Write-Output "CREATE: AI/ (v$HarnessVersion)"
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
$AgentsDst = Join-Path $Dest "AGENTS.md"
|
|
@@ -57,4 +65,10 @@ if (Test-Path $GiDst) {
|
|
|
57
65
|
Write-Output "CREATE: .gitignore"
|
|
58
66
|
}
|
|
59
67
|
|
|
60
|
-
Write-Output "OK: harness instalado en $Dest (package.json y mta.yaml intactos)"
|
|
68
|
+
Write-Output "OK: harness v$HarnessVersion instalado en $Dest (package.json y mta.yaml intactos)"
|
|
69
|
+
|
|
70
|
+
# Verificación de prerrequisitos en modo aviso (no bloquea la instalación).
|
|
71
|
+
try {
|
|
72
|
+
$Check = Join-Path $AiSrc "scripts\check-prereqs.ps1"
|
|
73
|
+
if (Test-Path $Check) { & $Check -WarnOnly }
|
|
74
|
+
} catch { Write-Output "AVISO: no se pudo ejecutar check-prereqs.ps1 (ver AI/docs/prerequisitos.md)" }
|
package/install.sh
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
# Instalador del harness BTP (idempotente, POSIX sh).
|
|
3
|
-
# Uso: ./install.sh [--dest
|
|
3
|
+
# Uso: ./install.sh [--dest <dir>] [--force] [--help]
|
|
4
4
|
# Sin secretos. No toca package.json ni mta.yaml del proyecto.
|
|
5
5
|
DEST="."
|
|
6
6
|
FORCE=0
|
|
@@ -8,22 +8,33 @@ while [ $# -gt 0 ]; do
|
|
|
8
8
|
case "$1" in
|
|
9
9
|
--dest) DEST="$2"; shift 2 ;;
|
|
10
10
|
--force) FORCE=1; shift ;;
|
|
11
|
-
|
|
11
|
+
-h|--help)
|
|
12
|
+
echo "Uso: ./install.sh [--dest <dir>] [--force] [--help]"
|
|
13
|
+
echo " --dest <dir> proyecto destino (por defecto: .)"
|
|
14
|
+
echo " --force reinstala AI/ con backup a AI.bak"
|
|
15
|
+
echo " -h, --help muestra esta ayuda"
|
|
16
|
+
exit 0 ;;
|
|
17
|
+
*) echo "ABORT: opción desconocida $1 (usa --help)"; exit 1 ;;
|
|
12
18
|
esac
|
|
13
19
|
done
|
|
14
20
|
SRC="$(cd "$(dirname "$0")" && pwd)"
|
|
15
21
|
if [ ! -d "$SRC/AI" ]; then echo "ABORT: no se encontró AI/ junto a install.sh"; exit 1; fi
|
|
22
|
+
HARNESS_VERSION="desconocida"
|
|
23
|
+
if [ -f "$SRC/AI/VERSION" ]; then HARNESS_VERSION="$(tr -d '[:space:]' < "$SRC/AI/VERSION")"; fi
|
|
24
|
+
[ -n "$HARNESS_VERSION" ] || HARNESS_VERSION="desconocida"
|
|
16
25
|
|
|
17
26
|
if [ -d "$DEST/AI" ]; then
|
|
18
27
|
if [ "$FORCE" -eq 1 ]; then
|
|
28
|
+
OLD_VERSION="desconocida"
|
|
29
|
+
if [ -f "$DEST/AI/VERSION" ]; then OLD_VERSION="$(tr -d '[:space:]' < "$DEST/AI/VERSION")"; fi
|
|
30
|
+
[ -n "$OLD_VERSION" ] || OLD_VERSION="desconocida"
|
|
19
31
|
rm -rf "$DEST/AI.bak" && mv "$DEST/AI" "$DEST/AI.bak"
|
|
20
|
-
echo "BACKUP: AI/ -> AI.bak"
|
|
21
|
-
cp -r "$SRC/AI" "$DEST/AI" && echo "CREATE: AI/ (reinstalado con --force)"
|
|
32
|
+
cp -r "$SRC/AI" "$DEST/AI" && echo "BACKUP: AI/ (v$OLD_VERSION) -> AI.bak; CREATE: AI/ (v$HARNESS_VERSION)"
|
|
22
33
|
else
|
|
23
34
|
echo "SKIP: AI/ ya existe (usa --force para reinstalar con backup .bak)"
|
|
24
35
|
fi
|
|
25
36
|
else
|
|
26
|
-
cp -r "$SRC/AI" "$DEST/AI" && echo "CREATE: AI/"
|
|
37
|
+
cp -r "$SRC/AI" "$DEST/AI" && echo "CREATE: AI/ (v$HARNESS_VERSION)"
|
|
27
38
|
fi
|
|
28
39
|
|
|
29
40
|
if [ -f "$DEST/AGENTS.md" ]; then
|
|
@@ -45,4 +56,11 @@ done < "$FRAG"
|
|
|
45
56
|
if [ "$ADDED" -eq 0 ]; then echo "SKIP: .gitignore ya contiene el fragmento"
|
|
46
57
|
else echo "CREATE: .gitignore (+$ADDED líneas)"; fi
|
|
47
58
|
|
|
48
|
-
echo "OK: harness instalado en $DEST (package.json y mta.yaml intactos)"
|
|
59
|
+
echo "OK: harness v$HARNESS_VERSION instalado en $DEST (package.json y mta.yaml intactos)"
|
|
60
|
+
|
|
61
|
+
# Verificación de prerrequisitos en modo aviso (no bloquea la instalación).
|
|
62
|
+
if [ -f "$SRC/AI/scripts/check-prereqs.sh" ]; then
|
|
63
|
+
sh "$SRC/AI/scripts/check-prereqs.sh" --warn-only || true
|
|
64
|
+
else
|
|
65
|
+
echo "AVISO: no se encontró check-prereqs.sh (ver AI/docs/prerequisitos.md)"
|
|
66
|
+
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-harness-btp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Instala el harness MVP SAP BTP como carpeta AI/ en cualquier proyecto",
|
|
5
5
|
"keywords": ["sap-btp", "opencode", "harness", "agents", "scaffolder", "create"],
|
|
6
6
|
"homepage": "https://github.com/horangelmillan/harness-btp#readme",
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sap-cf-cli
|
|
3
|
-
description: Uso seguro del CLI de Cloud Foundry como sap_cf en Windows
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# CLI Cloud Foundry (`sap_cf`)
|
|
7
|
-
|
|
8
|
-
En [TU_PC] `cf` es el CLI de **Cloudflare**. Cloud Foundry se invoca
|
|
9
|
-
**siempre** como `sap_cf` (`sap_cf.cmd`, ruta de instalación de
|
|
10
|
-
Cloud Foundry CLI en [TU_PC]; verificado en Windows, adapta rutas).
|
|
11
|
-
|
|
12
|
-
## Lectura segura (sin secretos)
|
|
13
|
-
|
|
14
|
-
```
|
|
15
|
-
sap_cf target # endpoint / org / espacio actuales
|
|
16
|
-
sap_cf api # endpoint y versión API
|
|
17
|
-
sap_cf orgs # solo nombres
|
|
18
|
-
sap_cf spaces # solo nombres
|
|
19
|
-
sap_cf apps # estado observable (started/stopped, rutas)
|
|
20
|
-
sap_cf services # instancias visibles
|
|
21
|
-
sap_cf logs <app> --recent
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
`target`, `api`, `orgs`, `spaces` y `app <nombre>` nunca muestran tokens.
|
|
25
|
-
Si una salida incluyera un secreto, redáctalo antes de citarla.
|
|
26
|
-
|
|
27
|
-
## Mutaciones (solo `deploy-cf`, con destino confirmado)
|
|
28
|
-
|
|
29
|
-
- Confirmar endpoint/org/espacio contra la spec **antes** de cada despliegue.
|
|
30
|
-
- `sap_cf push` para apps simples; `sap_cf deploy <archivo>.mtar` para MTA
|
|
31
|
-
(requiere plugin `multiapps`, no instalado: ver skill `mta-build`).
|
|
32
|
-
- Verificar después: `sap_cf apps` + `sap_cf logs <app> --recent` + URL.
|
|
33
|
-
|
|
34
|
-
## Denylist
|
|
35
|
-
|
|
36
|
-
- `cf ...` para cualquier operación Foundry.
|
|
37
|
-
- Borrar o renombrar orgs, espacios, apps o servicios fuera del MVP.
|
|
38
|
-
- `sap_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.
|