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
package/install.ps1 CHANGED
@@ -1,12 +1,18 @@
1
1
  <# Instalador del harness BTP (idempotente, PowerShell 5.1).
2
- Uso: .\install.ps1 [-Dest "."] [-Force]
2
+ Uso: .\install.ps1 [-Dest "."] [-Force] [-Client auto]
3
3
  - Copia AI/ al proyecto destino (SKIP si ya existe; con -Force hace backup a AI.bak).
4
+ - Fusiona el árbol del cliente agéntico desde AI/clients/<cliente>/ en la raíz
5
+ (solo faltantes; con -Force hace backup a <dir>.bak):
6
+ -Client auto (defecto): detecta por huellas (CLAUDE.md|.claude→claude,
7
+ .cursor→cursor, .github→copilot, opencode.json*|.opencode→opencode;
8
+ sin huellas→opencode) | all: todos | lista explícita (p. ej. claude,copilot).
4
9
  - Crea AGENTS.md raíz desde la plantilla solo si no existe.
5
10
  - Fusiona .gitignore con las líneas del fragmento (solo agrega faltantes).
6
11
  - NO toca package.json ni mta.yaml del proyecto. Sin secretos. #>
7
12
  param(
8
13
  [string]$Dest = ".",
9
- [switch]$Force
14
+ [switch]$Force,
15
+ $Client = "auto"
10
16
  )
11
17
 
12
18
  $ErrorActionPreference = "Stop"
@@ -49,6 +55,83 @@ if (Test-Path $AgentsDst) {
49
55
  Write-Output "CREATE: AGENTS.md (puntero a AI/AGENTS.md)"
50
56
  }
51
57
 
