@dforce2055/dai 0.9.0 → 0.11.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 (63) hide show
  1. package/{.env.example → .env.dai.example} +3 -3
  2. package/CHANGELOG.md +148 -0
  3. package/README.md +47 -26
  4. package/VERSION +1 -1
  5. package/cli/dai.mjs +528 -61
  6. package/cli/lib/bootstrap.mjs +44 -9
  7. package/cli/lib/branch-scope.mjs +144 -0
  8. package/cli/lib/env.mjs +12 -0
  9. package/cli/lib/forge-api.mjs +57 -0
  10. package/cli/lib/pm-adapter.mjs +16 -2
  11. package/cli/lib/pm-clickup.mjs +18 -3
  12. package/cli/lib/pm-jira.mjs +23 -3
  13. package/cli/lib/skills-source.mjs +8 -0
  14. package/cli/lib/us-format.mjs +147 -0
  15. package/docs/EJEMPLO-END-TO-END.md +78 -46
  16. package/docs/MANIFIESTO.md +2 -2
  17. package/docs/METODOLOGIA.md +25 -15
  18. package/docs/PROBAR.md +25 -15
  19. package/docs/SCRUM-CON-IA.md +11 -11
  20. package/docs/adr/0003-deteccion-y-estampado-son-comandos.md +1 -1
  21. package/docs/adr/0006-distribucion-y-licencia.md +1 -1
  22. package/docs/adr/0013-skills-externas-install-from.md +11 -4
  23. package/docs/adr/0015-jira-corporativo.md +1 -1
  24. package/docs/adr/0017-env-dai.md +64 -0
  25. package/docs/adr/0018-alcance-de-stamp-y-gate-de-ci.md +183 -0
  26. package/docs/adr/README.md +2 -0
  27. package/docs/detalle/01-refinamiento.md +20 -5
  28. package/docs/detalle/03-ramas.md +2 -2
  29. package/docs/detalle/04-tdd.md +15 -9
  30. package/docs/detalle/06-code-review.md +8 -5
  31. package/docs/detalle/07-merge-trazabilidad.md +13 -2
  32. package/docs/detalle/08-daily.md +1 -1
  33. package/docs/detalle/README.md +1 -1
  34. package/docs/glosario.md +3 -3
  35. package/docs/guias/dev.md +31 -7
  36. package/docs/guias/index.md +12 -0
  37. package/docs/guias/lead.md +1 -1
  38. package/docs/guias/po.md +53 -8
  39. package/docs/index.md +35 -0
  40. package/docs/public/favicon.svg +12 -0
  41. package/docs/public/logo-link.svg +12 -0
  42. package/docs/public/logo.svg +12 -0
  43. package/docs/public/tutoriales/clickup-1-settings.png +0 -0
  44. package/docs/public/tutoriales/clickup-2-api.png +0 -0
  45. package/docs/public/tutoriales/clickup-3-generate-copy.png +0 -0
  46. package/docs/public/tutoriales/jira-1-avatar.png +0 -0
  47. package/docs/public/tutoriales/jira-2-seguridad-tokens.png +0 -0
  48. package/docs/public/tutoriales/jira-3-crear-token.png +0 -0
  49. package/docs/public/tutoriales/jira-4-nombre-vencimiento.png +0 -0
  50. package/docs/public/tutoriales/jira-5-copiar.png +0 -0
  51. package/docs/tutoriales/claves-ssh.md +93 -0
  52. package/docs/tutoriales/configurar-git.md +53 -0
  53. package/docs/tutoriales/index.md +18 -0
  54. package/docs/tutoriales/instalar-glab.md +74 -0
  55. package/docs/tutoriales/token-clickup.md +73 -0
  56. package/docs/tutoriales/token-jira.md +74 -0
  57. package/governance/ci-rules.md +47 -8
  58. package/package.json +9 -3
  59. package/skills/dai-review/SKILL.md +1 -1
  60. package/skills/grill-epic/SKILL.md +2 -2
  61. package/skills/grill-intent/SKILL.md +1 -1
  62. package/skills/grill-user-story/SKILL.md +58 -10
  63. package/templates/ci-dai-gate.yml +50 -0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: grill-user-story
