create-harness-btp 0.2.4 → 0.2.5
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/VERSION +1 -1
- package/README.md +17 -13
- package/VERSION +1 -1
- package/bin/harness-btp.js +39 -1
- package/install.ps1 +33 -0
- package/install.sh +30 -0
- package/package.json +1 -1
package/AI/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.5
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# harness-btp
|
|
2
2
|
|
|
3
|
-
[](https://github.com/horangelmillan/harness-btp/releases/tag/v0.2.5)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://github.com/horangelmillan/harness-btp)
|
|
6
6
|
[](https://github.com/horangelmillan/harness-btp)
|
|
@@ -55,7 +55,7 @@ El camino de 30 segundos en un proyecto nuevo. Elige tu shell:
|
|
|
55
55
|
PowerShell (Windows):
|
|
56
56
|
|
|
57
57
|
```powershell
|
|
58
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
58
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
59
59
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
60
60
|
Remove-Item -Recurse -Force AI-tmp
|
|
61
61
|
```
|
|
@@ -63,7 +63,7 @@ Remove-Item -Recurse -Force AI-tmp
|
|
|
63
63
|
bash (Linux, macOS o Git Bash):
|
|
64
64
|
|
|
65
65
|
```bash
|
|
66
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
66
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
67
67
|
sh AI-tmp/install.sh --dest .
|
|
68
68
|
rm -rf AI-tmp
|
|
69
69
|
```
|
|
@@ -79,7 +79,7 @@ Descarga solo lo necesario, sin historial git:
|
|
|
79
79
|
PowerShell:
|
|
80
80
|
|
|
81
81
|
```powershell
|
|
82
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
82
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
83
83
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
84
84
|
Remove-Item -Recurse -Force AI-tmp
|
|
85
85
|
```
|
|
@@ -87,7 +87,7 @@ Remove-Item -Recurse -Force AI-tmp
|
|
|
87
87
|
bash:
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
90
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
91
91
|
sh AI-tmp/install.sh --dest .
|
|
92
92
|
rm -rf AI-tmp
|
|
93
93
|
```
|
|
@@ -99,7 +99,7 @@ Clon superficial anclado al tag:
|
|
|
99
99
|
PowerShell:
|
|
100
100
|
|
|
101
101
|
```powershell
|
|
102
|
-
git clone --branch v0.2.
|
|
102
|
+
git clone --branch v0.2.5 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
|
|
103
103
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest .
|
|
104
104
|
Remove-Item -Recurse -Force AI-tmp
|
|
105
105
|
```
|
|
@@ -107,7 +107,7 @@ Remove-Item -Recurse -Force AI-tmp
|
|
|
107
107
|
bash:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
git clone --branch v0.2.
|
|
110
|
+
git clone --branch v0.2.5 --depth 1 https://github.com/horangelmillan/harness-btp AI-tmp
|
|
111
111
|
sh AI-tmp/install.sh --dest .
|
|
112
112
|
rm -rf AI-tmp
|
|
113
113
|
```
|
|
@@ -117,13 +117,14 @@ rm -rf AI-tmp
|
|
|
117
117
|
Sin descargas manuales (requiere publicar `create-harness-btp` en el registry). Igual en todos los SO:
|
|
118
118
|
|
|
119
119
|
```bash
|
|
120
|
-
pnpm dlx create-harness-btp@0.2.
|
|
120
|
+
pnpm dlx create-harness-btp@0.2.5 --dest .
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
### Qué hace el instalador
|
|
124
124
|
|
|
125
125
|
- `CREATE: AI/` o `SKIP: AI/ ya existe` (solo lo reemplaza con `-Force` / `--force`, con backup a `AI.bak`).
|
|
126
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`).
|
|
127
|
+
- Fusiona `.opencode/` raíz desde `AI/.opencode/` (`agents` + `commands` + `skills`, lo que OpenCode descubre en la raíz del proyecto): sin fuerza solo copia los archivos que falten (`SKIP: .opencode/<ruta> ya existe` por cada uno conservado y `CREATE: .opencode/ (+N archivos)`); con `-Force` / `--force` respalda `.opencode/` a `.opencode.bak` (`BACKUP: .opencode/ -> .opencode.bak`) y copia todo.
|
|
127
128
|
- Fusiona `.gitignore`: añade las líneas que falten, sin duplicar ni borrar las tuyas.
|
|
128
129
|
- **No toca** `package.json` ni `mta.yaml` de tu proyecto, nunca.
|
|
129
130
|
|
|
@@ -132,7 +133,8 @@ Salida típica en proyecto nuevo:
|
|
|
132
133
|
```text
|
|
133
134
|
CREATE: AI/
|
|
134
135
|
CREATE: AGENTS.md
|
|
135
|
-
|
|
136
|
+
CREATE: .opencode/ (+17 archivos)
|
|
137
|
+
OK: harness v0.2.5 instalado
|
|
136
138
|
```
|
|
137
139
|
|
|
138
140
|
## Instalación asistida por agente
|
|
@@ -152,7 +154,7 @@ Vale para proyecto nuevo (con URL), existente, Windows/Linux/macOS y cualquier c
|
|
|
152
154
|
PowerShell:
|
|
153
155
|
|
|
154
156
|
```powershell
|
|
155
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
157
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
156
158
|
powershell -ExecutionPolicy Bypass -File AI-tmp/install.ps1 -Dest . -Force
|
|
157
159
|
Remove-Item -Recurse -Force AI-tmp
|
|
158
160
|
# tu versión anterior queda en AI.bak por si quieres comparar
|
|
@@ -161,7 +163,7 @@ Remove-Item -Recurse -Force AI-tmp
|
|
|
161
163
|
bash:
|
|
162
164
|
|
|
163
165
|
```bash
|
|
164
|
-
npx -p degit degit horangelmillan/harness-btp#v0.2.
|
|
166
|
+
npx -p degit degit horangelmillan/harness-btp#v0.2.5 AI-tmp -- AI-tmp
|
|
165
167
|
sh AI-tmp/install.sh --dest . --force
|
|
166
168
|
rm -rf AI-tmp
|
|
167
169
|
# tu versión anterior queda en AI.bak por si quieres comparar
|
|
@@ -213,7 +215,7 @@ harness-btp/
|
|
|
213
215
|
├── install.ps1 / install.sh # instaladores idempotentes (SKIP / CREATE / BACKUP / OK)
|
|
214
216
|
├── bin/ # ejecutable de create-harness-btp (pnpm dlx)
|
|
215
217
|
├── package.json # name create-harness-btp
|
|
216
|
-
└── VERSION # 0.2.
|
|
218
|
+
└── VERSION # 0.2.5
|
|
217
219
|
```
|
|
218
220
|
|
|
219
221
|
## Cómo lo descubre el agente
|
|
@@ -230,11 +232,12 @@ Tú no configuras nada: el agente se adapta solo.
|
|
|
230
232
|
| Problema | Causa | Comando |
|
|
231
233
|
|---|---|---|
|
|
232
234
|
| `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` |
|
|
235
|
+
| 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
236
|
| Mi `AGENTS.md` propio desapareció | se instaló con fuerza | recupera `AGENTS.md.bak` |
|
|
234
237
|
| Líneas duplicadas en `.gitignore` | edición manual tras la fusión | el instalador fusiona sin duplicar; borra el duplicado a mano |
|
|
235
238
|
| `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
239
|
| `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.
|
|
240
|
+
| `degit` falla sin Node | `degit` corre sobre Node 18+ | instala Node o usa `git clone --branch v0.2.5` |
|
|
238
241
|
| 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` |
|
|
239
242
|
| 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
243
|
|
|
@@ -262,6 +265,7 @@ MIT. Haz lo que quieras con el harness; sin garantía.
|
|
|
262
265
|
|
|
263
266
|
## Changelog
|
|
264
267
|
|
|
268
|
+
- **v0.2.5** — 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
269
|
- **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
270
|
- **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
271
|
- **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).
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.2.
|
|
1
|
+
0.2.5
|
package/bin/harness-btp.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// harness-btp init --dest <dir> [--force] [--ref <tag>]
|
|
3
|
-
// Copia AI/, crea AGENTS.md puntero
|
|
3
|
+
// Copia AI/, crea AGENTS.md puntero, fusiona AI/.opencode/ en .opencode/
|
|
4
|
+
// raíz (solo faltantes; con --force hace backup a .opencode.bak) y fusiona .gitignore. Sin secretos.
|
|
4
5
|
// No toca package.json ni mta.yaml del proyecto.
|
|
5
6
|
const fs = require("fs");
|
|
6
7
|
const path = require("path");
|
|
@@ -61,6 +62,43 @@ if (fs.existsSync(agentsDst)) {
|
|
|
61
62
|
console.log("CREATE: AGENTS.md (puntero a AI/AGENTS.md)");
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
const opSrc = path.join(src, "AI", ".opencode");
|
|
66
|
+
const opDst = path.join(dest, ".opencode");
|
|
67
|
+
function listFilesRec(dir, base) {
|
|
68
|
+
let out = [];
|
|
69
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
70
|
+
const p = path.join(dir, e.name);
|
|
71
|
+
if (e.isDirectory()) out = out.concat(listFilesRec(p, base));
|
|
72
|
+
else out.push(path.relative(base, p));
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
if (fs.existsSync(opSrc)) {
|
|
77
|
+
if (force) {
|
|
78
|
+
if (fs.existsSync(opDst)) {
|
|
79
|
+
const opBak = path.join(dest, ".opencode.bak");
|
|
80
|
+
fs.rmSync(opBak, { recursive: true, force: true });
|
|
81
|
+
fs.renameSync(opDst, opBak);
|
|
82
|
+
console.log("BACKUP: .opencode/ -> .opencode.bak");
|
|
83
|
+
}
|
|
84
|
+
fs.cpSync(opSrc, opDst, { recursive: true });
|
|
85
|
+
console.log("CREATE: .opencode/ (+" + listFilesRec(opDst, opDst).length + " archivos)");
|
|
86
|
+
} else {
|
|
87
|
+
let opCount = 0;
|
|
88
|
+
for (const rel of listFilesRec(opSrc, opSrc)) {
|
|
89
|
+
const tgt = path.join(opDst, rel);
|
|
90
|
+
if (fs.existsSync(tgt)) {
|
|
91
|
+
console.log("SKIP: .opencode/" + rel.split(path.sep).join("/") + " ya existe");
|
|
92
|
+
} else {
|
|
93
|
+
fs.mkdirSync(path.dirname(tgt), { recursive: true });
|
|
94
|
+
fs.copyFileSync(path.join(opSrc, rel), tgt);
|
|
95
|
+
opCount++;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
console.log("CREATE: .opencode/ (+" + opCount + " archivos)");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
64
102
|
const frag = fs.readFileSync(path.join(src, "AI", ".gitignore.fragment"), "utf8")
|
|
65
103
|
.split(/\r?\n/).map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
66
104
|
let cur = [];
|
package/install.ps1
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<# Instalador del harness BTP (idempotente, PowerShell 5.1).
|
|
2
2
|
Uso: .\install.ps1 [-Dest "."] [-Force]
|
|
3
3
|
- Copia AI/ al proyecto destino (SKIP si ya existe; con -Force hace backup a AI.bak).
|
|
4
|
+
- Fusiona AI/.opencode/{agents,commands,skills} en .opencode/ raíz (solo faltantes; con -Force hace backup a .opencode.bak).
|
|
4
5
|
- Crea AGENTS.md raíz desde la plantilla solo si no existe.
|
|
5
6
|
- Fusiona .gitignore con las líneas del fragmento (solo agrega faltantes).
|
|
6
7
|
- NO toca package.json ni mta.yaml del proyecto. Sin secretos. #>
|
|
@@ -49,6 +50,38 @@ if (Test-Path $AgentsDst) {
|
|
|
49
50
|
Write-Output "CREATE: AGENTS.md (puntero a AI/AGENTS.md)"
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
$OpSrc = Join-Path $AiSrc ".opencode"
|
|
54
|
+
$OpDst = Join-Path $Dest ".opencode"
|
|
55
|
+
if (Test-Path $OpSrc) {
|
|
56
|
+
if ($Force) {
|
|
57
|
+
if (Test-Path $OpDst) {
|
|
58
|
+
$OpBak = Join-Path $Dest ".opencode.bak"
|
|
59
|
+
if (Test-Path $OpBak) { Remove-Item $OpBak -Recurse -Force }
|
|
60
|
+
Rename-Item $OpDst ".opencode.bak"
|
|
61
|
+
Write-Output "BACKUP: .opencode/ -> .opencode.bak"
|
|
62
|
+
}
|
|
63
|
+
Copy-Item $OpSrc $OpDst -Recurse -Force
|
|
64
|
+
$OpCount = @(Get-ChildItem $OpDst -Recurse -File).Count
|
|
65
|
+
Write-Output ("CREATE: .opencode/ (+{0} archivos)" -f $OpCount)
|
|
66
|
+
} else {
|
|
67
|
+
$OpCount = 0
|
|
68
|
+
$OpFiles = @(Get-ChildItem $OpSrc -Recurse -File)
|
|
69
|
+
foreach ($f in $OpFiles) {
|
|
70
|
+
$rel = $f.FullName.Substring($OpSrc.Length + 1)
|
|
71
|
+
$tgt = Join-Path $OpDst $rel
|
|
72
|
+
if (Test-Path $tgt) {
|
|
73
|
+
Write-Output ("SKIP: .opencode/{0} ya existe" -f ($rel -replace "\\","/"))
|
|
74
|
+
} else {
|
|
75
|
+
$tgtDir = Split-Path -Parent $tgt
|
|
76
|
+
if (-not (Test-Path $tgtDir)) { New-Item $tgtDir -ItemType Directory -Force | Out-Null }
|
|
77
|
+
Copy-Item $f.FullName $tgt -Force
|
|
78
|
+
$OpCount++
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
Write-Output ("CREATE: .opencode/ (+{0} archivos)" -f $OpCount)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
52
85
|
$Frag = Join-Path $AiSrc ".gitignore.fragment"
|
|
53
86
|
$GiDst = Join-Path $Dest ".gitignore"
|
|
54
87
|
$lines = Get-Content $Frag | Where-Object { $_.Trim() -ne "" -and -not $_.Trim().StartsWith("#") }
|
package/install.sh
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
# Instalador del harness BTP (idempotente, POSIX sh).
|
|
3
3
|
# Uso: ./install.sh [--dest <dir>] [--force] [--help]
|
|
4
4
|
# Sin secretos. No toca package.json ni mta.yaml del proyecto.
|
|
5
|
+
# Fusiona AI/.opencode/{agents,commands,skills} en .opencode/ raíz
|
|
6
|
+
# (solo faltantes; con --force hace backup a .opencode.bak).
|
|
5
7
|
DEST="."
|
|
6
8
|
FORCE=0
|
|
7
9
|
while [ $# -gt 0 ]; do
|
|
@@ -43,6 +45,34 @@ else
|
|
|
43
45
|
cp "$SRC/templates/AGENTS.pointer.md" "$DEST/AGENTS.md" && echo "CREATE: AGENTS.md (puntero a AI/AGENTS.md)"
|
|
44
46
|
fi
|
|
45
47
|
|
|
48
|
+
OP_SRC="$SRC/AI/.opencode"
|
|
49
|
+
OP_DST="$DEST/.opencode"
|
|
50
|
+
if [ -d "$OP_SRC" ]; then
|
|
51
|
+
if [ "$FORCE" -eq 1 ]; then
|
|
52
|
+
if [ -d "$OP_DST" ]; then
|
|
53
|
+
rm -rf "$DEST/.opencode.bak" && mv "$DEST/.opencode" "$DEST/.opencode.bak"
|
|
54
|
+
echo "BACKUP: .opencode/ -> .opencode.bak"
|
|
55
|
+
fi
|
|
56
|
+
cp -r "$OP_SRC" "$OP_DST" && OP_COUNT=$(find "$OP_DST" -type f | wc -l) && echo "CREATE: .opencode/ (+$OP_COUNT archivos)"
|
|
57
|
+
else
|
|
58
|
+
OP_COUNT=0
|
|
59
|
+
OP_LIST="${TMPDIR:-/tmp}/harness-opcount-$$.tmp"
|
|
60
|
+
find "$OP_SRC" -type f -print > "$OP_LIST"
|
|
61
|
+
while IFS= read -r OP_FILE; do
|
|
62
|
+
OP_REL=${OP_FILE#"$OP_SRC"/}
|
|
63
|
+
if [ -f "$OP_DST/$OP_REL" ]; then
|
|
64
|
+
echo "SKIP: .opencode/$OP_REL ya existe"
|
|
65
|
+
else
|
|
66
|
+
mkdir -p "$(dirname "$OP_DST/$OP_REL")"
|
|
67
|
+
cp "$OP_FILE" "$OP_DST/$OP_REL"
|
|
68
|
+
OP_COUNT=$((OP_COUNT + 1))
|
|
69
|
+
fi
|
|
70
|
+
done < "$OP_LIST"
|
|
71
|
+
rm -f "$OP_LIST"
|
|
72
|
+
echo "CREATE: .opencode/ (+$OP_COUNT archivos)"
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
|
|
46
76
|
FRAG="$SRC/AI/.gitignore.fragment"
|
|
47
77
|
touch "$DEST/.gitignore"
|
|
48
78
|
ADDED=0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-harness-btp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
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",
|