58
+ $ClientsSrc = Join-Path $AiSrc "clients"
59
+
60
+ function Get-ClientList($Spec, $DestDir) {
61
+ $s = (($Spec -join ",") + "").Trim().ToLower()
62
+ if ($s -eq "auto") {
63
+ $d = @()
64
+ if ((Test-Path (Join-Path $DestDir "CLAUDE.md")) -or (Test-Path (Join-Path $DestDir ".claude"))) { $d += "claude" }
65
+ if (Test-Path (Join-Path $DestDir ".cursor")) { $d += "cursor" }
66
+ if (Test-Path (Join-Path $DestDir ".github")) { $d += "copilot" }
67
+ $opHints = @(Get-ChildItem $DestDir -Filter "opencode.json*" -File -ErrorAction SilentlyContinue)
68
+ if (($opHints.Count -gt 0) -or (Test-Path (Join-Path $DestDir ".opencode"))) { $d += "opencode" }
69
+ if ($d.Count -eq 0) { $d = @("opencode") }
70
+ return $d
71
+ }
72
+ if ($s -eq "all") { return @("opencode", "claude", "cursor", "copilot") }
73
+ $list = @($s -split "," | ForEach-Object { $_.Trim().ToLower() } | Where-Object { $_ -ne "" })
74
+ $known = @("opencode", "claude", "cursor", "copilot", "aider")
75
+ foreach ($c in $list) {
76
+ if ($known -notcontains $c) { Write-Host "ABORT: cliente desconocido '$c' (usa auto|all|opencode,claude,cursor,copilot,aider)"; exit 1 }
77
+ }
78
+ if ($list.Count -eq 0) { Write-Host "ABORT: -Client vacío (usa auto|all|opencode,claude,cursor,copilot,aider)"; exit 1 }
79
+ return $list
80
+ }
81
+
82
+ function Merge-Tree($TreeSrc, $TreeDst, $Label) {
83
+ if (-not (Test-Path $TreeSrc)) { Write-Output "AVISO: no existe $TreeSrc (regenera con node scripts/render-clients.js)"; return }
84
+ $BakLabel = $Label.TrimEnd("/") + ".bak"
85
+ if ($Force) {
86
+ if (Test-Path $TreeDst) {
87
+ $Bak = "$TreeDst.bak"
88
+ if (Test-Path $Bak) { Remove-Item $Bak -Recurse -Force }
89
+ Rename-Item $TreeDst ([IO.Path]::GetFileName($Bak))
90
+ Write-Output "BACKUP: $Label -> $BakLabel"
91
+ }
92
+ Copy-Item $TreeSrc $TreeDst -Recurse -Force
93
+ $TreeCount = @(Get-ChildItem $TreeDst -Recurse -File).Count
94
+ Write-Output ("CREATE: {0} (+{1} archivos)" -f $Label, $TreeCount)
95
+ } else {
96
+ $TreeCount = 0
97
+ $TreeFiles = @(Get-ChildItem $TreeSrc -Recurse -File)
98
+ foreach ($f in $TreeFiles) {
99
+ $rel = $f.FullName.Substring($TreeSrc.Length + 1)
100
+ $tgt = Join-Path $TreeDst $rel
101
+ if (Test-Path $tgt) {
102
+ Write-Output ("SKIP: {0}{1} ya existe" -f $Label, ($rel -replace "\\","/"))
103
+ } else {
104
+ $tgtDir = Split-Path -Parent $tgt
105
+ if (-not (Test-Path $tgtDir)) { New-Item $tgtDir -ItemType Directory -Force | Out-Null }
106
+ Copy-Item $f.FullName $tgt -Force
107
+ $TreeCount++
108
+ }
109
+ }
110
+ Write-Output ("CREATE: {0} (+{1} archivos)" -f $Label, $TreeCount)
111
+ }
112
+ }
113
+
114
+ $SelectedClients = @(Get-ClientList $Client $Dest)
115
+ if ((($Client -join ",") + "").Trim().ToLower() -eq "auto") {
116
+ Write-Output ("CLIENT: auto -> {0}" -f ($SelectedClients -join ","))
117
+ }
118
+ foreach ($c in $SelectedClients) {
119
+ if ($c -eq "opencode") {
120
+ Merge-Tree (Join-Path $ClientsSrc "opencode") (Join-Path $Dest ".opencode") ".opencode/"
121
+ } elseif ($c -eq "claude") {
122
+ Merge-Tree (Join-Path $ClientsSrc "claude") (Join-Path $Dest ".claude") ".claude/"
123
+ } elseif ($c -eq "cursor") {
124
+ Merge-Tree (Join-Path $ClientsSrc "cursor\commands") (Join-Path $Dest ".cursor\commands") ".cursor/commands/"
125
+ Merge-Tree (Join-Path $ClientsSrc "cursor\skills") (Join-Path $Dest ".agents\skills") ".agents/skills/"
126
+ } elseif ($c -eq "copilot") {
127
+ Merge-Tree (Join-Path $ClientsSrc "copilot\agents") (Join-Path $Dest ".github\agents") ".github/agents/"
128
+ Merge-Tree (Join-Path $ClientsSrc "copilot\skills") (Join-Path $Dest ".github\skills") ".github/skills/"
129
+ Merge-Tree (Join-Path $ClientsSrc "copilot\prompts") (Join-Path $Dest ".github\prompts") ".github/prompts/"
130
+ } elseif ($c -eq "aider") {
131
+ Write-Output "SKIP: aider usa AGENTS.md raiz (nada que fusionar)"
132
+ }
133
+ }
134
+
52
135
  $Frag = Join-Path $AiSrc ".gitignore.fragment"
53
136
  $GiDst = Join-Path $Dest ".gitignore"
54
137
  $lines = Get-Content $Frag | Where-Object { $_.Trim() -ne "" -and -not $_.Trim().StartsWith("#") }
package/install.sh CHANGED
@@ -1,18 +1,26 @@
1
1
  #!/bin/sh
2
2
  # Instalador del harness BTP (idempotente, POSIX sh).
3
- # Uso: ./install.sh [--dest <dir>] [--force] [--help]
3
+ # Uso: ./install.sh [--dest <dir>] [--force] [--client auto|all|opencode,claude,...] [--help]
4
4
  # Sin secretos. No toca package.json ni mta.yaml del proyecto.
