@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 +16 -0
- package/CHANGELOG.md +71 -0
- package/README.md +3 -2
- package/VERSION +1 -1
- package/cli/dai.mjs +545 -2
- package/cli/lib/branch-scope.mjs +24 -9
- package/cli/lib/help.mjs +76 -0
- package/cli/lib/notify.mjs +205 -0
- package/cli/lib/pm-adapter.mjs +16 -0
- package/cli/lib/pm-clickup.mjs +17 -0
- package/cli/lib/pm-jira.mjs +20 -0
- package/cli/lib/pr-remote.mjs +14 -0
- package/cli/lib/release-files.mjs +119 -0
- package/cli/lib/release-plan.mjs +221 -0
- package/cli/lib/release-stamp.mjs +87 -0
- package/docs/adr/0019-ciclo-de-version-y-aviso-de-release.md +190 -0
- package/docs/adr/README.md +1 -0
- package/docs/guias/index.md +3 -0
- package/docs/guias/releases.md +156 -0
- package/docs/tutoriales/ciclo-de-release.md +266 -0
- package/docs/tutoriales/index.md +6 -0
- package/package.json +1 -1
- package/skills/dai-release/SKILL.md +167 -0
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.
|
|
1
|
+
0.15.0
|