create-quiver 0.4.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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +15 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
- package/.github/pull_request_template.md +4 -0
- package/.github/workflows/ci.yml +74 -0
- package/CHANGELOG.md +24 -0
- package/CODE_OF_CONDUCT.md +12 -0
- package/CONTRIBUTING.md +15 -0
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/README_FOR_AI.md +90 -0
- package/ROADMAP.md +20 -0
- package/SECURITY.md +12 -0
- package/TEMPLATE.md +108 -0
- package/bin/create-quiver.js +8 -0
- package/docs/CONTEXTO.md.template +45 -0
- package/docs/DOCUMENTATION_GUIDE.md.template +34 -0
- package/docs/GITFLOW_PR_GUIDE.md.template +52 -0
- package/docs/INDEX.md.template +41 -0
- package/docs/MOCK_DATA_GUIDE.md.template +31 -0
- package/docs/MULTI_AGENT_WORKFLOW.md.template +31 -0
- package/docs/STATUS.md.template +26 -0
- package/docs/SUPPORT_MATRIX.md.template +31 -0
- package/docs/TESTING_GUIDE_FOR_AI.md.template +42 -0
- package/docs/TROUBLESHOOTING.md.template +70 -0
- package/docs/UI_STANDARDS.md.template +31 -0
- package/docs/WORKFLOW.md.template +56 -0
- package/docs/ai/LESSONS.md.template +24 -0
- package/docs/ai/PRINCIPLES.md +25 -0
- package/docs/ai/RULES.yaml +33 -0
- package/i18n/es/README.md +15 -0
- package/i18n/es/README_FOR_AI.md +6 -0
- package/i18n/es/TEMPLATE.md +18 -0
- package/i18n/es/docs/CONTEXTO.md.template +9 -0
- package/i18n/es/docs/DOCUMENTATION_GUIDE.md.template +4 -0
- package/i18n/es/docs/GITFLOW_PR_GUIDE.md.template +4 -0
- package/i18n/es/docs/INDEX.md.template +10 -0
- package/i18n/es/docs/MOCK_DATA_GUIDE.md.template +4 -0
- package/i18n/es/docs/MULTI_AGENT_WORKFLOW.md.template +4 -0
- package/i18n/es/docs/STATUS.md.template +9 -0
- package/i18n/es/docs/TESTING_GUIDE_FOR_AI.md.template +7 -0
- package/i18n/es/docs/UI_STANDARDS.md.template +4 -0
- package/i18n/es/docs/WORKFLOW.md.template +6 -0
- package/i18n/es/docs/ai/LESSONS.md.template +3 -0
- package/i18n/es/docs/ai/PRINCIPLES.md +7 -0
- package/i18n/es/docs/ai/RULES.yaml +7 -0
- package/package.json +19 -0
- package/package.template.json +10 -0
- package/scripts/check-pr-readiness.sh +138 -0
- package/scripts/check-scope.sh +150 -0
- package/scripts/check-slice-readiness.sh +319 -0
- package/scripts/cleanup-slice.sh +177 -0
- package/scripts/init-docs.sh +368 -0
- package/scripts/migrate-project.sh +218 -0
- package/scripts/package-quiver.sh +124 -0
- package/scripts/refresh-active-slices.sh +232 -0
- package/scripts/release-quiver.sh +77 -0
- package/scripts/start-slice.sh +429 -0
- package/specs/[project-name]/EVIDENCE_REPORT.md.template +15 -0
- package/specs/[project-name]/SPEC.md.template +39 -0
- package/specs/[project-name]/STATUS.md.template +22 -0
- package/specs/[project-name]/slices/pr.md.template +97 -0
- package/specs/[project-name]/slices/slice-template/slice.json +69 -0
- package/specs/quiver-v05-readme-adoption-contract/EVIDENCE_REPORT.md +21 -0
- package/specs/quiver-v05-readme-adoption-contract/SPEC.md +40 -0
- package/specs/quiver-v05-readme-adoption-contract/STATUS.md +24 -0
- package/specs/quiver-v05-readme-adoption-contract/slices/slice-01-readme-adoption-contract/slice.json +68 -0
- package/specs/quiver-v06-release-readiness/EVIDENCE_REPORT.md +23 -0
- package/specs/quiver-v06-release-readiness/SPEC.md +40 -0
- package/specs/quiver-v06-release-readiness/STATUS.md +24 -0
- package/specs/quiver-v06-release-readiness/slices/slice-01-first-npm-release-readiness/slice.json +71 -0
- package/src/create-quiver/index.js +329 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
usage() {
|
|
6
|
+
cat <<'EOF'
|
|
7
|
+
Uso:
|
|
8
|
+
bash tools/scripts/cleanup-slice.sh <ruta-al-slice.json> [--close-baseline] [--discard] [--force] [--dry-run]
|
|
9
|
+
|
|
10
|
+
Politica:
|
|
11
|
+
- slice-00: queda congelado por default; no se elimina salvo --close-baseline
|
|
12
|
+
- slice-01+: se elimina despues de merge/rechazo/reemplazo segun la politica del repo
|
|
13
|
+
|
|
14
|
+
Opciones:
|
|
15
|
+
--close-baseline Permite cerrar y eliminar un slice-00 congelado
|
|
16
|
+
--discard Permite cerrar un slice no mergeado (descartado/reemplazado)
|
|
17
|
+
--force Fuerza git worktree remove --force y git branch -D
|
|
18
|
+
--dry-run Solo informa que haria, no ejecuta cambios
|
|
19
|
+
EOF
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
fail() {
|
|
23
|
+
echo "FAIL: $1" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
pass() {
|
|
28
|
+
echo "PASS: $1"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
close_baseline="false"
|
|
32
|
+
discard="false"
|
|
33
|
+
force_delete="false"
|
|
34
|
+
dry_run="false"
|
|
35
|
+
slice_input=""
|
|
36
|
+
|
|
37
|
+
while [[ $# -gt 0 ]]; do
|
|
38
|
+
case "$1" in
|
|
39
|
+
-h|--help)
|
|
40
|
+
usage
|
|
41
|
+
exit 0
|
|
42
|
+
;;
|
|
43
|
+
--close-baseline)
|
|
44
|
+
close_baseline="true"
|
|
45
|
+
;;
|
|
46
|
+
--discard)
|
|
47
|
+
discard="true"
|
|
48
|
+
;;
|
|
49
|
+
--force)
|
|
50
|
+
force_delete="true"
|
|
51
|
+
;;
|
|
52
|
+
--dry-run)
|
|
53
|
+
dry_run="true"
|
|
54
|
+
;;
|
|
55
|
+
-*)
|
|
56
|
+
fail "Opcion desconocida: $1"
|
|
57
|
+
;;
|
|
58
|
+
*)
|
|
59
|
+
if [[ -n "$slice_input" ]]; then
|
|
60
|
+
fail "Solo se acepta un slice por ejecucion."
|
|
61
|
+
fi
|
|
62
|
+
slice_input="$1"
|
|
63
|
+
;;
|
|
64
|
+
esac
|
|
65
|
+
shift
|
|
66
|
+
done
|
|
67
|
+
|
|
68
|
+
[[ -n "$slice_input" ]] || {
|
|
69
|
+
usage
|
|
70
|
+
exit 1
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
command -v git >/dev/null 2>&1 || fail "git no esta disponible en PATH."
|
|
74
|
+
command -v node >/dev/null 2>&1 || fail "node no esta disponible en PATH."
|
|
75
|
+
|
|
76
|
+
repo_root="$(git rev-parse --show-toplevel)"
|
|
77
|
+
|
|
78
|
+
[[ -f "$slice_input" ]] || fail "No existe el slice '$slice_input'."
|
|
79
|
+
|
|
80
|
+
slice_abs="$(cd "$(dirname "$slice_input")" && pwd)/$(basename "$slice_input")"
|
|
81
|
+
|
|
82
|
+
slice_meta=()
|
|
83
|
+
while IFS= read -r line; do
|
|
84
|
+
slice_meta+=("$line")
|
|
85
|
+
done < <(node - "$slice_abs" "$repo_root" <<'NODE'
|
|
86
|
+
const fs = require('fs');
|
|
87
|
+
const path = require('path');
|
|
88
|
+
|
|
89
|
+
const [slicePath, repoRoot] = process.argv.slice(2);
|
|
90
|
+
const json = JSON.parse(fs.readFileSync(slicePath, 'utf8'));
|
|
91
|
+
|
|
92
|
+
const branchName = String(json.git?.branch_name || '').trim();
|
|
93
|
+
const sliceId = String(json.slice_id || '').trim();
|
|
94
|
+
const isBaseline = sliceId.startsWith('slice-00');
|
|
95
|
+
const repoName = path.basename(repoRoot);
|
|
96
|
+
const repoParent = path.dirname(repoRoot);
|
|
97
|
+
const worktreesRoot = process.env.SLICE_WORKTREES_DIR || path.join(repoParent, '.worktrees', repoName);
|
|
98
|
+
const safeBranchName = branchName.replace(/[^A-Za-z0-9._-]/g, '-');
|
|
99
|
+
const worktreePath = path.join(worktreesRoot, safeBranchName);
|
|
100
|
+
|
|
101
|
+
console.log(branchName);
|
|
102
|
+
console.log(sliceId);
|
|
103
|
+
console.log(isBaseline ? 'true' : 'false');
|
|
104
|
+
console.log(worktreePath);
|
|
105
|
+
NODE
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
[[ ${#slice_meta[@]} -eq 4 ]] || fail "No se pudo leer la metadata de cleanup del slice."
|
|
109
|
+
|
|
110
|
+
branch_name="${slice_meta[0]}"
|
|
111
|
+
slice_id="${slice_meta[1]}"
|
|
112
|
+
is_baseline="${slice_meta[2]}"
|
|
113
|
+
worktree_path="${slice_meta[3]}"
|
|
114
|
+
|
|
115
|
+
[[ -n "$branch_name" ]] || fail "Falta git.branch_name en el slice."
|
|
116
|
+
|
|
117
|
+
if [[ "$is_baseline" == "true" && "$close_baseline" != "true" ]]; then
|
|
118
|
+
echo "INFO: '$slice_id' es baseline. El worktree queda congelado por default."
|
|
119
|
+
echo "INFO: Usa --close-baseline solo cuando la primera ola del spec ya este estable o mergeada."
|
|
120
|
+
exit 0
|
|
121
|
+
fi
|
|
122
|
+
|
|
123
|
+
current_branch="$(git branch --show-current)"
|
|
124
|
+
|
|
125
|
+
if [[ "$discard" != "true" ]]; then
|
|
126
|
+
[[ "$current_branch" == "develop" ]] || fail "El cleanup normal debe correrse desde develop. Rama actual: $current_branch"
|
|
127
|
+
[[ -z "$(git status --porcelain)" ]] || fail "El checkout actual no esta limpio. Limpialo antes del cleanup."
|
|
128
|
+
|
|
129
|
+
git fetch origin develop >/dev/null 2>&1 || true
|
|
130
|
+
|
|
131
|
+
local_develop_sha="$(git rev-parse HEAD)"
|
|
132
|
+
remote_develop_sha="$(git rev-parse origin/develop)"
|
|
133
|
+
[[ "$local_develop_sha" == "$remote_develop_sha" ]] || fail "develop local no esta actualizado. Ejecuta git pull --ff-only antes del cleanup."
|
|
134
|
+
|
|
135
|
+
if git show-ref --verify --quiet "refs/heads/$branch_name"; then
|
|
136
|
+
git merge-base --is-ancestor "$branch_name" "origin/develop" || fail "La rama '$branch_name' no esta mergeada en origin/develop. Usa --discard si el slice se descarta."
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
worktree_exists="false"
|
|
141
|
+
branch_exists="false"
|
|
142
|
+
|
|
143
|
+
[[ -d "$worktree_path" ]] && worktree_exists="true"
|
|
144
|
+
git show-ref --verify --quiet "refs/heads/$branch_name" && branch_exists="true"
|
|
145
|
+
|
|
146
|
+
[[ "$worktree_exists" == "true" || "$branch_exists" == "true" ]] || fail "No existe worktree ni rama local para '$slice_id'."
|
|
147
|
+
|
|
148
|
+
remove_worktree_cmd=(git worktree remove "$worktree_path")
|
|
149
|
+
remove_branch_cmd=(git branch -d "$branch_name")
|
|
150
|
+
|
|
151
|
+
if [[ "$force_delete" == "true" || "$discard" == "true" ]]; then
|
|
152
|
+
remove_worktree_cmd=(git worktree remove --force "$worktree_path")
|
|
153
|
+
remove_branch_cmd=(git branch -D "$branch_name")
|
|
154
|
+
fi
|
|
155
|
+
|
|
156
|
+
if [[ "$dry_run" == "true" ]]; then
|
|
157
|
+
echo "DRY RUN: slice=$slice_id branch=$branch_name"
|
|
158
|
+
[[ "$worktree_exists" == "true" ]] && echo "DRY RUN: ${remove_worktree_cmd[*]}"
|
|
159
|
+
[[ "$branch_exists" == "true" ]] && echo "DRY RUN: ${remove_branch_cmd[*]}"
|
|
160
|
+
exit 0
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
if [[ "$worktree_exists" == "true" ]]; then
|
|
164
|
+
"${remove_worktree_cmd[@]}"
|
|
165
|
+
pass "Worktree eliminado: $worktree_path"
|
|
166
|
+
fi
|
|
167
|
+
|
|
168
|
+
if [[ "$branch_exists" == "true" ]]; then
|
|
169
|
+
"${remove_branch_cmd[@]}"
|
|
170
|
+
pass "Rama local eliminada: $branch_name"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
if [[ -x "$repo_root/tools/scripts/refresh-active-slices.sh" ]]; then
|
|
174
|
+
"$repo_root/tools/scripts/refresh-active-slices.sh" >/dev/null 2>&1 || true
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
pass "Cleanup finalizado para '$slice_id'."
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Script de Inicialización de Documentación
|
|
4
|
+
# Uso: ./init-docs.sh "Nombre del Proyecto"
|
|
5
|
+
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
# Colores para output
|
|
9
|
+
RED='\033[0;31m'
|
|
10
|
+
GREEN='\033[0;32m'
|
|
11
|
+
YELLOW='\033[1;33m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
NC='\033[0m' # No Color
|
|
14
|
+
|
|
15
|
+
# Función para imprimir mensajes
|
|
16
|
+
print_info() {
|
|
17
|
+
echo -e "${BLUE}ℹ️ $1${NC}"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
print_success() {
|
|
21
|
+
echo -e "${GREEN}✅ $1${NC}"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
print_warning() {
|
|
25
|
+
echo -e "${YELLOW}⚠️ $1${NC}"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
print_error() {
|
|
29
|
+
echo -e "${RED}❌ $1${NC}"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Verificar argumento
|
|
33
|
+
if [ -z "$1" ]; then
|
|
34
|
+
print_error "Nombre del proyecto requerido"
|
|
35
|
+
echo "Uso: ./init-docs.sh \"Nombre del Proyecto\""
|
|
36
|
+
echo "Ejemplo: ./init-docs.sh \"Mi Proyecto\""
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
PROJECT_NAME="$1"
|
|
41
|
+
PROJECT_SLUG=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]-')
|
|
42
|
+
CURRENT_DATE=$(date +%Y-%m-%d)
|
|
43
|
+
DATE_PLUS_7=$(node -e 'const d = new Date(); d.setDate(d.getDate() + 7); const p = (n) => String(n).padStart(2, "0"); console.log(`${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`);')
|
|
44
|
+
DATE_PLUS_30=$(node -e 'const d = new Date(); d.setDate(d.getDate() + 30); const p = (n) => String(n).padStart(2, "0"); console.log(`${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`);')
|
|
45
|
+
DATE_PLUS_35=$(node -e 'const d = new Date(); d.setDate(d.getDate() + 35); const p = (n) => String(n).padStart(2, "0"); console.log(`${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`);')
|
|
46
|
+
|
|
47
|
+
print_info "Inicializando documentación para: $PROJECT_NAME"
|
|
48
|
+
print_info "Project slug: $PROJECT_SLUG"
|
|
49
|
+
print_info "Fecha: $CURRENT_DATE"
|
|
50
|
+
|
|
51
|
+
# Verificar que existe docs-template/
|
|
52
|
+
if [ ! -d "docs-template" ]; then
|
|
53
|
+
print_error "No se encontró docs-template/"
|
|
54
|
+
print_error "Asegurate de estar en el directorio correcto"
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Crear directorios base
|
|
59
|
+
print_info "Creando estructura de directorios..."
|
|
60
|
+
|
|
61
|
+
mkdir -p "docs"
|
|
62
|
+
mkdir -p "docs/ai"
|
|
63
|
+
mkdir -p "docs/tools"
|
|
64
|
+
mkdir -p "docs/archive"
|
|
65
|
+
mkdir -p "specs/$PROJECT_SLUG/slices/slice-template"
|
|
66
|
+
mkdir -p "tools/scripts"
|
|
67
|
+
|
|
68
|
+
# Copiar templates y reemplazar placeholders
|
|
69
|
+
print_info "Copiando templates..."
|
|
70
|
+
|
|
71
|
+
# Función para copiar y reemplazar
|
|
72
|
+
copy_template() {
|
|
73
|
+
local src="$1"
|
|
74
|
+
local dest="$2"
|
|
75
|
+
|
|
76
|
+
if [ -f "$src" ]; then
|
|
77
|
+
# Remover .template del nombre si existe
|
|
78
|
+
dest=$(echo "$dest" | sed 's/\.template$//')
|
|
79
|
+
|
|
80
|
+
# Copiar y reemplazar placeholders
|
|
81
|
+
sed -e "s/{{PROJECT_NAME}}/$PROJECT_NAME/g" \
|
|
82
|
+
-e "s/{{PROJECT_SLUG}}/$PROJECT_SLUG/g" \
|
|
83
|
+
-e "s/\[project\]/$PROJECT_SLUG/g" \
|
|
84
|
+
-e "s/\[project-name\]/$PROJECT_SLUG/g" \
|
|
85
|
+
-e "s/\[project-slug\]/$PROJECT_SLUG/g" \
|
|
86
|
+
-e "s/{{FECHA}}/$CURRENT_DATE/g" \
|
|
87
|
+
-e "s/{{FECHA_PROXIMA}}/$DATE_PLUS_7/g" \
|
|
88
|
+
-e "s/{{FECHA_PROXIMA_MES}}/$DATE_PLUS_30/g" \
|
|
89
|
+
-e "s/{{FECHA_LAUNCH}}/$DATE_PLUS_35/g" \
|
|
90
|
+
-e "s/{{ESTADO}}/En planificación/g" \
|
|
91
|
+
-e "s/{{FASE}}/Fase 1/g" \
|
|
92
|
+
-e "s/{{X}}%/0%/g" \
|
|
93
|
+
"$src" > "$dest"
|
|
94
|
+
|
|
95
|
+
print_success "Creado: $dest"
|
|
96
|
+
fi
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
copy_template_keep_name() {
|
|
100
|
+
local src="$1"
|
|
101
|
+
local dest="$2"
|
|
102
|
+
|
|
103
|
+
if [ -f "$src" ]; then
|
|
104
|
+
sed -e "s/{{PROJECT_NAME}}/$PROJECT_NAME/g" \
|
|
105
|
+
-e "s/{{PROJECT_SLUG}}/$PROJECT_SLUG/g" \
|
|
106
|
+
-e "s/\[project\]/$PROJECT_SLUG/g" \
|
|
107
|
+
-e "s/\[project-name\]/$PROJECT_SLUG/g" \
|
|
108
|
+
-e "s/\[project-slug\]/$PROJECT_SLUG/g" \
|
|
109
|
+
-e "s/{{FECHA}}/$CURRENT_DATE/g" \
|
|
110
|
+
-e "s/{{FECHA_PROXIMA}}/$DATE_PLUS_7/g" \
|
|
111
|
+
-e "s/{{FECHA_PROXIMA_MES}}/$DATE_PLUS_30/g" \
|
|
112
|
+
-e "s/{{FECHA_LAUNCH}}/$DATE_PLUS_35/g" \
|
|
113
|
+
-e "s/{{ESTADO}}/En planificación/g" \
|
|
114
|
+
-e "s/{{FASE}}/Fase 1/g" \
|
|
115
|
+
-e "s/{{X}}%/0%/g" \
|
|
116
|
+
"$src" > "$dest"
|
|
117
|
+
|
|
118
|
+
print_success "Creado: $dest"
|
|
119
|
+
fi
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
copy_file_if_missing() {
|
|
123
|
+
local src="$1"
|
|
124
|
+
local dest="$2"
|
|
125
|
+
|
|
126
|
+
mkdir -p "$(dirname "$dest")"
|
|
127
|
+
|
|
128
|
+
if [ -f "$dest" ]; then
|
|
129
|
+
print_info "Saltado: $dest ya existe"
|
|
130
|
+
return 0
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
if [ ! -f "$src" ]; then
|
|
134
|
+
print_warning "No se encontró $src; se omite $dest"
|
|
135
|
+
return 0
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
cp "$src" "$dest"
|
|
139
|
+
print_success "Creado: $dest"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
# Copiar templates de docs/
|
|
143
|
+
copy_template "docs-template/docs/INDEX.md.template" "docs/INDEX.md"
|
|
144
|
+
copy_template "docs-template/docs/CONTEXTO.md.template" "docs/CONTEXTO.md"
|
|
145
|
+
copy_template "docs-template/docs/STATUS.md.template" "docs/STATUS.md"
|
|
146
|
+
copy_template "docs-template/docs/WORKFLOW.md.template" "docs/WORKFLOW.md"
|
|
147
|
+
copy_template "docs-template/docs/SUPPORT_MATRIX.md.template" "docs/SUPPORT_MATRIX.md"
|
|
148
|
+
copy_template "docs-template/docs/TROUBLESHOOTING.md.template" "docs/TROUBLESHOOTING.md"
|
|
149
|
+
copy_template "docs-template/docs/MULTI_AGENT_WORKFLOW.md.template" "docs/MULTI_AGENT_WORKFLOW.md"
|
|
150
|
+
copy_template "docs-template/docs/MOCK_DATA_GUIDE.md.template" "docs/MOCK_DATA_GUIDE.md"
|
|
151
|
+
copy_template "docs-template/docs/UI_STANDARDS.md.template" "docs/UI_STANDARDS.md"
|
|
152
|
+
copy_template "docs-template/docs/GITFLOW_PR_GUIDE.md.template" "docs/GITFLOW_PR_GUIDE.md"
|
|
153
|
+
copy_template "docs-template/docs/DOCUMENTATION_GUIDE.md.template" "docs/DOCUMENTATION_GUIDE.md"
|
|
154
|
+
copy_template "docs-template/docs/TESTING_GUIDE_FOR_AI.md.template" "docs/TESTING_GUIDE_FOR_AI.md"
|
|
155
|
+
|
|
156
|
+
# Copiar archivos que no son templates
|
|
157
|
+
if [ -f "docs-template/docs/UI_STANDARDS.md" ]; then
|
|
158
|
+
cp "docs-template/docs/UI_STANDARDS.md" "docs/UI_STANDARDS.md"
|
|
159
|
+
print_success "Creado: docs/UI_STANDARDS.md"
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
if [ -f "docs-template/docs/MOCK_DATA_GUIDE.md" ]; then
|
|
163
|
+
cp "docs-template/docs/MOCK_DATA_GUIDE.md" "docs/MOCK_DATA_GUIDE.md"
|
|
164
|
+
print_success "Creado: docs/MOCK_DATA_GUIDE.md"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# Copiar configuración de IA
|
|
168
|
+
if [ -f "docs-template/docs/ai/PRINCIPLES.md" ]; then
|
|
169
|
+
cp "docs-template/docs/ai/PRINCIPLES.md" "docs/ai/PRINCIPLES.md"
|
|
170
|
+
print_success "Creado: docs/ai/PRINCIPLES.md"
|
|
171
|
+
fi
|
|
172
|
+
|
|
173
|
+
if [ -f "docs-template/docs/ai/RULES.yaml" ]; then
|
|
174
|
+
cp "docs-template/docs/ai/RULES.yaml" "docs/ai/RULES.yaml"
|
|
175
|
+
print_success "Creado: docs/ai/RULES.yaml"
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
# Copiar template de LESSONS (vacío)
|
|
179
|
+
copy_template "docs-template/docs/ai/LESSONS.md.template" "docs/ai/LESSONS.md"
|
|
180
|
+
|
|
181
|
+
# Copiar SPEC del proyecto y artefactos requeridos por gates
|
|
182
|
+
copy_template "docs-template/specs/[project-name]/SPEC.md.template" "specs/$PROJECT_SLUG/SPEC.md"
|
|
183
|
+
copy_template "docs-template/specs/[project-name]/STATUS.md.template" "specs/$PROJECT_SLUG/STATUS.md"
|
|
184
|
+
copy_template "docs-template/specs/[project-name]/EVIDENCE_REPORT.md.template" "specs/$PROJECT_SLUG/EVIDENCE_REPORT.md"
|
|
185
|
+
|
|
186
|
+
# Copiar template de slice
|
|
187
|
+
copy_template_keep_name "docs-template/specs/[project-name]/slices/slice-template/slice.json" "specs/$PROJECT_SLUG/slices/slice-template/slice.json"
|
|
188
|
+
print_success "Creado: specs/$PROJECT_SLUG/slices/slice-template/slice.json"
|
|
189
|
+
|
|
190
|
+
# Copiar template de PR del slice
|
|
191
|
+
copy_template_keep_name "docs-template/specs/[project-name]/slices/pr.md.template" "specs/$PROJECT_SLUG/slices/slice-template/pr.md.template"
|
|
192
|
+
|
|
193
|
+
# Copiar baseline legal y OSS cuando faltan
|
|
194
|
+
copy_file_if_missing "docs-template/LICENSE" "LICENSE"
|
|
195
|
+
copy_file_if_missing "docs-template/CONTRIBUTING.md" "CONTRIBUTING.md"
|
|
196
|
+
copy_file_if_missing "docs-template/CODE_OF_CONDUCT.md" "CODE_OF_CONDUCT.md"
|
|
197
|
+
copy_file_if_missing "docs-template/SECURITY.md" "SECURITY.md"
|
|
198
|
+
copy_file_if_missing "docs-template/CHANGELOG.md" "CHANGELOG.md"
|
|
199
|
+
copy_file_if_missing "docs-template/ROADMAP.md" "ROADMAP.md"
|
|
200
|
+
copy_file_if_missing "docs-template/.github/pull_request_template.md" ".github/pull_request_template.md"
|
|
201
|
+
copy_file_if_missing "docs-template/.github/ISSUE_TEMPLATE/bug_report.md" ".github/ISSUE_TEMPLATE/bug_report.md"
|
|
202
|
+
copy_file_if_missing "docs-template/.github/ISSUE_TEMPLATE/feature_request.md" ".github/ISSUE_TEMPLATE/feature_request.md"
|
|
203
|
+
copy_file_if_missing "docs-template/.github/workflows/ci.yml" ".github/workflows/ci.yml"
|
|
204
|
+
|
|
205
|
+
# Sincronizar package.json del host
|
|
206
|
+
sync_package_json() {
|
|
207
|
+
local package_template="docs-template/package.template.json"
|
|
208
|
+
local package_json="package.json"
|
|
209
|
+
|
|
210
|
+
if [ ! -f "$package_template" ]; then
|
|
211
|
+
print_warning "No se encontró package.template.json; se omite la sincronización de package.json"
|
|
212
|
+
return 0
|
|
213
|
+
fi
|
|
214
|
+
|
|
215
|
+
if [ ! -f "$package_json" ]; then
|
|
216
|
+
cp "$package_template" "$package_json"
|
|
217
|
+
print_success "Creado: $package_json"
|
|
218
|
+
return 0
|
|
219
|
+
fi
|
|
220
|
+
|
|
221
|
+
node - "$package_json" "$package_template" <<'NODE'
|
|
222
|
+
const fs = require('fs');
|
|
223
|
+
|
|
224
|
+
const [packagePath, templatePath] = process.argv.slice(2);
|
|
225
|
+
const existing = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
226
|
+
const template = JSON.parse(fs.readFileSync(templatePath, 'utf8'));
|
|
227
|
+
|
|
228
|
+
existing.scripts = {
|
|
229
|
+
...(existing.scripts || {}),
|
|
230
|
+
...(template.scripts || {})
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
fs.writeFileSync(packagePath, `${JSON.stringify(existing, null, 2)}\n`);
|
|
234
|
+
NODE
|
|
235
|
+
|
|
236
|
+
print_success "Actualizado: $package_json (scripts mergeados)"
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
sync_package_json
|
|
240
|
+
|
|
241
|
+
# Copiar bootstrap de slices a tools/scripts
|
|
242
|
+
if [ -f "docs-template/scripts/start-slice.sh" ]; then
|
|
243
|
+
cp "docs-template/scripts/start-slice.sh" "tools/scripts/start-slice.sh"
|
|
244
|
+
chmod +x "tools/scripts/start-slice.sh"
|
|
245
|
+
print_success "Creado: tools/scripts/start-slice.sh"
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
if [ -f "docs-template/scripts/refresh-active-slices.sh" ]; then
|
|
249
|
+
cp "docs-template/scripts/refresh-active-slices.sh" "tools/scripts/refresh-active-slices.sh"
|
|
250
|
+
chmod +x "tools/scripts/refresh-active-slices.sh"
|
|
251
|
+
print_success "Creado: tools/scripts/refresh-active-slices.sh"
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
if [ -f "docs-template/scripts/check-slice-readiness.sh" ]; then
|
|
255
|
+
cp "docs-template/scripts/check-slice-readiness.sh" "tools/scripts/check-slice-readiness.sh"
|
|
256
|
+
chmod +x "tools/scripts/check-slice-readiness.sh"
|
|
257
|
+
print_success "Creado: tools/scripts/check-slice-readiness.sh"
|
|
258
|
+
fi
|
|
259
|
+
|
|
260
|
+
if [ -f "docs-template/scripts/check-pr-readiness.sh" ]; then
|
|
261
|
+
cp "docs-template/scripts/check-pr-readiness.sh" "tools/scripts/check-pr-readiness.sh"
|
|
262
|
+
chmod +x "tools/scripts/check-pr-readiness.sh"
|
|
263
|
+
print_success "Creado: tools/scripts/check-pr-readiness.sh"
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
if [ -f "docs-template/scripts/cleanup-slice.sh" ]; then
|
|
267
|
+
cp "docs-template/scripts/cleanup-slice.sh" "tools/scripts/cleanup-slice.sh"
|
|
268
|
+
chmod +x "tools/scripts/cleanup-slice.sh"
|
|
269
|
+
print_success "Creado: tools/scripts/cleanup-slice.sh"
|
|
270
|
+
fi
|
|
271
|
+
|
|
272
|
+
if [ -f "docs-template/scripts/check-scope.sh" ]; then
|
|
273
|
+
cp "docs-template/scripts/check-scope.sh" "tools/scripts/check-scope.sh"
|
|
274
|
+
chmod +x "tools/scripts/check-scope.sh"
|
|
275
|
+
print_success "Creado: tools/scripts/check-scope.sh"
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
# Crear archivo SEARCH.md básico
|
|
279
|
+
cat > "docs/SEARCH.md" << EOF
|
|
280
|
+
# Búsqueda por Tema
|
|
281
|
+
|
|
282
|
+
**Última actualización:** $CURRENT_DATE
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Autenticación
|
|
287
|
+
|
|
288
|
+
- **Spec:** \`../specs/$PROJECT_SLUG/slices/slice-01/slice.json\`
|
|
289
|
+
- **PR del slice:** \`../specs/$PROJECT_SLUG/slices/slice-01/pr.md\`
|
|
290
|
+
- **Bootstrap del slice:** \`../tools/scripts/start-slice.sh ../specs/$PROJECT_SLUG/slices/slice-01/slice.json\`
|
|
291
|
+
- **Hook:** \`hooks/useAuth.ts\`
|
|
292
|
+
- **API:** \`docs/api/auth/README.md\`
|
|
293
|
+
- **Componentes:** \`app/(auth)/\`
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## IA Configuración
|
|
298
|
+
|
|
299
|
+
- **Principios:** \`docs/ai/PRINCIPLES.md\`
|
|
300
|
+
- **Reglas:** \`docs/ai/RULES.yaml\`
|
|
301
|
+
- **Lessons:** \`docs/ai/LESSONS.md\`
|
|
302
|
+
|
|
303
|
+
## Soporte
|
|
304
|
+
|
|
305
|
+
- **Support Matrix:** \`docs/SUPPORT_MATRIX.md\`
|
|
306
|
+
- **Troubleshooting:** \`docs/TROUBLESHOOTING.md\`
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
**Fin de la búsqueda**
|
|
311
|
+
EOF
|
|
312
|
+
|
|
313
|
+
print_success "Creado: docs/SEARCH.md"
|
|
314
|
+
|
|
315
|
+
# Crear README.md en la raíz del proyecto (si no existe)
|
|
316
|
+
if [ ! -f "README.md" ]; then
|
|
317
|
+
cat > "README.md" << EOF
|
|
318
|
+
# $PROJECT_NAME
|
|
319
|
+
|
|
320
|
+
[Descripción breve del proyecto]
|
|
321
|
+
|
|
322
|
+
## Quick Start
|
|
323
|
+
|
|
324
|
+
\`\`\`bash
|
|
325
|
+
npm install
|
|
326
|
+
cp .env.example .env.local
|
|
327
|
+
npm run dev
|
|
328
|
+
\`\`\`
|
|
329
|
+
|
|
330
|
+
## Verification Checklist
|
|
331
|
+
|
|
332
|
+
- [ ] npm install completes
|
|
333
|
+
- [ ] npm run dev starts
|
|
334
|
+
- [ ] App opens at http://localhost:3000
|
|
335
|
+
|
|
336
|
+
## Documentation
|
|
337
|
+
|
|
338
|
+
- [Contexto](./docs/CONTEXTO.md) - Qué es $PROJECT_NAME
|
|
339
|
+
- [Workflow](./docs/WORKFLOW.md) - Cómo implementar
|
|
340
|
+
- [Support Matrix](./docs/SUPPORT_MATRIX.md) - Qué entornos están soportados
|
|
341
|
+
- [Troubleshooting](./docs/TROUBLESHOOTING.md) - Cómo recuperarse de fallos comunes
|
|
342
|
+
- [Status](./docs/STATUS.md) - Estado del proyecto
|
|
343
|
+
- [API Docs](./docs/api/) - Endpoint documentation (si aplica)
|
|
344
|
+
EOF
|
|
345
|
+
print_success "Creado: README.md"
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
# Resumen
|
|
349
|
+
echo ""
|
|
350
|
+
print_success "¡Inicialización completada!"
|
|
351
|
+
echo ""
|
|
352
|
+
echo "📁 Estructura creada:"
|
|
353
|
+
echo " docs/ ← Documentación core"
|
|
354
|
+
echo " docs/ai/ ← Configuración de IA"
|
|
355
|
+
echo " docs/tools/ ← Herramientas (vacío)"
|
|
356
|
+
echo " docs/archive/ ← Histórico (vacío)"
|
|
357
|
+
echo " specs/$PROJECT_SLUG/ ← Especificaciones del proyecto"
|
|
358
|
+
echo ""
|
|
359
|
+
echo "📝 Próximos pasos:"
|
|
360
|
+
echo " 1. Editar docs/CONTEXTO.md con la información de tu proyecto"
|
|
361
|
+
echo " 2. Editar docs/STATUS.md con el estado actual"
|
|
362
|
+
echo " 3. Crear el primer directorio de slice en specs/$PROJECT_SLUG/slices/[slice-id]/"
|
|
363
|
+
echo " 4. Actualizar docs/SEARCH.md con temas específicos"
|
|
364
|
+
echo ""
|
|
365
|
+
echo "📖 Más información:"
|
|
366
|
+
echo " - Ver docs-template/TEMPLATE.md para guía de personalización"
|
|
367
|
+
echo " - Ver docs-template/README.md para documentación del template"
|
|
368
|
+
echo ""
|