@dforce2055/dai 0.14.0 → 0.15.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/.env.dai.example CHANGED
@@ -27,6 +27,22 @@ DAI_PM=md
27
27
  # rama como producción: no adivina cuál es.
28
28
  # DAI_BRANCH_PROD=main
29
29
 
30
+ # ── Aviso de release a un canal de equipo (opcional) ─────────────────────────
31
+ # Tercer adaptador de dai, con la misma forma que DAI_PM: una variable elige el canal y el
32
+ # canal trae las suyas. Por default no hay aviso: dai no habla hacia afuera sin pedirlo.
33
+ # discord | slack | webex | telegram | webhook | none
34
+ # `webhook` es el genérico: manda los campos del release en JSON a cualquier endpoint
35
+ # (Teams, Mattermost, un sistema interno) e incluye además el texto ya armado.
36
+ # DAI_NOTIFY=webex
37
+
38
+ # El endpoint del canal. ⚠️ ES LA CREDENCIAL: quien lo tiene, puede postear. Nunca lo
39
+ # commitees; dai muestra el host, nunca la URL. Probalo con `dai release notify --test`.
40
+ # DAI_NOTIFY_WEBHOOK=
41
+
42
+ # Solo para telegram: no tiene webhooks de entrada, así que el endpoint es el bot y hace
43
+ # falta decir a qué chat va el mensaje.
44
+ # DAI_NOTIFY_CHAT_ID=
45
+
30
46
  # ── Backend md (local, offline) ──────────────────────────────────────────────
31
47
  # Carpeta donde viven las US como <ID>.md (p. ej. ABC-482.md).
32
48
  DAI_MD_US_DIR=.dai/us