3
- description: "Interroga a un PO o analista funcional para producir una User Story funcional y testeable siguiendo el formato del modelo de trazabilidad — o pule una US vaga existente. Se queda a nivel funcional/usuario y se niega a derivar en diseño técnico o a emitir una US con criterios no testeables. Al terminar, PUBLICA la US en el tracker configurado del repo (Jira o ClickUp, según DAI_PM del .env) usando su MCP; si no hay MCP/token, deja un .md con el mismo formato para copiar y pegar. Invocar como /grill-user-story, opcionalmente con un título, un ID/URL del tracker, y/o una US rústica existente. Usar antes de opsx:propose, o cuando alguien dice \"necesito una US\", \"convierte esto en una US como corresponde\", o \"esta historia está muy vaga\"."
3
+ description: "Interroga a un PO o analista funcional para producir una User Story funcional y testeable siguiendo el formato del modelo de trazabilidad — o pule una US vaga existente. Se queda a nivel funcional/usuario y se niega a derivar en diseño técnico o a emitir una US con criterios no testeables. Al terminar la PUBLICA en el tracker configurado del repo (Jira o ClickUp, según DAI_PM de su .env.dai o .env): si la US es NUEVA la crea (MCP o `dai publish`); si YA tiene key la actualiza con `dai edit-us --no-editor`, que valida el formato y pregunta si sube el spec_version antes de pisar nada. Sin MCP ni token, deja un .md con el mismo formato para copiar y pegar. Invocar como /grill-user-story, opcionalmente con un título, un ID/URL del tracker, y/o una US rústica existente. Usar antes de opsx:propose, o cuando alguien dice \"necesito una US\", \"convierte esto en una US como corresponde\", o \"esta historia está muy vaga\"."
4
4
  ---
5
5
 
6
6
  # grill-user-story
@@ -31,15 +31,17 @@ Si no viene nada, pedir título y si hay un borrador existente.
31
31
 
32
32
  1. **Cortar en lo técnico.** Si la charla deriva a tablas, endpoints, migraciones o elección de framework, frenar: "eso es diseño, no ahora". La US nombra *qué necesita el usuario*, nunca *cómo se construye*.
33
33
  2. **Cortar en lo no testeable.** Nunca emitir un criterio que no pueda volverse un test. "El usuario tiene una buena experiencia" se rechaza. "Un carrito vacío no se puede finalizar" se acepta — funcional y verificable. Empujar cada AC hasta que sea observable.
34
- 3. **Publicar, no pedir.** Si el tracker está configurado (`DAI_PM=jira|clickup` con token en `.env`), **CREA el ticket tú** (por MCP o con `dai publish`). **Nunca** cierres pidiéndole al usuario que te "pase el ID/URL del ticket" como si ya existiera el ticket lo creas en este paso. Solo pides un ID existente si el usuario dijo explícitamente que está refinando una US ya creada.
34
+ 3. **Publicar, no pedir.** Si el tracker está configurado (`DAI_PM=jira|clickup` con token en `.env.dai` o `.env`), **dejá la US publicada tú**. **Nunca** cierres pidiéndole al usuario que te "pase el ID/URL del ticket" como si ya existiera, ni que copie y pegue el markdown al navegador. Dos caminos según si la US ya tiene key:
35
+ - **No tiene key → la CREÁS** (MCP o `dai publish`).
36
+ - **Ya tiene key → la ACTUALIZÁS con `dai edit-us <ID> --no-editor`**, nunca pisando el ticket a mano por MCP. El comando valida el formato antes de escribir, muestra qué cambia y pregunta si sube el `spec_version` — controles que por MCP no existen.
35
37
 
36
38
  ## Proceso
37
39
 