5
+ # Fusiona el árbol del cliente agéntico desde AI/clients/<cliente>/ en la raíz
6
+ # (solo faltantes; con --force hace backup a <dir>.bak).
7
+ # --client auto (defecto): detecta por huellas (CLAUDE.md|.claude→claude,
8
+ # .cursor→cursor, .github→copilot, opencode.json*|.opencode→opencode;
9
+ # sin huellas→opencode). all: todos. Lista explícita: esos.
5
10
  DEST="."
6
11
  FORCE=0
12
+ CLIENT="auto"
7
13
  while [ $# -gt 0 ]; do
8
14
  case "$1" in
9
15
  --dest) DEST="$2"; shift 2 ;;
10
16
  --force) FORCE=1; shift ;;
17
+ --client) CLIENT="$2"; shift 2 ;;
11
18
  -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"
19
+ echo "Uso: ./install.sh [--dest <dir>] [--force] [--client <clientes>] [--help]"
20
+ echo " --dest <dir> proyecto destino (por defecto: .)"
21
+ echo " --force reinstala AI/ con backup a AI.bak"
22
+ echo " --client <list> auto (defecto) | all | opencode,claude,cursor,copilot,aider"
23
+ echo " -h, --help muestra esta ayuda"
16
24
  exit 0 ;;
17
25
  *) echo "ABORT: opción desconocida $1 (usa --help)"; exit 1 ;;
18
26
  esac
@@ -43,6 +51,88 @@ else
43
51
  cp "$SRC/templates/AGENTS.pointer.md" "$DEST/AGENTS.md" && echo "CREATE: AGENTS.md (puntero a AI/AGENTS.md)"
44
52
  fi
45
53
 
