@ancleto/spec 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.
- package/README.md +46 -0
- package/agents/coder.md +149 -0
- package/agents/context-resolver.md +102 -0
- package/agents/documenter.md +157 -0
- package/agents/memory-keeper.md +142 -0
- package/agents/orchestrator.md +423 -0
- package/agents/reviewer.md +205 -0
- package/agents/spec-writer.md +105 -0
- package/agents/technical-discovery.md +134 -0
- package/agents/technical-seed-writer.md +56 -0
- package/agents/tester.md +179 -0
- package/commands/opsx-apply.md +161 -0
- package/commands/opsx-archive.md +172 -0
- package/commands/opsx-bulk-archive.md +255 -0
- package/commands/opsx-continue.md +135 -0
- package/commands/opsx-explore.md +181 -0
- package/commands/opsx-ff.md +164 -0
- package/commands/opsx-new.md +151 -0
- package/commands/opsx-onboard.md +567 -0
- package/commands/opsx-propose.md +174 -0
- package/commands/opsx-recall.md +57 -0
- package/commands/opsx-sync.md +144 -0
- package/commands/opsx-verify.md +176 -0
- package/package.json +41 -0
- package/skills/ancleto-commit/SKILL.md +118 -0
- package/skills/ancleto-pr/SKILL.md +164 -0
- package/skills/ancleto-technical-discovery/SKILL.md +74 -0
- package/skills/ancleto-technical-discovery/references/archetypes/api-layered.md +8 -0
- package/skills/ancleto-technical-discovery/references/archetypes/monorepo.md +8 -0
- package/skills/ancleto-technical-discovery/references/archetypes/ops-tooling.md +7 -0
- package/skills/ancleto-technical-discovery/references/archetypes/service-legacy.md +7 -0
- package/skills/ancleto-technical-discovery/references/archetypes/spa.md +7 -0
- package/skills/ancleto-technical-discovery/references/discovery-config.md +24 -0
- package/skills/ancleto-technical-discovery/references/generation-pipeline.md +56 -0
- package/skills/ancleto-technical-discovery/references/node-frontmatter.md +30 -0
- package/skills/ancleto-technical-discovery/references/output-contract.md +36 -0
- package/skills/ancleto-technical-discovery/references/templates/dossier.md +38 -0
- package/skills/ancleto-technical-discovery/references/templates/inventory.md +22 -0
- package/skills/ancleto-technical-discovery/references/templates/setup.md +27 -0
- package/skills/ancleto-technical-discovery/references/validation-checklist.md +12 -0
- package/skills/ancleto-upgrade/SKILL.md +449 -0
- package/skills/ancleto-upgrade/references/templates.md +320 -0
- package/src/cli/index.js +119 -0
- package/templates/AGENTS.md +36 -0
- package/templates/CONTRIBUTING.md +25 -0
- package/templates/PRODUCT.md +180 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# Templates — Artefactos OpenSpec
|
|
2
|
+
|
|
3
|
+
Este archivo contiene los templates exactos para los cuatro artefactos que genera
|
|
4
|
+
el skill. Leer este archivo en el Paso 6 y completar cada placeholder `{...}`.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## proposal.md
|
|
9
|
+
|
|
10
|
+
```markdown
|
|
11
|
+
# Propuesta: Migración a {LIBRARY} v{TARGET_VERSION}
|
|
12
|
+
|
|
13
|
+
## Contexto
|
|
14
|
+
|
|
15
|
+
{Descripción del estado actual: versión actual de LIBRARY instalada, razón para migrar
|
|
16
|
+
(EOL, mejoras de performance, compatibilidad, nuevas features). Si se obtuvo documentación
|
|
17
|
+
oficial, resumir los puntos más relevantes del changelog aquí.}
|
|
18
|
+
|
|
19
|
+
## Cobertura del análisis
|
|
20
|
+
|
|
21
|
+
- source files analizados: {source_files_scanned}
|
|
22
|
+
- test files analizados: {test_files_scanned}
|
|
23
|
+
- config files analizados: {config_files_scanned}
|
|
24
|
+
- archivos con matches: {files_with_matches}
|
|
25
|
+
- archivos sin matches: {files_without_matches}
|
|
26
|
+
|
|
27
|
+
## Alcance del cambio
|
|
28
|
+
|
|
29
|
+
### Dependencias afectadas — {N} paquetes en {M} package.json
|
|
30
|
+
|
|
31
|
+
| package.json | Paquete | Versión actual | Versión objetivo |
|
|
32
|
+
| ------------ | ------- | -------------- | ---------------- |
|
|
33
|
+
|
|
34
|
+
{Una fila por cada entry en DEPENDENCY_CHANGES[]}
|
|
35
|
+
|
|
36
|
+
### Archivos de configuración a modificar — {N} archivos
|
|
37
|
+
|
|
38
|
+
{Lista de archivos con descripción del cambio requerido. Si no hay, escribir "Ninguno."}
|
|
39
|
+
|
|
40
|
+
### Código fuente con breaking changes — {N} archivos
|
|
41
|
+
|
|
42
|
+
{Lista de archivos afectados con el breaking change detectado. Si no hay, escribir "Ninguno."}
|
|
43
|
+
|
|
44
|
+
### Tests con breaking changes — {N} archivos
|
|
45
|
+
|
|
46
|
+
{Lista de archivos de test afectados. Si no hay, escribir "Ninguno."}
|
|
47
|
+
|
|
48
|
+
## Evaluación de breaking changes
|
|
49
|
+
|
|
50
|
+
{Para cada KNOWN_BREAK relevante a la migración:}
|
|
51
|
+
|
|
52
|
+
- ✅ AFECTA — {id}: {description} — {N} ocurrencias en {M} archivos
|
|
53
|
+
- ✓ NO AFECTA — {id}: {description}
|
|
54
|
+
|
|
55
|
+
## Matches de baja confianza
|
|
56
|
+
|
|
57
|
+
{Lista de UNSURE_MATCHES[] para revisión manual. Si no hay, escribir "Ninguno."}
|
|
58
|
+
|
|
59
|
+
## Decisión
|
|
60
|
+
|
|
61
|
+
Migrar {LIBRARY} {CURRENT_VERSION} → v{TARGET_VERSION}.
|
|
62
|
+
|
|
63
|
+
Fuente de información: {DOCS_URL | "Búsqueda web: {query}" | "Knowledge base interna"}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## specs/{LIBRARY_SLUG}{TARGET_VERSION}.md
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
# Especificaciones: {LIBRARY} v{TARGET_VERSION} Migration
|
|
72
|
+
|
|
73
|
+
## Dependencias
|
|
74
|
+
|
|
75
|
+
{Para cada entry en DEPENDENCY_CHANGES[]:}
|
|
76
|
+
|
|
77
|
+
- REQ-D-{N}: `{package_name}` en `{path}` SHALL usar versión `^{TARGET_VERSION}.0.0`
|
|
78
|
+
|
|
79
|
+
## Configuración
|
|
80
|
+
|
|
81
|
+
{Para cada entry en CONFIG_CHANGES[]:}
|
|
82
|
+
|
|
83
|
+
- REQ-C-{N}: `{file}` SHALL {descripción del cambio requerido}
|
|
84
|
+
|
|
85
|
+
{Si CONFIG_CHANGES está vacío:}
|
|
86
|
+
No se requieren cambios de configuración.
|
|
87
|
+
|
|
88
|
+
## Código fuente
|
|
89
|
+
|
|
90
|
+
{Para cada entry en BREAKING_CHANGES_IN_CODE[]:}
|
|
91
|
+
|
|
92
|
+
- REQ-S-{N} [{break_id}]: {descripción del cambio requerido en el código}
|
|
93
|
+
Evidencia: `{file}:{line_number}` ({confidence})
|
|
94
|
+
|
|
95
|
+
{Si BREAKING_CHANGES_IN_CODE está vacío:}
|
|
96
|
+
No se detectaron breaking changes en código fuente.
|
|
97
|
+
|
|
98
|
+
## Tests
|
|
99
|
+
|
|
100
|
+
{Para cada entry en BREAKING_CHANGES_IN_TESTS[]:}
|
|
101
|
+
|
|
102
|
+
- REQ-T-{N} [{break_id}]: {descripción del cambio requerido en los tests}
|
|
103
|
+
Evidencia: `{file}:{line_number}` ({confidence})
|
|
104
|
+
|
|
105
|
+
{Si BREAKING_CHANGES_IN_TESTS está vacío:}
|
|
106
|
+
No se detectaron breaking changes en tests.
|
|
107
|
+
|
|
108
|
+
## Verificación
|
|
109
|
+
|
|
110
|
+
- REQ-V-001: El proyecto SHALL compilar sin errores TypeScript
|
|
111
|
+
- REQ-V-002: Todos los tests SHALL pasar luego de la migración
|
|
112
|
+
{Si lint script existe:}
|
|
113
|
+
- REQ-V-003: El proyecto SHALL pasar lint sin errores
|
|
114
|
+
|
|
115
|
+
## Cobertura
|
|
116
|
+
|
|
117
|
+
- REQ-X-001: El análisis SHALL incluir todo archivo de código fuente elegible (`.ts`, `.tsx`, `.js`) excluyendo `node_modules`, `dist` y artefactos generados
|
|
118
|
+
- REQ-X-002: El análisis SHALL incluir todo archivo de tests elegible (`*.spec.*`, `*.test.*`)
|
|
119
|
+
- REQ-X-003: El resultado SHALL reportar métricas de cobertura (`source_files_scanned`, `test_files_scanned`, `config_files_scanned`)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## tasks.md
|
|
125
|
+
|
|
126
|
+
````markdown
|
|
127
|
+
# Tasks: {LIBRARY} v{TARGET_VERSION} Migration
|
|
128
|
+
|
|
129
|
+
## Fase 1: Dependencias
|
|
130
|
+
|
|
131
|
+
{Para cada entry en DEPENDENCY_CHANGES[]:}
|
|
132
|
+
|
|
133
|
+
- [ ] **T-D-{N}** Actualizar `{package_name}` en `{path}` de `{current_version}` a `^{TARGET_VERSION}.0.0`
|
|
134
|
+
|
|
135
|
+
- [ ] **T-D-LAST** Regenerar lockfile:
|
|
136
|
+
```bash
|
|
137
|
+
npm install
|
|
138
|
+
```
|
|
139
|
+
````
|
|
140
|
+
|
|
141
|
+
## Fase 2: Infraestructura y runtime
|
|
142
|
+
|
|
143
|
+
{Solo si IS_RUNTIME = true:}
|
|
144
|
+
{Si .nvmrc existe o debe crearse:}
|
|
145
|
+
|
|
146
|
+
- [ ] **T-I-001** {Crear | Actualizar} `.nvmrc` con el valor `{TARGET_VERSION}`
|
|
147
|
+
|
|
148
|
+
{Para cada CI file con nodeVersion a cambiar:}
|
|
149
|
+
|
|
150
|
+
- [ ] **T-I-002** Actualizar `nodeVersion` en `{CI_FILE}` de `{current}` a `{TARGET_VERSION}.x`
|
|
151
|
+
|
|
152
|
+
{Para cada Dockerfile con FROM node:X:}
|
|
153
|
+
|
|
154
|
+
- [ ] **T-I-003** Actualizar imagen base en `{Dockerfile}`:
|
|
155
|
+
```dockerfile
|
|
156
|
+
# Antes
|
|
157
|
+
FROM node:{current}-alpine
|
|
158
|
+
# Después
|
|
159
|
+
FROM node:{TARGET_VERSION}-alpine
|
|
160
|
+
```
|
|
161
|
+
_(Ajustar variant según el Dockerfile existente: alpine, slim, bullseye, etc.)_
|
|
162
|
+
|
|
163
|
+
{Para cada appSettings.json con "Runtime":}
|
|
164
|
+
|
|
165
|
+
- [ ] **T-I-004** Actualizar `Runtime` en `{appSettings.json}` a `NODEJS_{TARGET_VERSION}_X`
|
|
166
|
+
|
|
167
|
+
{Si IS*RUNTIME = false:}
|
|
168
|
+
*(No aplica para migraciones de librería)\_
|
|
169
|
+
|
|
170
|
+
## Fase 3: Configuración de build y tests
|
|
171
|
+
|
|
172
|
+
{Para cada entry en CONFIG_CHANGES[]:}
|
|
173
|
+
|
|
174
|
+
- [ ] **T-C-{N}** {Descripción concreta del cambio}
|
|
175
|
+
Archivo: `{file}`
|
|
176
|
+
```
|
|
177
|
+
// Antes
|
|
178
|
+
{current_value}
|
|
179
|
+
// Después
|
|
180
|
+
{target_value}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
{Si CONFIG*CHANGES está vacío:}
|
|
184
|
+
*(No se detectaron cambios de configuración necesarios)\_
|
|
185
|
+
|
|
186
|
+
## Fase 4: Breaking changes en código fuente
|
|
187
|
+
|
|
188
|
+
{Para cada entry en BREAKING_CHANGES_IN_CODE[]:}
|
|
189
|
+
|
|
190
|
+
- [ ] **T-S-{N}** [{break_id}] `{severity}` — {description}
|
|
191
|
+
Fix: {fix}
|
|
192
|
+
Archivos afectados:
|
|
193
|
+
{Para cada {file, line_number, snippet}:}
|
|
194
|
+
- `{file}:{line_number}` ({confidence}) — `{snippet}`
|
|
195
|
+
|
|
196
|
+
{Si BREAKING*CHANGES_IN_CODE está vacío:}
|
|
197
|
+
*(No se detectaron breaking changes en código fuente para esta migración)\_
|
|
198
|
+
|
|
199
|
+
## Fase 5: Breaking changes en tests
|
|
200
|
+
|
|
201
|
+
{Para cada entry en BREAKING_CHANGES_IN_TESTS[]:}
|
|
202
|
+
|
|
203
|
+
- [ ] **T-T-{N}** [{break_id}] `{severity}` — {description}
|
|
204
|
+
Fix: {fix}
|
|
205
|
+
Archivos afectados:
|
|
206
|
+
{Para cada {file, line_number, snippet}:}
|
|
207
|
+
- `{file}:{line_number}` ({confidence}) — `{snippet}`
|
|
208
|
+
|
|
209
|
+
{Si BREAKING*CHANGES_IN_TESTS está vacío:}
|
|
210
|
+
*(No se detectaron breaking changes en tests para esta migración)\_
|
|
211
|
+
|
|
212
|
+
## Fase 6: Verificación
|
|
213
|
+
|
|
214
|
+
- [ ] **T-V-001** Verificar compilación TypeScript:
|
|
215
|
+
```bash
|
|
216
|
+
npx tsc --noEmit
|
|
217
|
+
# En monorepos Nx: npx nx affected --target=typecheck
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
{Si script "build" en SCRIPTS_AVAILABLE[]:}
|
|
221
|
+
|
|
222
|
+
- [ ] **T-V-002** Verificar build:
|
|
223
|
+
```bash
|
|
224
|
+
npm run build
|
|
225
|
+
# En monorepos Nx: npx nx affected --target=build
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
{Si script "lint" en SCRIPTS_AVAILABLE[]:}
|
|
229
|
+
|
|
230
|
+
- [ ] **T-V-003** Ejecutar linter:
|
|
231
|
+
```bash
|
|
232
|
+
npm run lint
|
|
233
|
+
# En monorepos Nx: npx nx affected:lint
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
{Si script "test" en SCRIPTS_AVAILABLE[]:}
|
|
237
|
+
|
|
238
|
+
- [ ] **T-V-004** Correr suite de tests:
|
|
239
|
+
```bash
|
|
240
|
+
npm test
|
|
241
|
+
# En monorepos Nx: npx nx affected --target=test
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
{Si script "test:ci" en SCRIPTS_AVAILABLE[]:}
|
|
245
|
+
|
|
246
|
+
- [ ] **T-V-005** Correr tests en modo CI:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm run test:ci
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
- [ ] **T-V-900** Validar cobertura del escaneo:
|
|
253
|
+
- confirmar conteo de archivos escaneados (source/tests/config)
|
|
254
|
+
- revisar `UNSURE_MATCHES[]` y clasificar cada caso
|
|
255
|
+
|
|
256
|
+
````
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## design.md
|
|
261
|
+
|
|
262
|
+
```markdown
|
|
263
|
+
# Design: {LIBRARY} v{TARGET_VERSION} Migration
|
|
264
|
+
|
|
265
|
+
## Estrategia de migración
|
|
266
|
+
|
|
267
|
+
{Explicar el enfoque en orden de las fases: primero dependencias (para detectar errores
|
|
268
|
+
de compilación antes de tocar código), luego infraestructura, luego config, luego código.
|
|
269
|
+
Describir el riesgo principal y cómo se mitiga.}
|
|
270
|
+
|
|
271
|
+
## Decisiones técnicas
|
|
272
|
+
|
|
273
|
+
### Rango de versión — `^{TARGET_VERSION}.0.0`
|
|
274
|
+
|
|
275
|
+
Se usa caret (`^`) en lugar de pin exacto para recibir parches y minor automáticamente,
|
|
276
|
+
manteniendo la estabilidad del major. Se evita `>=` para no aceptar accidentalmente el
|
|
277
|
+
próximo major con potenciales breaking changes.
|
|
278
|
+
|
|
279
|
+
### Cambios de configuración
|
|
280
|
+
|
|
281
|
+
{Para cada CONFIG_CHANGE relevante: explicar el razonamiento técnico.}
|
|
282
|
+
{Ej para MIDDY7-001: "Jest necesita transformIgnorePatterns porque @middy v7 publica
|
|
283
|
+
ESM puro y Jest por defecto no transpila node_modules. Sin este cambio, los tests
|
|
284
|
+
fallan con SyntaxError en el import."}
|
|
285
|
+
|
|
286
|
+
### Breaking changes — análisis de impacto
|
|
287
|
+
|
|
288
|
+
{Para cada breaking change encontrado: explicar el impacto técnico y por qué el fix
|
|
289
|
+
propuesto es la solución correcta y no un workaround.}
|
|
290
|
+
|
|
291
|
+
{Si no hay breaking changes: "No se detectaron breaking changes en este repositorio
|
|
292
|
+
para esta migración. El riesgo es bajo."}
|
|
293
|
+
|
|
294
|
+
### Compatibilidad del ecosistema
|
|
295
|
+
|
|
296
|
+
{Mencionar dependencias relacionadas que pueden verse afectadas.}
|
|
297
|
+
{Ej para Middy v7: listar middlewares de terceros y su estado de compatibilidad con v7.}
|
|
298
|
+
{Si no aplica: "No se identificaron dependencias del ecosistema con riesgo de incompatibilidad."}
|
|
299
|
+
|
|
300
|
+
### Calidad del análisis
|
|
301
|
+
|
|
302
|
+
- Cobertura: {source_files_scanned} source, {test_files_scanned} tests, {config_files_scanned} config
|
|
303
|
+
- Matches de alta confianza: {N}
|
|
304
|
+
- Matches de media confianza: {N}
|
|
305
|
+
- Matches de baja confianza: {N}
|
|
306
|
+
- Estrategia de revisión manual para baja confianza: {criterio aplicado}
|
|
307
|
+
|
|
308
|
+
## Tabla de cambios
|
|
309
|
+
|
|
310
|
+
| Archivo | Campo / Patrón | Antes | Después |
|
|
311
|
+
|---------|----------------|-------|---------|
|
|
312
|
+
{Una fila por cada cambio concreto en DEPENDENCY_CHANGES[], CONFIG_CHANGES[],
|
|
313
|
+
BREAKING_CHANGES_IN_CODE[] y BREAKING_CHANGES_IN_TESTS[]}
|
|
314
|
+
|
|
315
|
+
## Referencias
|
|
316
|
+
|
|
317
|
+
- {DOCS_URL si está disponible}
|
|
318
|
+
- {Links adicionales encontrados durante el análisis}
|
|
319
|
+
- Knowledge base interna consultada: {lista de break_ids relevantes de known-breaks.md}
|
|
320
|
+
````
|
package/src/cli/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { cp, mkdir, access, writeFile, readFile } from 'node:fs/promises'
|
|
3
|
+
import { join, dirname, resolve } from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { homedir } from 'node:os'
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
const ROOT = join(__dirname, '..', '..')
|
|
9
|
+
const ASSETS = ['agents', 'commands', 'skills']
|
|
10
|
+
const TEMPLATES = ['AGENTS.md', 'PRODUCT.md', 'CONTRIBUTING.md']
|
|
11
|
+
|
|
12
|
+
const HELP = `ancleto - orquestador SDD liviano con subagentes optimizados para costo/tokens
|
|
13
|
+
(alias: aspec)
|
|
14
|
+
|
|
15
|
+
Uso:
|
|
16
|
+
ancleto install [--project <dir>] Instala agents/commands/skills en opencode
|
|
17
|
+
(global por defecto, o en .opencode/ del proyecto)
|
|
18
|
+
ancleto update [--project <dir>] Alias de install (re-instala sobre lo existente)
|
|
19
|
+
ancleto init Crea .ancletorc en el repositorio actual
|
|
20
|
+
ancleto discovery --check Estado del technical seed (no implementado aun)
|
|
21
|
+
ancleto discovery --compress Genera el pack del repo (no implementado aun)
|
|
22
|
+
ancleto --help Esta ayuda
|
|
23
|
+
ancleto --version Version del paquete
|
|
24
|
+
`
|
|
25
|
+
|
|
26
|
+
async function exists(p) {
|
|
27
|
+
try { await access(p); return true } catch { return false }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function globalConfigDir() {
|
|
31
|
+
return process.env.XDG_CONFIG_HOME
|
|
32
|
+
? join(process.env.XDG_CONFIG_HOME, 'opencode')
|
|
33
|
+
: join(homedir(), '.config', 'opencode')
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function copyAssets(dest) {
|
|
37
|
+
await mkdir(dest, { recursive: true })
|
|
38
|
+
for (const d of ASSETS) {
|
|
39
|
+
await cp(join(ROOT, d), join(dest, d), { recursive: true })
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function copyTemplates(projectDir) {
|
|
44
|
+
const dest = join(projectDir, '.opencode')
|
|
45
|
+
await copyAssets(dest)
|
|
46
|
+
for (const t of TEMPLATES) {
|
|
47
|
+
const target = join(projectDir, t)
|
|
48
|
+
if (await exists(target)) continue
|
|
49
|
+
await writeFile(target, await readFile(join(ROOT, 'templates', t)))
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function install(args) {
|
|
54
|
+
const pi = args.indexOf('--project')
|
|
55
|
+
const project = pi >= 0 ? args[pi + 1] : null
|
|
56
|
+
if (project) {
|
|
57
|
+
const dir = resolve(project)
|
|
58
|
+
if (!(await exists(dir))) {
|
|
59
|
+
console.error(`ancleto: el directorio no existe: ${dir}`)
|
|
60
|
+
process.exit(1)
|
|
61
|
+
}
|
|
62
|
+
await copyTemplates(dir)
|
|
63
|
+
console.log(`ancleto: instalado en ${dir} (.opencode/ + templates en la raiz)`)
|
|
64
|
+
} else {
|
|
65
|
+
const target = globalConfigDir()
|
|
66
|
+
await copyAssets(target)
|
|
67
|
+
console.log(`ancleto: instalado en ${target} (disponible en todos tus proyectos)`)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function initProject() {
|
|
72
|
+
const rc = join(process.cwd(), '.ancletorc')
|
|
73
|
+
if (await exists(rc)) {
|
|
74
|
+
console.log('ancleto: .ancletorc ya existe, no se toca')
|
|
75
|
+
return
|
|
76
|
+
}
|
|
77
|
+
const content = JSON.stringify({
|
|
78
|
+
version: 1,
|
|
79
|
+
discovery: {
|
|
80
|
+
outputDir: 'docs/technical-discovery',
|
|
81
|
+
exclude: []
|
|
82
|
+
}
|
|
83
|
+
}, null, 2)
|
|
84
|
+
await writeFile(rc, content + '\n')
|
|
85
|
+
console.log(`ancleto: .ancletorc creado en ${process.cwd()}`)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function discovery() {
|
|
89
|
+
console.error('ancleto: discovery todavia no esta implementado (motor de repomix pendiente).')
|
|
90
|
+
process.exit(1)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const [cmd, ...rest] = process.argv.slice(2)
|
|
94
|
+
|
|
95
|
+
switch (cmd) {
|
|
96
|
+
case 'install':
|
|
97
|
+
case 'update':
|
|
98
|
+
await install(rest)
|
|
99
|
+
break
|
|
100
|
+
case 'init':
|
|
101
|
+
await initProject()
|
|
102
|
+
break
|
|
103
|
+
case 'discovery':
|
|
104
|
+
discovery()
|
|
105
|
+
break
|
|
106
|
+
case '--version':
|
|
107
|
+
case '-v':
|
|
108
|
+
console.log('ancleto 0.1.0')
|
|
109
|
+
break
|
|
110
|
+
case '--help':
|
|
111
|
+
case '-h':
|
|
112
|
+
case undefined:
|
|
113
|
+
console.log(HELP)
|
|
114
|
+
break
|
|
115
|
+
default:
|
|
116
|
+
console.error(`ancleto: comando desconocido: ${cmd}`)
|
|
117
|
+
console.log(HELP)
|
|
118
|
+
process.exit(1)
|
|
119
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# AI Agents Context
|
|
2
|
+
|
|
3
|
+
> Contexto global para agentes de IA en este repositorio.
|
|
4
|
+
|
|
5
|
+
## Context Hierarchy
|
|
6
|
+
|
|
7
|
+
Antes de actuar, consultar el contexto en este orden:
|
|
8
|
+
|
|
9
|
+
1. El `AGENTS.md` local del package o app afectada, si existe.
|
|
10
|
+
2. `PRODUCT.md` para contexto del repositorio, estructura, comandos y reglas de producto.
|
|
11
|
+
3. `CONTRIBUTING.md` para el flujo de contribución y validaciones esperadas.
|
|
12
|
+
4. Este `AGENTS.md` como marco común.
|
|
13
|
+
|
|
14
|
+
En caso de conflicto, gana la documentación más específica del área afectada.
|
|
15
|
+
|
|
16
|
+
## Guardrails
|
|
17
|
+
|
|
18
|
+
- Cambios de TypeScript en modo estricto donde aplique.
|
|
19
|
+
- Mantener el repositorio en estado mergeable.
|
|
20
|
+
- No commits directos a ramas protegidas (`main`, `develop`).
|
|
21
|
+
- Commits con Conventional Commits.
|
|
22
|
+
- Toda operación destructiva requiere confirmación explícita del usuario.
|
|
23
|
+
- Antes de cerrar un cambio, correr las validaciones que el proyecto considere necesarias.
|
|
24
|
+
|
|
25
|
+
## Flujo de trabajo
|
|
26
|
+
|
|
27
|
+
Este repositorio usa el flujo spec-driven (OpenSpec) cuando corresponde:
|
|
28
|
+
|
|
29
|
+
- Cambios nuevos o con scope incierto: artifacts en `openspec/changes/<name>/`
|
|
30
|
+
- Cambios chicos y de riesgo bajo: implementación directa
|
|
31
|
+
- Archivar con `openspec archive` cuando el cambio este completo
|
|
32
|
+
|
|
33
|
+
## Herramientas
|
|
34
|
+
|
|
35
|
+
- `ancleto` CLI para inicialización de proyectos y descubrimiento técnico.
|
|
36
|
+
- `openspec` CLI para el ciclo de changes (proposal, specs, design, tasks, archive).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Guía de contribución para este repositorio personal.
|
|
4
|
+
|
|
5
|
+
## Flujo
|
|
6
|
+
|
|
7
|
+
1. Crear rama de features: `feat/`, `fix/`, `chore/`
|
|
8
|
+
2. Commits en formato Conventional Commits:
|
|
9
|
+
- `feat(scope): descripcion en presente`
|
|
10
|
+
- `fix(scope): descripcion en presente`
|
|
11
|
+
- `chore(scope): descripcion en presente`
|
|
12
|
+
- `docs(scope): ...`
|
|
13
|
+
- `refactor(scope): ...`
|
|
14
|
+
- `test(scope): ...`
|
|
15
|
+
4. Abrir PR/merge request contra `main` con título semántico y plan de pruebas cuando aplique.
|
|
16
|
+
5. No forzar push ni saltar hooks de validación.
|
|
17
|
+
|
|
18
|
+
## Validaciones
|
|
19
|
+
|
|
20
|
+
Correr antes de cerrar un cambio (según el proyecto):
|
|
21
|
+
|
|
22
|
+
- `npm run typecheck` / `tsc --noEmit`
|
|
23
|
+
- `npm run lint`
|
|
24
|
+
- `npm test`
|
|
25
|
+
- `npm run build`
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Product Context - [Product Name]
|
|
2
|
+
|
|
3
|
+
> **This file is EXTENSIBLE and will never be replaced by @ancleto/ai-tooling-framework**
|
|
4
|
+
>
|
|
5
|
+
> Fill in the sections according to your product/project. This file is read by AI agents (Claude, Cursor, etc.) to understand the specific context of your product.
|
|
6
|
+
|
|
7
|
+
> **How to complete this file:** replace `[Product Name]` in the title and fill each section with your product's real values, deleting the example/placeholder text as you go. At a minimum, complete **Project Type**, **Tech Stack**, **Azure DevOps**, **AI Memory**, **Project Structure**, and **Project Commands** — agents rely on these to operate in your repo. The remaining sections are optional but recommended.
|
|
8
|
+
|
|
9
|
+
## Project Type
|
|
10
|
+
|
|
11
|
+
_Describe the project type: Web App, API, Library, Monorepo, etc._
|
|
12
|
+
|
|
13
|
+
**Example:**
|
|
14
|
+
|
|
15
|
+
- Web application with SSR
|
|
16
|
+
- REST API with Node.js
|
|
17
|
+
- Shared TypeScript library
|
|
18
|
+
- Nx/Lerna monorepo
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Tech Stack
|
|
23
|
+
|
|
24
|
+
_List the project's main technologies._
|
|
25
|
+
|
|
26
|
+
**Base stack:**
|
|
27
|
+
|
|
28
|
+
- **Runtime**: Node.js 20.x
|
|
29
|
+
- **Language**: TypeScript
|
|
30
|
+
- **Build**: Nx / Webpack / Vite (depending on the project)
|
|
31
|
+
- **Testing**: Jest + Testing Library
|
|
32
|
+
- **CI/CD**: Azure DevOps
|
|
33
|
+
|
|
34
|
+
**Additional per project:**
|
|
35
|
+
|
|
36
|
+
- Framework: React / Vue / Angular / Express
|
|
37
|
+
- State: Redux / Context / Zustand
|
|
38
|
+
- Styling: TailwindCSS / Sass / CSS-in-JS
|
|
39
|
+
- Infra: AWS CDK / Serverless / Containers
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Azure DevOps
|
|
44
|
+
|
|
45
|
+
_How this project retrieves work items and other Azure DevOps resources. AI agents read this to resolve cards._
|
|
46
|
+
|
|
47
|
+
**Fill in for your project:**
|
|
48
|
+
|
|
49
|
+
- **Organization URL**: https://dev.azure.com/your-org
|
|
50
|
+
- **Team Project**: YourProject
|
|
51
|
+
|
|
52
|
+
Keep the `Organization URL` value as a plain URL, on a line containing the words `Organization URL` — the fetch command below reads it from here with a `grep`.
|
|
53
|
+
|
|
54
|
+
**Work items (card fetch):** via the `az` CLI (`azure-devops` extension), in a single call:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
ORG=$(grep -Eim1 '\*\*(Organization URL|Organization)\*\*:' PRODUCT.md | grep -oE 'https?://[^ `"]+') && \
|
|
58
|
+
az boards work-item show --id <id> --org "$ORG" --expand none --fields System.Id,System.Title,System.WorkItemType,System.TeamProject,System.State,System.Description,Microsoft.VSTS.Common.AcceptanceCriteria \
|
|
59
|
+
| sed 's/\\r\\n/\n/g; s/\\n/\n/g; s/<[^>]*>//g; s/ / /g; s/"/"/g; s/</</g; s/>/>/g; s/&/\&/g' \
|
|
60
|
+
| fold -s -w 200
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- **Required inputs**: `id` (card number) + `org`. Do NOT pass `--project` — it fails with `unrecognized arguments: --project`; the id is org-global and the project comes back as `System.TeamProject`.
|
|
64
|
+
- **The organization is read from this file by the shell**, from the `Organization URL` line above — one substitution inside the same call, instead of an agent reading this whole file into its context.
|
|
65
|
+
- **Always project with `--expand none --fields`**: the CLI defaults to `--expand all` and returns the entire work item. `--fields` without `--expand none` fails with `The expand parameter can not be used with the fields parameter`.
|
|
66
|
+
- **`sed` + `fold` are not cosmetic**: `System.Description` arrives as a single HTML line that can exceed 70.000 characters, and the agent runtime truncates long lines at 2.000 — without them the agent silently receives a fraction of the description.
|
|
67
|
+
- **Response fields used** (`.fields`): `System.Id`, `System.Title`, `System.Description`, `Microsoft.VSTS.Common.AcceptanceCriteria`, `System.WorkItemType`, `System.TeamProject`, `System.State`.
|
|
68
|
+
- **Setup/auth**: requires `az extension add --name azure-devops`; `az login` (AAD) is enough — a PAT (`AZURE_DEVOPS_EXT_PAT`) only as a fallback.
|
|
69
|
+
|
|
70
|
+
## AI Memory
|
|
71
|
+
|
|
72
|
+
- **Repository App ID**: ancleto.YourProject
|
|
73
|
+
|
|
74
|
+
`Repository App ID` identifies this repository in the shared mem0 store. Agents use it to isolate memories from other repositories. It must be unique to this repository, not shared across the Azure DevOps team project.
|
|
75
|
+
|
|
76
|
+
`Team Project` from the Azure DevOps section is stored as `project_id` in mem0. Complete both `Repository App ID` and `Team Project` before using AI memory.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Project Structure
|
|
81
|
+
|
|
82
|
+
_Describe the project's main folder structure._
|
|
83
|
+
|
|
84
|
+
**Example for a monorepo:**
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
libs/ # Shared libraries
|
|
88
|
+
apps/ # Applications
|
|
89
|
+
tools/ # Build tools
|
|
90
|
+
openspec/ # OpenSpec configuration
|
|
91
|
+
config.yaml # Project context
|
|
92
|
+
changes/ # Active changes
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Example for a standalone app:**
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
src/
|
|
99
|
+
components/ # Reusable components
|
|
100
|
+
features/ # Business features
|
|
101
|
+
services/ # Services and APIs
|
|
102
|
+
utils/ # Utilities
|
|
103
|
+
openspec/
|
|
104
|
+
config.yaml
|
|
105
|
+
changes/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Critical Files & Guardrails
|
|
111
|
+
|
|
112
|
+
_Project-specific critical files or folders that require special care._
|
|
113
|
+
|
|
114
|
+
**Take special care when modifying:**
|
|
115
|
+
|
|
116
|
+
**Example:**
|
|
117
|
+
|
|
118
|
+
- Code in `src/core/` (affects the whole app)
|
|
119
|
+
- Routing configuration
|
|
120
|
+
- Shared assets
|
|
121
|
+
- Infrastructure (CDK, Terraform, etc.)
|
|
122
|
+
|
|
123
|
+
**Avoid:**
|
|
124
|
+
|
|
125
|
+
- Architecture changes without documenting them in OpenSpec
|
|
126
|
+
- Introducing new dependencies without reviewing existing ones
|
|
127
|
+
- Modifying established conventions without team consensus
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Project Commands
|
|
132
|
+
|
|
133
|
+
_The project's most important npm/yarn/pnpm commands._
|
|
134
|
+
|
|
135
|
+
**Example:**
|
|
136
|
+
|
|
137
|
+
- `npm run dev` → Development server
|
|
138
|
+
- `npm test` → Run tests
|
|
139
|
+
- `npm run build` → Production build
|
|
140
|
+
- `npm run lint` → Linter
|
|
141
|
+
- `npm run deploy` → Deploy (per environment)
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Team Guidelines
|
|
146
|
+
|
|
147
|
+
_Team-specific conventions, patterns, and guides._
|
|
148
|
+
|
|
149
|
+
**You can add:**
|
|
150
|
+
|
|
151
|
+
- Specific naming conventions
|
|
152
|
+
- Preferred design patterns
|
|
153
|
+
- Architecture guides
|
|
154
|
+
- Links to internal documentation
|
|
155
|
+
- Reference contacts
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Custom Commit Rules
|
|
160
|
+
|
|
161
|
+
_Project-specific commit rules (in addition to the Conventional Commits convention defined in `CONTRIBUTING.md` and `AGENTS.md`)._
|
|
162
|
+
|
|
163
|
+
**Example:**
|
|
164
|
+
|
|
165
|
+
- Use a specific scope for modules: `feat(auth):`, `fix(payments):`
|
|
166
|
+
- Include the ticket number in the commit: `feat(auth): add OAuth #JIRA-123`
|
|
167
|
+
- Team-specific breaking-change format
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## Custom Agent Configuration
|
|
172
|
+
|
|
173
|
+
_Agent configuration specific to this project._
|
|
174
|
+
|
|
175
|
+
**Example:**
|
|
176
|
+
|
|
177
|
+
- Code style preferences
|
|
178
|
+
- Patterns to follow/avoid
|
|
179
|
+
- Custom workflows
|
|
180
|
+
- Specific testing rules
|