package/CHANGELOG.md CHANGED
@@ -3,6 +3,76 @@
3
3
  Formato basado en [Keep a Changelog](https://keepachangelog.com/). Versionado semver
4
4
  (ver `VERSION`).
5
5
 
6
+ ## [0.15.0] — 2026-09-09
7
+
8
+ **Un equipo puede tener el link QUÉ↔CÓMO perfecto y seguir sin poder contestar la pregunta
9
+ que hace el negocio: "¿esto ya está en producción?". La trazabilidad llegaba hasta la PR y
10
+ se cortaba justo ahí. Esta versión agrega el último eslabón — la versión desplegada — y con
11
+ él, el ciclo completo para cortarla, cerrarla y contarla.**
12
+
13
+ ### Agregado
14
+ - **`dai release plan` — el manifiesto de la versión.** Qué User Stories entran entre el
15
+ último tag y la rama de integración, en qué estado está cada una, y qué entró **sin**
16
+ declarar US. Resuelve las US leyendo los `implements.yaml` **tal como estaban en cada
17
+ commit del rango**, no por el nombre de la rama: el link viaja con el código, así que la
18
+ respuesta sobrevive a que la branch se borre y a que el change se archive — el estado
19
+ normal del repo cuando llegás a cortar, días después del merge. Es el dato del que
20
+ dependen los otros cuatro comandos; `--json` es lo que consume la skill.
21
+ - **`dai release cut <X.Y.Z>` — preparar, sin hablar hacia afuera.** Rama de release, número
22
+ en los archivos que el repo espeja, entrada del CHANGELOG y commit. Ni push, ni tag, ni
23
+ PR: todo lo que pasa ANTES de la firma humana.
24
+ - **`dai release done <X.Y.Z>` — cerrar, después del merge.** Tag anotado, release note en
25
+ el forge, back-merge a integración, borrado de la rama de release y aviso al canal. Existe
26
+ como comando separado porque los dos pasos que más se olvidan cuando la ceremonia se hace
27
+ a mano viven en esta mitad, la que queda después de la firma. Se llama `done` y no
28
+ `finish` por lo mismo que `dai done` cierra el trabajo de una branch: mismo verbo, distinto
29
+ sustantivo.
30
+ - **`dai release stamp <X.Y.Z> --env <ambiente>` — que cada US sepa dónde está.** Deja en
31
+ cada historia del release un comentario con versión, app, ambiente y fecha, y con eso el
32
+ funcional lee el ticket en vez de preguntar. Una US federada en varios repos acumula sola
33
+ su matriz. Es **opcional** y decir que no sale con 0: cuando el comando corre, el tag ya
34
+ existe y la versión está hecha.
35
+ - **`dai release status`** — dónde estás en el ciclo: versión declarada vs último tag, qué
36
+ falta promover, si quedó un back-merge pendiente, qué ramas de release sobrevivieron.
37
+ **`dai release notify --test`** — probar el canal antes de depender de él, porque un
38
+ webhook no se puede validar sin postear y fingir que sí sería justo lo que dai no hace.
39
+ - **Aviso de release a un canal de equipo** (`DAI_NOTIFY`): discord, slack, webex, telegram
40
+ o un `webhook` genérico para Teams, Mattermost o un sistema interno. Apagado por default:
41
+ dai no habla hacia afuera sin que se lo pidan. El endpoint **es la credencial**, así que
42
+ vive en el `.env.dai` y dai muestra el host, nunca la URL — tampoco en los errores.
43
+ - **Skill `/dai-release`** — conduce el ciclo confirmando paso a paso. No recalcula el
44
+ manifiesto: lo pide y lo narra. Si su memoria y el CLI se contradicen, gana el CLI.
45
+ - **[Guía de releases](docs/guias/releases.md)** con el *porqué* y
46
+ **[tutorial del ciclo completo](docs/tutoriales/ciclo-de-release.md)**. Una estrategia de
47
+ branching que el equipo no entiende se abandona en dos sprints, así que la documentación
48
+ entra en la misma versión que los comandos, no después.
49
+
50
+ ### Corregido
51
+ - **`dai pr` no podía abrir la PR de una `feature/` en un repo sin User Stories.** Le pasa a
52
+ cualquier repo de tooling o librería interna que use dai para versionar sin gestionar sus
53
+ propias historias — a este, sin ir más lejos, donde el mensaje mandaba a renombrar la
54
+ branch a `chore/`. Lo que distingue un olvido de un repo que no trabaja así es si la
55
+ branch **nombra un ticket**. El gate de CI no se toca.
56
+ - **Un aviso que aparece siempre no avisa nada.** El manifiesto marcaba cada branch sin US
57
+ como "entró trabajo sin link", incluso en repos donde ninguna branch va a declarar una
58
+ jamás. Ahora el hallazgo se reporta solo si el repo trabaja con User Stories — salvo que
59
+ la branch nombre un ticket, que ahí sí es un olvido.
60
+ - **`dai pr` fallaba al actualizar una PR por un motivo que no era suyo.** `gh pr edit`
61
+ resuelve por GraphQL y arrastra campos deprecados del servidor, así que devolvía un error
62
+ sobre *Projects (classic)* cuando lo único que se quería era cambiar el body. Ahora
63
+ reintenta por REST con la misma autenticación; se intenta callado y solo se reporta si el
64
+ plan B también falla.
65
+
66
+ ### Interno
67
+ - **475 tests** (+68 desde la 0.14.0): el manifiesto y su resolución por commit, el corte y
68
+ el cierre, el gate de alcance del estampado y su idempotencia por (app, versión,
69
+ ambiente), y el adaptador de canal — incluidos tres tests que fallan si el endpoint se
70
+ filtra en algún mensaje.
71
+ - El adaptador de PM suma `comment(id, markdown)` y `listComments(id)` en los tres backends:
72
+ sin poder leer sus propios comentarios, dai no puede saber qué ya estampó.
73
+ - Esta versión se cortó con los comandos nuevos, y el dogfooding devolvió tres de las
74
+ correcciones de arriba.
75
+
6
76
  ## [0.14.0] — 2026-09-08
7
77
 
8
78
  **`dai pr` proponía mergear a `main` en un repo donde `main` despliega a producción, y el
@@ -918,6 +988,7 @@ ClickUp y Jira Cloud.
918
988
  - Tests de las rutas de red (jira/clickup/forge) con `fetch` mockeado. Sin links rotos;
919
989
  `files` de npm sin tests ni secretos.
920
990
 
991
+ [0.15.0]: https://github.com/dforce2055/dai/releases/tag/v0.15.0
921
992
  [0.14.0]: https://github.com/dforce2055/dai/releases/tag/v0.14.0
922
993
  [0.13.3]: https://github.com/dforce2055/dai/releases/tag/v0.13.3
923
994
  [0.13.2]: https://github.com/dforce2055/dai/releases/tag/v0.13.2
package/README.md CHANGED
@@ -209,6 +209,7 @@ flowchart TD
209
209
  | `dai forge review <ref> --from <review.json>` `[--dry-run\|--yes]` | **review inline**: un resumen + un comentario anclado a cada `archivo:línea`, clasificado low/medium/high. **Valida cada posición contra el diff** (descarta lo que el modelo inventó) antes de postear; sin `--yes` muestra el preview y no postea nada. Modo desatendido: `--min-severity`/`--min-confidence`/`--max-comments`. El review sale con `event: COMMENT`, nunca `APPROVE` ([ADR-0016](docs/adr/0016-review-inline.md)) |
210
210
  | `dai forge comment <ref> --body-file <f>` · `dai forge pr <ref>` | comentar / leer una PR/MR (GitHub/GitLab) — el fallback simple, sin anclar |
211
211
  | `dai ac-hash <us.md>` | calcula el hash de los criterios de aceptación de una US |
212
+ | `dai release plan` · `cut <X.Y.Z>` · `done <X.Y.Z>` · `stamp <X.Y.Z> --env <amb>` · `status` · `notify --test` | **el ciclo de versión** ([ADR-0019](docs/adr/0019-ciclo-de-version-y-aviso-de-release.md)). `plan` arma el **manifiesto**: qué US entran, cuáles quedaron **atrasadas** y qué se coló **sin US** — más el bump que **propone** (la versión la firma una persona: un cambio de default es minor aunque todo sea `fix:`). `cut` prepara (rama, número, entrada del CHANGELOG con el material para repartir, commit) y **no habla hacia afuera**; `done` cierra tras el merge (tag + release note + back-merge + aviso) — los dos pasos que más se olvidan. `stamp` le avisa a **cada US** en qué versión y ambiente salió: muestra el alcance real, es **idempotente** por (app, versión, ambiente) y **es opcional** (decir que no sale con 0). El tag es la versión; `VERSION`/`package.json` son espejos y puede no haber ninguno. Guía: [releases](docs/guias/releases.md) · Tutorial: [ciclo de release](docs/tutoriales/ciclo-de-release.md) |
212
213
  | `dai help [<comando>]` · `dai <comando> --help` | ayuda del CLI. Pedir ayuda **nunca ejecuta el comando**: sale por `stdout` y termina con 0. Valen `--help`, `-h` y `dai <comando> help` — las tres formas, en todos los comandos |
213
214
  | `dai doctor` · `dai docs <dest>` · `dai version` | diagnóstico del entorno (incluye **version-drift** del scaffold) · copiar la doc (sin los assets del sitio; los links a las capturas apuntan al sitio publicado) · versión (`dai version` avisa si tu repo quedó atrás) |
214
215
 
@@ -243,7 +244,7 @@ flowchart TD
243
244
  > en [`skills/`](skills/).
244
245
 
245
246
  Skills (se invocan en el asistente): `/doc-to-backlog` · `/grill-intent` · `/grill-epic` · `/grill-user-story` · `/link-us` ·
246
- `/tdd` · `/dai-review`. Config del tracker (`md`\|`jira`\|`clickup`) y tokens: en `.env.dai`
247
+ `/tdd` · `/dai-review` · `/dai-release`. Config del tracker (`md`\|`jira`\|`clickup`) y tokens: en `.env.dai`
247
248
  (no versionado; el `.env` del equipo no se toca — [ADR-0017](docs/adr/0017-env-dai.md)) —
248
249
  ver [`.env.dai.example`](.env.dai.example). Auth (SSH + tokens): [ADR-0007](docs/adr/0007-modelo-de-autenticacion.md).
249
250
 
@@ -279,7 +280,7 @@ mi-repo/
279
280
  ├── CLAUDE.md · Constitución del proyecto (auto-cargada por Claude)
280
281
  ├── .env.dai · tu tracker (NO versionado, completa el token) + .env.dai.example (plantilla, sí versionada)
281
282
  ├── .claude/skills/ · Las skills, locales al repo (el equipo las hereda)
282
- │ └── doc-to-backlog · grill-intent · grill-epic · grill-user-story · link-us · tdd · dai-review
283
+ │ └── doc-to-backlog · grill-intent · grill-epic · grill-user-story · link-us · tdd · dai-review · dai-release
283
284
  ├── .github/
284
285
  │ ├── copilot-instructions.md · La constitución, auto-inyectada en cada chat de Copilot
285
286
  │ ├── skills/ · Las mismas skills, en formato Copilot nativo (SKILL.md)
package/VERSION CHANGED
@@ -1 +1 @@
1
- 0.14.0
1
+ 0.15.0