rootkid0-initializer 0.1.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 (86) hide show
  1. package/.opencode/README.md +38 -0
  2. package/.opencode/agents/README.md +12 -0
  3. package/.opencode/agents/architect.md +16 -0
  4. package/.opencode/agents/implementer.md +16 -0
  5. package/.opencode/agents/ops.md +15 -0
  6. package/.opencode/agents/reviewer.md +12 -0
  7. package/.opencode/context.md +36 -0
  8. package/.opencode/mcp/README.md +34 -0
  9. package/.opencode/mcp/servers.recommended.template.json +30 -0
  10. package/.opencode/mcp/servers.template.json +18 -0
  11. package/.opencode/skills/global/SKILL.md +20 -0
  12. package/.opencode/templates/subproject-agents.template.md +20 -0
  13. package/.opencode/templates/subproject-skill.template.md +9 -0
  14. package/01-business/01-business-understanding.md +22 -0
  15. package/01-business/02-problem-statement.md +15 -0
  16. package/01-business/03-as-is-flow.md +17 -0
  17. package/01-business/04-scope-definition.md +17 -0
  18. package/01-business/05-assumptions-risks.md +17 -0
  19. package/01-business/AGENTS.md +32 -0
  20. package/01-business/DISCOVERY-OPERATING-MODEL.md +74 -0
  21. package/01-business/skills/SKILL.md +12 -0
  22. package/02-proposal/01-proposal.md +27 -0
  23. package/02-proposal/AGENTS.md +28 -0
  24. package/02-proposal/PROPOSAL-OPERATING-MODEL.md +77 -0
  25. package/02-proposal/skills/SKILL.md +11 -0
  26. package/03-design/01-architecture-overview.md +17 -0
  27. package/03-design/02-to-be-flow.md +16 -0
  28. package/03-design/03-components.md +12 -0
  29. package/03-design/04-data-model.md +17 -0
  30. package/03-design/05-api-contracts.md +18 -0
  31. package/03-design/06-error-handling.md +19 -0
  32. package/03-design/AGENTS.md +33 -0
  33. package/03-design/DESIGN-OPERATING-MODEL.md +83 -0
  34. package/03-design/skills/SKILL.md +11 -0
  35. package/04-management/01-project-overview.md +17 -0
  36. package/04-management/02-roadmap.md +14 -0
  37. package/04-management/03-backlog.md +11 -0
  38. package/04-management/04-sprints.md +12 -0
  39. package/04-management/05-risks.md +12 -0
  40. package/04-management/06-change-log.md +11 -0
  41. package/04-management/AGENTS.md +33 -0
  42. package/04-management/MANAGEMENT-OPERATING-MODEL.md +83 -0
  43. package/04-management/skills/SKILL.md +11 -0
  44. package/05-development/01-setup.md +13 -0
  45. package/05-development/02-standards.md +12 -0
  46. package/05-development/03-testing.md +12 -0
  47. package/05-development/04-structure.md +11 -0
  48. package/05-development/AGENTS.md +31 -0
  49. package/05-development/DEVELOPMENT-OPERATING-MODEL.md +82 -0
  50. package/05-development/skills/SKILL.md +11 -0
  51. package/06-deployment/01-environments.md +11 -0
  52. package/06-deployment/02-ci-cd.md +13 -0
  53. package/06-deployment/03-config.md +11 -0
  54. package/06-deployment/04-monitoring.md +12 -0
  55. package/06-deployment/AGENTS.md +31 -0
  56. package/06-deployment/DEPLOYMENT-OPERATING-MODEL.md +82 -0
  57. package/06-deployment/skills/SKILL.md +11 -0
  58. package/07-production/01-operations-runbook.md +23 -0
  59. package/07-production/02-incident-management.md +25 -0
  60. package/07-production/03-performance-capacity.md +24 -0
  61. package/07-production/04-continuous-improvement.md +24 -0
  62. package/07-production/AGENTS.md +31 -0
  63. package/07-production/PRODUCTION-OPERATING-MODEL.md +81 -0
  64. package/07-production/skills/SKILL.md +11 -0
  65. package/99-common/01-readme-base.md +16 -0
  66. package/99-common/02-initial-checklist.md +7 -0
  67. package/99-common/03-glossary.md +7 -0
  68. package/99-common/04-release-closure-product-3-4.md +47 -0
  69. package/99-common/05-p1-notion-multi-db-plan.md +126 -0
  70. package/99-common/06-p1-notion-schema-spec.md +189 -0
  71. package/99-common/07-p1-notion-manual-setup-checklist.md +72 -0
  72. package/99-common/AGENTS.md +20 -0
  73. package/99-common/project.config.json +7 -0
  74. package/99-common/skills/SKILL.md +9 -0
  75. package/AGENTS.md +275 -0
  76. package/LICENSE +201 -0
  77. package/README.md +95 -0
  78. package/bin/rootkid0-initializer.js +89 -0
  79. package/package.json +38 -0
  80. package/rootkid0-bootstrap/AGENTS.md +20 -0
  81. package/rootkid0-bootstrap/helpers.sh +106 -0
  82. package/rootkid0-bootstrap/init-project.ps1 +114 -0
  83. package/rootkid0-bootstrap/init-project.sh +71 -0
  84. package/rootkid0-bootstrap/notion-bootstrap.ps1 +162 -0
  85. package/rootkid0-bootstrap/notion-bootstrap.sh +301 -0
  86. package/rootkid0-bootstrap/skills/SKILL.md +9 -0
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+
8
+ source "$SCRIPT_DIR/helpers.sh"
9
+
10
+ print_usage() {
11
+ echo "Uso: ./rootkid0-bootstrap/init-project.sh [--setup-mcp] <project-name>"
12
+ }
13
+
14
+ SETUP_MCP=false
15
+ PROJECT_NAME=""
16
+
17
+ for arg in "$@"; do
18
+ case "$arg" in
19
+ --setup-mcp)
20
+ SETUP_MCP=true
21
+ ;;
22
+ -h|--help)
23
+ print_usage
24
+ exit 0
25
+ ;;
26
+ *)
27
+ if [[ -z "$PROJECT_NAME" ]]; then
28
+ PROJECT_NAME="$arg"
29
+ else
30
+ echo "Error: argumento no reconocido '$arg'" >&2
31
+ print_usage
32
+ exit 1
33
+ fi
34
+ ;;
35
+ esac
36
+ done
37
+
38
+ if [[ -z "$PROJECT_NAME" ]]; then
39
+ read -r -p "Nombre del proyecto: " PROJECT_NAME
40
+ fi
41
+
42
+ validate_project_name "$PROJECT_NAME"
43
+
44
+ DESTINATION="$PWD/$PROJECT_NAME"
45
+
46
+ if [[ -e "$DESTINATION" ]]; then
47
+ echo "Error: Ya existe la carpeta $DESTINATION" >&2
48
+ exit 1
49
+ fi
50
+
51
+ echo "Creando proyecto: $PROJECT_NAME"
52
+ mkdir -p "$DESTINATION"
53
+
54
+ copy_baseline "$REPO_ROOT" "$DESTINATION"
55
+ replace_project_placeholders "$DESTINATION" "$PROJECT_NAME"
56
+ generate_project_readme "$DESTINATION" "$PROJECT_NAME"
57
+
58
+ if [[ "$SETUP_MCP" == "true" ]]; then
59
+ setup_global_mcp_config "$REPO_ROOT"
60
+ fi
61
+
62
+ bash "$SCRIPT_DIR/notion-bootstrap.sh" --project-name "$PROJECT_NAME" --project-dir "$DESTINATION"
63
+
64
+ echo
65
+ echo "Proyecto creado en: $DESTINATION"
66
+ echo "Siguientes pasos:"
67
+ echo " 1) cd \"$PROJECT_NAME\""
68
+ echo " 2) Completar 01-business/ a 07-production/"
69
+ echo " 3) Ajustar 99-common/project.config.json"
70
+ echo " 4) Revisar AGENTS.md y .opencode/README.md"
71
+ echo " 5) Revisar 99-common/notion-bootstrap.output.json"
@@ -0,0 +1,162 @@
1
+ param(
2
+ [Parameter(Mandatory = $true)]
3
+ [string]$ProjectName,
4
+
5
+ [Parameter(Mandatory = $true)]
6
+ [string]$ProjectDir
7
+ )
8
+
9
+ Set-StrictMode -Version Latest
10
+ $ErrorActionPreference = "Stop"
11
+
12
+ function Fail([string]$Message) {
13
+ throw $Message
14
+ }
15
+
16
+ function Require-Env([string]$Name) {
17
+ $value = [Environment]::GetEnvironmentVariable($Name)
18
+ if ([string]::IsNullOrWhiteSpace($value)) {
19
+ Fail "Variable requerida no definida: $Name. Definila y vuelve a ejecutar init-project."
20
+ }
21
+ }
22
+
23
+ function Get-NotionPagePayload([string]$ParentPageId, [string]$Title) {
24
+ return @{
25
+ parent = @{ page_id = $ParentPageId }
26
+ properties = @{
27
+ title = @{
28
+ title = @(
29
+ @{
30
+ type = "text"
31
+ text = @{ content = $Title }
32
+ }
33
+ )
34
+ }
35
+ }
36
+ } | ConvertTo-Json -Depth 10
37
+ }
38
+
39
+ function New-NotionPage([string]$ParentPageId, [string]$Title) {
40
+ $headers = @{
41
+ Authorization = "Bearer $env:NOTION_TOKEN"
42
+ "Notion-Version" = "2022-06-28"
43
+ "Content-Type" = "application/json"
44
+ }
45
+
46
+ $body = Get-NotionPagePayload -ParentPageId $ParentPageId -Title $Title
47
+
48
+ try {
49
+ $response = Invoke-RestMethod -Method Post -Uri "https://api.notion.com/v1/pages" -Headers $headers -Body $body
50
+ }
51
+ catch {
52
+ $apiMessage = $_.ErrorDetails.Message
53
+ if ([string]::IsNullOrWhiteSpace($apiMessage)) {
54
+ $apiMessage = $_.Exception.Message
55
+ }
56
+ Fail "No se pudo crear pagina en Notion ($Title). Detalle: $apiMessage"
57
+ }
58
+
59
+ if ([string]::IsNullOrWhiteSpace($response.id)) {
60
+ Fail "Notion no devolvio un id valido al crear '$Title'."
61
+ }
62
+
63
+ return $response.id
64
+ }
65
+
66
+ if (-not (Test-Path -LiteralPath $ProjectDir)) {
67
+ Fail "No existe el directorio de proyecto: $ProjectDir"
68
+ }
69
+
70
+ $mcpFile = Join-Path $HOME ".config/opencode/mcp-servers.json"
71
+
72
+ if (-not (Test-Path -LiteralPath $mcpFile)) {
73
+ Fail "No existe $mcpFile. Configura MCP global con servidor notion y vuelve a ejecutar init-project."
74
+ }
75
+
76
+ try {
77
+ $mcpConfig = Get-Content -Path $mcpFile -Raw | ConvertFrom-Json
78
+ }
79
+ catch {
80
+ Fail "El archivo $mcpFile no tiene JSON valido. Corrigelo y vuelve a ejecutar init-project."
81
+ }
82
+
83
+ if ($null -eq $mcpConfig.servers -or $null -eq $mcpConfig.servers.notion) {
84
+ Fail "Falta entrada servers.notion en $mcpFile. Agregala y vuelve a ejecutar init-project."
85
+ }
86
+
87
+ Require-Env "NOTION_TOKEN"
88
+ Require-Env "NOTION_PARENT_PAGE_ID"
89
+
90
+ $workspaceName = [Environment]::GetEnvironmentVariable("NOTION_WORKSPACE_NAME")
91
+
92
+ Write-Host "Iniciando bootstrap automatico de Notion..."
93
+
94
+ $rootTitle = $ProjectName
95
+ if (-not [string]::IsNullOrWhiteSpace($workspaceName)) {
96
+ $rootTitle = "$workspaceName - $ProjectName"
97
+ }
98
+
99
+ $projectRootPageId = New-NotionPage -ParentPageId $env:NOTION_PARENT_PAGE_ID -Title $rootTitle
100
+ Write-Host "Pagina raiz creada: $projectRootPageId"
101
+
102
+ $phaseNames = @(
103
+ "01-business",
104
+ "02-proposal",
105
+ "03-design",
106
+ "04-management",
107
+ "05-development",
108
+ "06-deployment",
109
+ "07-production",
110
+ "99-common"
111
+ )
112
+
113
+ $phaseMap = [ordered]@{}
114
+ $commonPageId = ""
115
+
116
+ foreach ($phase in $phaseNames) {
117
+ $phaseId = New-NotionPage -ParentPageId $projectRootPageId -Title $phase
118
+ $phaseMap[$phase] = $phaseId
119
+ Write-Host "Pagina creada ($phase): $phaseId"
120
+ if ($phase -eq "99-common") {
121
+ $commonPageId = $phaseId
122
+ }
123
+ }
124
+
125
+ if ([string]::IsNullOrWhiteSpace($commonPageId)) {
126
+ Fail "No se pudo crear la pagina 99-common en Notion."
127
+ }
128
+
129
+ $sectionNames = @(
130
+ "Projects",
131
+ "Phases",
132
+ "Deliverables",
133
+ "Backlog",
134
+ "Risks",
135
+ "Decisions",
136
+ "Incidents"
137
+ )
138
+
139
+ $sectionMap = [ordered]@{}
140
+
141
+ foreach ($section in $sectionNames) {
142
+ $sectionId = New-NotionPage -ParentPageId $commonPageId -Title $section
143
+ $sectionMap[$section] = $sectionId
144
+ Write-Host "Seccion modelo MVP creada ($section): $sectionId"
145
+ }
146
+
147
+ $outputPath = Join-Path $ProjectDir "99-common/notion-bootstrap.output.json"
148
+
149
+ $result = [ordered]@{
150
+ project_name = $ProjectName
151
+ workspace_name = $workspaceName
152
+ created_at_utc = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
153
+ notion_parent_page_id = $env:NOTION_PARENT_PAGE_ID
154
+ project_root_page_id = $projectRootPageId
155
+ phase_pages = $phaseMap
156
+ model_sections = $sectionMap
157
+ }
158
+
159
+ $result | ConvertTo-Json -Depth 10 | Set-Content -Path $outputPath
160
+
161
+ Write-Host "Bootstrap Notion completado."
162
+ Write-Host "Salida guardada en: $outputPath"
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ print_usage() {
6
+ echo "Uso: ./rootkid0-bootstrap/notion-bootstrap.sh --project-name <name> --project-dir <path>"
7
+ }
8
+
9
+ fail() {
10
+ echo "Error: $1" >&2
11
+ exit 1
12
+ }
13
+
14
+ json_escape() {
15
+ local value="${1:-}"
16
+ value="${value//\\/\\\\}"
17
+ value="${value//\"/\\\"}"
18
+ value="${value//$'\n'/ }"
19
+ value="${value//$'\r'/ }"
20
+ printf '%s' "$value"
21
+ }
22
+
23
+ pick_python() {
24
+ if command -v python3 >/dev/null 2>&1; then
25
+ echo "python3"
26
+ return 0
27
+ fi
28
+
29
+ if command -v python >/dev/null 2>&1; then
30
+ echo "python"
31
+ return 0
32
+ fi
33
+
34
+ return 1
35
+ }
36
+
37
+ validate_mcp_config() {
38
+ local mcp_file="$HOME/.config/opencode/mcp-servers.json"
39
+ local py_bin
40
+ local py_status
41
+
42
+ if [[ ! -f "$mcp_file" ]]; then
43
+ fail "No existe $mcp_file. Configura el MCP global con entrada 'notion' y vuelve a ejecutar init-project."
44
+ fi
45
+
46
+ py_bin="$(pick_python || true)"
47
+
48
+ if [[ -n "$py_bin" ]]; then
49
+ if "$py_bin" - "$mcp_file" <<'PY'; then
50
+ import json
51
+ import sys
52
+
53
+ path = sys.argv[1]
54
+ try:
55
+ with open(path, "r", encoding="utf-8") as f:
56
+ data = json.load(f)
57
+ except Exception:
58
+ sys.exit(2)
59
+
60
+ servers = data.get("servers")
61
+ if isinstance(servers, dict) and "notion" in servers:
62
+ sys.exit(0)
63
+
64
+ sys.exit(1)
65
+ PY
66
+ py_status=0
67
+ else
68
+ py_status=$?
69
+ fi
70
+
71
+ if [[ "$py_status" -ne 0 ]]; then
72
+ case "$py_status" in
73
+ 1)
74
+ fail "Falta el servidor 'notion' en $mcp_file. Agrega la entrada en servers.notion y vuelve a ejecutar init-project."
75
+ ;;
76
+ 2)
77
+ fail "El archivo $mcp_file no tiene JSON valido. Corrigelo y vuelve a ejecutar init-project."
78
+ ;;
79
+ *)
80
+ fail "No se pudo validar $mcp_file. Verifica permisos y formato del archivo."
81
+ ;;
82
+ esac
83
+ fi
84
+ return 0
85
+ fi
86
+
87
+ if ! grep -q '"notion"' "$mcp_file"; then
88
+ fail "No se detecto la entrada 'notion' en $mcp_file. Agrega el servidor notion y vuelve a ejecutar init-project."
89
+ fi
90
+ }
91
+
92
+ require_env() {
93
+ local var_name="$1"
94
+ local var_value="${!var_name:-}"
95
+
96
+ if [[ -z "$var_value" ]]; then
97
+ fail "Variable requerida no definida: $var_name. Exporta $var_name y vuelve a ejecutar init-project."
98
+ fi
99
+ }
100
+
101
+ require_command() {
102
+ local command_name="$1"
103
+ if ! command -v "$command_name" >/dev/null 2>&1; then
104
+ fail "Dependencia requerida no encontrada: $command_name. Instalala y vuelve a ejecutar init-project."
105
+ fi
106
+ }
107
+
108
+ build_page_payload() {
109
+ local parent_id="$1"
110
+ local title="$2"
111
+
112
+ printf '{"parent":{"page_id":"%s"},"properties":{"title":{"title":[{"type":"text","text":{"content":"%s"}}]}}}' \
113
+ "$parent_id" \
114
+ "$(json_escape "$title")"
115
+ }
116
+
117
+ create_notion_page() {
118
+ local parent_id="$1"
119
+ local title="$2"
120
+ local payload
121
+ local response_file
122
+ local status
123
+ local py_bin
124
+ local page_id
125
+
126
+ payload="$(build_page_payload "$parent_id" "$title")"
127
+ response_file="$(mktemp)"
128
+
129
+ status="$(curl -sS -o "$response_file" -w "%{http_code}" \
130
+ -X POST "https://api.notion.com/v1/pages" \
131
+ -H "Authorization: Bearer $NOTION_TOKEN" \
132
+ -H "Notion-Version: 2022-06-28" \
133
+ -H "Content-Type: application/json" \
134
+ --data "$payload")"
135
+
136
+ if [[ "$status" -lt 200 || "$status" -ge 300 ]]; then
137
+ local error_body
138
+ error_body="$(tr -d '\n' < "$response_file")"
139
+ rm -f "$response_file"
140
+ fail "Notion API devolvio HTTP $status al crear '$title'. Respuesta: $error_body"
141
+ fi
142
+
143
+ py_bin="$(pick_python || true)"
144
+ if [[ -n "$py_bin" ]]; then
145
+ page_id="$("$py_bin" - "$response_file" <<'PY'
146
+ import json
147
+ import sys
148
+
149
+ with open(sys.argv[1], "r", encoding="utf-8") as f:
150
+ data = json.load(f)
151
+
152
+ print(data.get("id", ""))
153
+ PY
154
+ )"
155
+ else
156
+ page_id="$(grep -o '"id":"[^"]*"' "$response_file" | head -n 1 | cut -d '"' -f 4)"
157
+ fi
158
+
159
+ rm -f "$response_file"
160
+
161
+ if [[ -z "$page_id" ]]; then
162
+ fail "No se pudo extraer el id de la pagina creada para '$title'."
163
+ fi
164
+
165
+ printf '%s' "$page_id"
166
+ }
167
+
168
+ PROJECT_NAME=""
169
+ PROJECT_DIR=""
170
+
171
+ while [[ $# -gt 0 ]]; do
172
+ case "$1" in
173
+ --project-name)
174
+ PROJECT_NAME="${2:-}"
175
+ shift 2
176
+ ;;
177
+ --project-dir)
178
+ PROJECT_DIR="${2:-}"
179
+ shift 2
180
+ ;;
181
+ -h|--help)
182
+ print_usage
183
+ exit 0
184
+ ;;
185
+ *)
186
+ fail "Argumento no reconocido: $1"
187
+ ;;
188
+ esac
189
+ done
190
+
191
+ if [[ -z "$PROJECT_NAME" || -z "$PROJECT_DIR" ]]; then
192
+ print_usage
193
+ fail "Debes indicar --project-name y --project-dir."
194
+ fi
195
+
196
+ if [[ ! -d "$PROJECT_DIR" ]]; then
197
+ fail "No existe el directorio de proyecto: $PROJECT_DIR"
198
+ fi
199
+
200
+ validate_mcp_config
201
+ require_command "curl"
202
+ require_env "NOTION_TOKEN"
203
+ require_env "NOTION_PARENT_PAGE_ID"
204
+
205
+ NOTION_WORKSPACE_NAME="${NOTION_WORKSPACE_NAME:-}"
206
+
207
+ echo "Iniciando bootstrap automatico de Notion..."
208
+
209
+ root_title="$PROJECT_NAME"
210
+ if [[ -n "$NOTION_WORKSPACE_NAME" ]]; then
211
+ root_title="$NOTION_WORKSPACE_NAME - $PROJECT_NAME"
212
+ fi
213
+
214
+ project_root_page_id="$(create_notion_page "$NOTION_PARENT_PAGE_ID" "$root_title")"
215
+ echo "Pagina raiz creada: $project_root_page_id"
216
+
217
+ phase_names=(
218
+ "01-business"
219
+ "02-proposal"
220
+ "03-design"
221
+ "04-management"
222
+ "05-development"
223
+ "06-deployment"
224
+ "07-production"
225
+ "99-common"
226
+ )
227
+
228
+ phase_ids=()
229
+ common_page_id=""
230
+
231
+ for phase in "${phase_names[@]}"; do
232
+ phase_id="$(create_notion_page "$project_root_page_id" "$phase")"
233
+ phase_ids+=("$phase_id")
234
+ echo "Pagina creada ($phase): $phase_id"
235
+ if [[ "$phase" == "99-common" ]]; then
236
+ common_page_id="$phase_id"
237
+ fi
238
+ done
239
+
240
+ if [[ -z "$common_page_id" ]]; then
241
+ fail "No se pudo crear la pagina 99-common en Notion."
242
+ fi
243
+
244
+ section_names=(
245
+ "Projects"
246
+ "Phases"
247
+ "Deliverables"
248
+ "Backlog"
249
+ "Risks"
250
+ "Decisions"
251
+ "Incidents"
252
+ )
253
+
254
+ section_ids=()
255
+ for section in "${section_names[@]}"; do
256
+ section_id="$(create_notion_page "$common_page_id" "$section")"
257
+ section_ids+=("$section_id")
258
+ echo "Seccion modelo MVP creada ($section): $section_id"
259
+ done
260
+
261
+ output_file="$PROJECT_DIR/99-common/notion-bootstrap.output.json"
262
+ timestamp_utc="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
263
+
264
+ {
265
+ echo "{"
266
+ echo " \"project_name\": \"$(json_escape "$PROJECT_NAME")\","
267
+ echo " \"workspace_name\": \"$(json_escape "$NOTION_WORKSPACE_NAME")\","
268
+ echo " \"created_at_utc\": \"$timestamp_utc\","
269
+ echo " \"notion_parent_page_id\": \"$(json_escape "$NOTION_PARENT_PAGE_ID")\","
270
+ echo " \"project_root_page_id\": \"$project_root_page_id\","
271
+ echo " \"phase_pages\": {"
272
+
273
+ for i in "${!phase_names[@]}"; do
274
+ key="${phase_names[$i]}"
275
+ value="${phase_ids[$i]}"
276
+ suffix=","
277
+ if [[ "$i" -eq $((${#phase_names[@]} - 1)) ]]; then
278
+ suffix=""
279
+ fi
280
+ echo " \"$(json_escape "$key")\": \"$value\"$suffix"
281
+ done
282
+
283
+ echo " },"
284
+ echo " \"model_sections\": {"
285
+
286
+ for i in "${!section_names[@]}"; do
287
+ key="${section_names[$i]}"
288
+ value="${section_ids[$i]}"
289
+ suffix=","
290
+ if [[ "$i" -eq $((${#section_names[@]} - 1)) ]]; then
291
+ suffix=""
292
+ fi
293
+ echo " \"$(json_escape "$key")\": \"$value\"$suffix"
294
+ done
295
+
296
+ echo " }"
297
+ echo "}"
298
+ } > "$output_file"
299
+
300
+ echo "Bootstrap Notion completado."
301
+ echo "Salida guardada en: $output_file"
@@ -0,0 +1,9 @@
1
+ ---
2
+ name: local-bootstrap-conventions
3
+ description: Convenciones para scripts de bootstrap. Trigger: cambios en rootkid0-bootstrap.
4
+ ---
5
+
6
+ # Skill local rootkid0-bootstrap
7
+
8
+ - Cuidar validaciones de nombre y rutas.
9
+ - No introducir dependencias innecesarias.