38
- 0. **Detectar el tracker (SIEMPRE, antes de nada).** Lee el archivo `.env` del repo y observa `DAI_PM`:
40
+ 0. **Detectar el tracker (SIEMPRE, antes de nada).** Lee la config de dai del repo y observa `DAI_PM`. **Está en `.env.dai` o en el `.env` del equipo: mirá los dos.** dai carga ambos, y si una clave está en los dos gana `.env.dai` (ADR-0017). Un repo que tiene todo en `.env` funciona igual — no hace falta migrar nada:
39
41
  - `DAI_PM=jira` → publicas en **Jira** (base: `DAI_JIRA_BASE_URL`), vía el MCP de Atlassian/Jira.
40
42
  - `DAI_PM=clickup` → publicas en **ClickUp**, vía el MCP de ClickUp.
41
- - `DAI_PM=md` (o sin `.env`) → no hay tracker: dejas la US como `.md`.
42
- **No asumas el tracker** — depende del `.env`. Si no hay `.env`, pregunta cuál usa el equipo.
43
+ - `DAI_PM=md` (o sin config) → no hay tracker: dejas la US como `.md`.
44
+ **No asumas el tracker** — depende de la config. Si no hay `.env.dai` ni `.env`, pregunta cuál usa el equipo.
43
45
  1. **Resolver inputs.** Obtener título e ID del tracker (si existe). Si se refina, leer la US y anotar — para uno mismo — qué secciones del formato faltan o están flojas: rol genérico ("el usuario"), falta el "para", sin flujo de excepción, solución prefijada, ACs vagos.
44
46
  2. **Grillar, un eje por vez.** No tirar un cuestionario — preguntar, escuchar, profundizar, y seguir. Cubrir en orden:
45
47
  - **Título** — corto, **3 a 6 palabras**, nombra la capacidad (de ahí sale la branch). Si el título es una frase larga, acórtalo: el detalle va en la descripción, no en el título. Ej: "Confirmar acciones con consecuencias", no "Confirmación deliberada antes de ejecutar acciones con consecuencias".
@@ -49,11 +51,18 @@ Si no viene nada, pedir título y si hay un borrador existente.
49
51
  - **Criterios de aceptación** — convertir cada flujo en una condición funcional y testeable, en Gherkin. Aplicar el corte #2 acá, fuerte.
50
52
  - **Fuera de scope** — qué NO hace esta historia (mata el scope creep más adelante).
51
53
  3. **Chequeo de tamaño (INVEST).** Si los flujos y ACs desbordan y la historia se dispersa, es demasiado grande para una sola US. No seguir empujando: **promoverla a una épica** con `/grill-epic` (que la parte en varias US independientes) y después volver acá para grillar cada US hija. Una US que no entra en un sprint es la señal de que hay una épica adentro.
52
- 4. **Publicar la US en el tracker (PASO OBLIGATORIO, ver abajo).** No termines con "¿la guardo y/o disparo el siguiente paso?": el trabajo de esta skill **incluye dejar la US publicada** en el tracker (con su key), no solo redactarla.
54
+ 4. **Dejar la US en el tracker (PASO OBLIGATORIO, ver abajo).** No termines con "¿la guardo y/o disparo el siguiente paso?": el trabajo de esta skill **incluye dejar la US publicada** en el tracker (con su key), no solo redactarla. Si la US ya existía, actualizarla cuenta como publicarla.
53
55
 
54
- ## Salida — publicar en el tracker (según `DAI_PM`), con fallback a .md
56
+ ## Salida — dejar la US en el tracker (según `DAI_PM`), con fallback a .md
55
57
 
56
- La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo que cambia es **dónde se publica** lo definió el paso 0:
58
+ La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo que cambia es **dónde va** y **si se crea o se actualiza**.
59
+
60
+ > **Primero: ¿la US ya tiene key?**
61
+ > - **No** (nació en esta sesión) → **CREAR** — pasos 1–4 de abajo.
62
+ > - **Sí** (el usuario trajo `ABC-482`, o vos la creaste antes en esta misma charla) →
63
+ > **ACTUALIZAR** — saltá a *"Si la US ya existe"*.
64
+
65
+ ### Si la US es nueva (crear)
57
66
 