54
+ # Fusion idempotente de un arbol: merge_tree <origen> <destino> <etiqueta>
55
+ # (etiqueta p. ej. ".opencode/"; el backup va a <destino>.bak).
56
+ merge_tree() {
57
+ MT_SRC="$1"; MT_DST="$2"; MT_LABEL="$3"
58
+ if [ ! -d "$MT_SRC" ]; then echo "AVISO: no existe $MT_SRC (regenera con node scripts/render-clients.js)"; return 0; fi
59
+ MT_BAKLABEL="$(printf '%s' "$MT_LABEL" | sed 's:/$::').bak"
60
+ if [ "$FORCE" -eq 1 ]; then
61
+ if [ -d "$MT_DST" ]; then
62
+ rm -rf "$MT_DST.bak" && mv "$MT_DST" "$MT_DST.bak"
63
+ echo "BACKUP: $MT_LABEL -> $MT_BAKLABEL"
64
+ fi
65
+ mkdir -p "$(dirname "$MT_DST")"
66
+ cp -r "$MT_SRC" "$MT_DST" && MT_COUNT=$(find "$MT_DST" -type f | wc -l) && echo "CREATE: $MT_LABEL (+$MT_COUNT archivos)"
67
+ else
68
+ MT_COUNT=0
69
+ MT_LIST="${TMPDIR:-/tmp}/harness-mt-$$.tmp"
70
+ find "$MT_SRC" -type f -print > "$MT_LIST"
71
+ while IFS= read -r MT_FILE; do
72
+ MT_REL=${MT_FILE#"$MT_SRC"/}
73
+ if [ -f "$MT_DST/$MT_REL" ]; then
74
+ echo "SKIP: $MT_LABEL$MT_REL ya existe"
75
+ else
76
+ mkdir -p "$(dirname "$MT_DST/$MT_REL")"
77
+ cp "$MT_FILE" "$MT_DST/$MT_REL"
78
+ MT_COUNT=$((MT_COUNT + 1))
79
+ fi
80
+ done < "$MT_LIST"
81
+ rm -f "$MT_LIST"
82
+ echo "CREATE: $MT_LABEL (+$MT_COUNT archivos)"
83
+ fi
84
+ }
85
+
86
+ # Resuelve la lista de clientes: detecta huellas en auto, valida explícitos.
87
+ resolve_clients() {
88
+ case "$CLIENT" in
89
+ auto)
90
+ RC_LIST=""
91
+ { [ -f "$DEST/CLAUDE.md" ] || [ -d "$DEST/.claude" ]; } && RC_LIST="$RC_LIST claude"
92
+ [ -d "$DEST/.cursor" ] && RC_LIST="$RC_LIST cursor"
93
+ [ -d "$DEST/.github" ] && RC_LIST="$RC_LIST copilot"
94
+ if ls "$DEST"/opencode.json* >/dev/null 2>&1 || [ -d "$DEST/.opencode" ]; then RC_LIST="$RC_LIST opencode"; fi
95
+ [ -z "$RC_LIST" ] && RC_LIST=" opencode"
96
+ echo "CLIENT: auto -> $(printf '%s' "$RC_LIST" | tr ' ' ',' | sed 's/^,//')" >&2
97
+ printf '%s' "$RC_LIST"
98
+ ;;
99
+ all) printf ' opencode claude cursor copilot' ;;
100
+ *)
101
+ RC_OUT=""
102
+ RC_REST="$CLIENT,"
103
+ while [ -n "$RC_REST" ]; do
104
+ RC_ONE=${RC_REST%%,*}; RC_REST=${RC_REST#*,}
105
+ RC_ONE=$(printf '%s' "$RC_ONE" | tr 'A-Z' 'a-z' | tr -d ' ')
106
+ [ -z "$RC_ONE" ] && continue
107
+ case "$RC_ONE" in
108
+ opencode|claude|cursor|copilot|aider) RC_OUT="$RC_OUT $RC_ONE" ;;
109
+ *) echo "ABORT: cliente desconocido '$RC_ONE' (usa auto|all|opencode,claude,cursor,copilot,aider)" >&2; exit 1 ;;
110
+ esac
111
+ done
112
+ [ -z "$RC_OUT" ] && { echo "ABORT: --client vacío (usa auto|all|opencode,claude,cursor,copilot,aider)" >&2; exit 1; }
113
+ printf '%s' "$RC_OUT"
114
+ ;;
115
+ esac
116
+ }
117
+
118
+ CLIENTS_SRC="$SRC/AI/clients"
119
+ RC_RESOLVED=$(resolve_clients); RC_STATUS=$?
120
+ if [ "$RC_STATUS" -ne 0 ]; then exit "$RC_STATUS"; fi
121
+ for C in $RC_RESOLVED; do
122
+ case "$C" in
123
+ opencode) merge_tree "$CLIENTS_SRC/opencode" "$DEST/.opencode" ".opencode/" ;;
124
+ claude) merge_tree "$CLIENTS_SRC/claude" "$DEST/.claude" ".claude/" ;;
125
+ cursor)
126
+ merge_tree "$CLIENTS_SRC/cursor/commands" "$DEST/.cursor/commands" ".cursor/commands/"
127
+ merge_tree "$CLIENTS_SRC/cursor/skills" "$DEST/.agents/skills" ".agents/skills/" ;;
128
+ copilot)
129
+ merge_tree "$CLIENTS_SRC/copilot/agents" "$DEST/.github/agents" ".github/agents/"
130
+ merge_tree "$CLIENTS_SRC/copilot/skills" "$DEST/.github/skills" ".github/skills/"
131
+ merge_tree "$CLIENTS_SRC/copilot/prompts" "$DEST/.github/prompts" ".github/prompts/" ;;
132
+ aider) echo "SKIP: aider usa AGENTS.md raiz (nada que fusionar)" ;;
133
+ esac
134
+ done
135
+
46
136
  FRAG="$SRC/AI/.gitignore.fragment"
47
137
  touch "$DEST/.gitignore"
48
138
  ADDED=0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-harness-btp",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
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",