58
67
  1. **Armar la US** completa: metadata de trazabilidad (`ID`, `spec_version: v1`, autor, repos esperados) + historia + contexto + casos de uso + criterios Gherkin + fuera de scope + reglas + dependencias + métricas.
59
68
  2. **Publicar en el tracker que dice `DAI_PM`:**
@@ -62,10 +71,10 @@ La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo q
62
71
  - Confirmar al usuario con el link al ticket publicado.
63
72
  - **Importante:** los criterios SIEMPRE van bajo `## Criterios de aceptación` en la descripción — así `dai link-us`/`check` los encuentran, sin importar el tracker.
64
73
  3. **Fallback SIN MCP → publicar con el CLI (`dai publish`):**
65
- - Si NO hay MCP del tracker conectado (pero sí `DAI_PM=jira|clickup` + token en `.env`):
74
+ - Si NO hay MCP del tracker conectado (pero sí `DAI_PM=jira|clickup` + token en `.env.dai` o `.env`):
66
75
  escribe la US como `.md` (formato `formato-us.md`) y publícala con el comando:
67
76
  **`dai publish <ruta-del-md>`** → crea el issue/tarea vía REST y devuelve el key.
68
- (Jira necesita además `DAI_JIRA_PROJECT` en el `.env` — la clave del **proyecto**,
77
+ (Jira necesita además `DAI_JIRA_PROJECT` — la clave del **proyecto**,
69
78
  `PROJ`, no la de un ticket.)
70
79
  - **Si la US pertenece a una épica:** `dai publish <us.md> --parent <KEY-de-la-épica>`.
71
80
  - **Si el proyecto exige campos propios** (típico en Jira corporativo): van con
@@ -82,6 +91,45 @@ La US se produce UNA vez con el formato de `../../templates/formato-us.md`. Lo q
82
91
  atajo publica igual, pero el `## Criterios de aceptación` puede quedar mal formado y
83
92
  **el link QUÉ↔CÓMO se rompe en silencio**. Si el error nombra un campo obligatorio que
84
93
  falta, decláralo en `.dai/jira-fields.json` (molde en `.dai/templates/`) y reintenta.
94
+ ### Si la US ya existe (refinar) — `dai edit-us`
95
+
96
+ Cuando la US **ya tiene key**, el trabajo no es crearla sino **pisarla con la versión
97
+ refinada**. Eso NO se hace por MCP ni editando el ticket en el navegador: se hace con
98
+
99
+ ```bash
100
+ dai edit-us <ID> --us <ruta-del-md> --no-editor
101
+ ```
102
+
103
+ Escribí la US refinada al `.md` y pasáselo. `--no-editor` es lo que hace que el comando
104
+ sirva desde una skill: no abre `$EDITOR` (vos ya editaste), pero **conserva todo lo demás**.
105
+
106
+ Qué te da ese camino, que por MCP no existe:
107
+
108
+ 1. **Valida el formato antes de escribir.** Frena si falta el `# Título`, la sección
109
+ `## Criterios de aceptación`, o si está vacía — las tres cosas sin las cuales no hay
110
+ `ac_hash` y el link QUÉ↔CÓMO se rompe. Y **avisa** si un criterio no es Gherkin
111
+ completo o se metió en el CÓMO. Si frena, **arreglá el `.md` y reintentá**: no busques
112
+ otra vía para publicar igual, el chequeo está para eso.
113
+ 2. **Muestra qué cambia** en el tracker (título, cuántos criterios, `ac_hash`) antes de
114
+ tocarlo.
115
+ 3. **Pregunta si sube el `spec_version`** — y esta pregunta **es de la persona, no tuya**:
116
+ - **material** (un criterio nuevo, una regla distinta) → sube `v1` → `v2`, y los repos
117
+ que implementaron `v1` se marcan **atrasados** solos.
118
+ - **editorial** (typo, redacción más clara) → se queda en `v1`, nadie se marca atrasado.
119
+
120
+ Con `--yes` el comando asume material y sube la versión. **No pongas `--yes` sin
121
+ preguntar**: marcar repos como atrasados de más entrena al equipo a ignorar los ⚠️.
122
+ Preguntale al PO cuál de las dos es, y recién entonces corré con `--bump` o `--no-bump`.
123
+ 4. **Re-estampa el `ac_hash`** del `implements.yaml` si el repo ya implementaba esa US,
124
+ para que `dai check` no la marque atrasada por la propia edición.
125
+
126
+ Usá **`--dry-run` primero** para mostrarle el preview a la persona, y corré en firme
127
+ recién cuando lo apruebe. Si el backend es `md` (sin tracker), el mismo comando actualiza
128
+ el `.md` canónico.
129
+
130
+ > Si preferís no traer nada del tracker porque ya tenés la US entera escrita,
131
+ > `dai update-us <ID> --us <md>` es el mismo camino sin el paso de bajarla.
132
+
85
133
  5. **Estado.** Dejar la US en `pulida`. Ofrecer que el dev siga con `dai link-us <ID>` → `opsx:propose` (lado técnico).
86
134
 
87
135
  ## Hand-off
@@ -0,0 +1,50 @@
1
+ # Gate de trazabilidad de dai — la regla de governance/ci-rules.md, ejecutable.
2
+ #
3
+ # Qué hace: en cada PR, verifica que una branch de producto declare qué US implementa
4
+ # (implements.yaml) y que ese link no haya quedado atrasado contra la US viva.
5
+ #
6
+ # Qué NO hace: exigirle US a todo. `chore/`, `docs/`, `ci/`, `build/`, `test/`,
7
+ # `refactor/`, `style/`, `release/`, `hotfix/` y `revert/` pasan sin link — son trabajo
8
+ # legítimo sin ticket (governance/branch-naming.md). Un gate que bloquea esas branches
9
+ # se termina desactivando, y entonces no protege nada.
10
+ #
11
+ # Cómo se instala: copialo a .github/workflows/ de tu repo. Si tu CI no es GitHub
12
+ # Actions, el contrato es el mismo en cualquier runner — es un solo comando:
13
+ #
14
+ # npx --yes @dforce2055/dai check --ci
15
+ #
16
+ # Códigos de salida: 0 = pasa · 1 = falta el link · 2 = el QUÉ cambió (US atrasada)
17
+
18
+ name: dai · trazabilidad
19
+
20
+ on:
21
+ pull_request:
22
+
23
+ jobs:
24
+ link:
25
+ name: link QUÉ↔CÓMO
26
+ runs-on: ubuntu-latest
27
+ steps:
28
+ - uses: actions/checkout@v4
29
+ - uses: actions/setup-node@v4
30
+ with:
31
+ node-version: 20
32
+
33
+ # `dai check --ci` detecta solo la branch de la PR (GITHUB_HEAD_REF): en una PR,
34
+ # HEAD es un merge commit detached y `git rev-parse --abbrev-ref HEAD` diría "HEAD".
35
+ #
36
+ # Sin secrets del tracker, el gate valida el LINK y no compara contra la US viva
37
+ # (--no-network). Con secrets, sacá el flag y además detecta las US atrasadas.
38
+ - name: Gate de trazabilidad
39
+ run: npx --yes @dforce2055/dai check --ci --no-network
40
+
41
+ # Variante con tracker — descomentala y cargá los secrets del repo para que el
42
+ # gate marque también las US ATRASADAS (salida 2). Comentá el paso de arriba.
43
+ #
44
+ # - name: Gate de trazabilidad (con tracker)
45
+ # env:
46
+ # DAI_PM: jira # o clickup
47
+ # DAI_JIRA_BASE_URL: ${{ vars.DAI_JIRA_BASE_URL }}
48
+ # DAI_JIRA_EMAIL: ${{ secrets.DAI_JIRA_EMAIL }}
49
+ # DAI_JIRA_TOKEN: ${{ secrets.DAI_JIRA_TOKEN }}
50
+ # run: npx --yes @dforce2055/dai check --ci