@dforce2055/dai 0.8.2 → 0.10.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.example → .env.dai.example} +3 -3
- package/CHANGELOG.md +81 -0
- package/README.md +41 -29
- package/VERSION +1 -1
- package/cli/dai.mjs +175 -44
- package/cli/lib/bootstrap.mjs +42 -7
- package/cli/lib/env.mjs +12 -0
- package/cli/lib/forge-api.mjs +89 -2
- package/cli/lib/pm-clickup.mjs +2 -2
- package/cli/lib/pm-jira.mjs +2 -2
- package/cli/lib/review-findings.mjs +195 -0
- package/cli/lib/skills-source.mjs +8 -0
- package/docs/EJEMPLO-END-TO-END.md +52 -43
- package/docs/MANIFIESTO.md +2 -2
- package/docs/METODOLOGIA.md +20 -15
- package/docs/PROBAR.md +13 -14
- package/docs/SCRUM-CON-IA.md +10 -10
- package/docs/adr/0003-deteccion-y-estampado-son-comandos.md +1 -1
- package/docs/adr/0006-distribucion-y-licencia.md +1 -1
- package/docs/adr/0013-skills-externas-install-from.md +11 -4
- package/docs/adr/0015-jira-corporativo.md +1 -1
- package/docs/adr/0016-review-inline.md +128 -0
- package/docs/adr/0017-env-dai.md +64 -0
- package/docs/adr/README.md +2 -0
- package/docs/detalle/01-refinamiento.md +6 -5
- package/docs/detalle/03-ramas.md +2 -2
- package/docs/detalle/04-tdd.md +15 -9
- package/docs/detalle/06-code-review.md +8 -5
- package/docs/detalle/08-daily.md +1 -1
- package/docs/detalle/README.md +1 -1
- package/docs/glosario.md +2 -2
- package/docs/guias/dev.md +10 -7
- package/docs/guias/index.md +12 -0
- package/docs/guias/lead.md +1 -1
- package/docs/guias/po.md +13 -7
- package/docs/index.md +35 -0
- package/docs/public/favicon.svg +12 -0
- package/docs/public/logo-link.svg +12 -0
- package/docs/public/logo.svg +12 -0
- package/docs/public/tutoriales/clickup-1-settings.png +0 -0
- package/docs/public/tutoriales/clickup-2-api.png +0 -0
- package/docs/public/tutoriales/clickup-3-generate-copy.png +0 -0
- package/docs/public/tutoriales/jira-1-avatar.png +0 -0
- package/docs/public/tutoriales/jira-2-seguridad-tokens.png +0 -0
- package/docs/public/tutoriales/jira-3-crear-token.png +0 -0
- package/docs/public/tutoriales/jira-4-nombre-vencimiento.png +0 -0
- package/docs/public/tutoriales/jira-5-copiar.png +0 -0
- package/docs/tutoriales/claves-ssh.md +93 -0
- package/docs/tutoriales/configurar-git.md +53 -0
- package/docs/tutoriales/index.md +18 -0
- package/docs/tutoriales/instalar-glab.md +74 -0
- package/docs/tutoriales/token-clickup.md +73 -0
- package/docs/tutoriales/token-jira.md +74 -0
- package/package.json +9 -3
- package/skills/dai-review/SKILL.md +96 -42
|
@@ -18,11 +18,17 @@ dueño ni gatekeeper de ellas.
|
|
|
18
18
|
|
|
19
19
|
## Decisión
|
|
20
20
|
|
|
21
|
-
Agregamos **`dai skills install --from <git-url|path>[#ref]`**: instala skills
|
|
22
|
-
**externas** desde un repo/dir (con estructura `skills/<nombre>/SKILL.md`, la misma
|
|
21
|
+
Agregamos **`dai skills install --from <git-url|npm:pkg|path>[#ref]`**: instala skills
|
|
22
|
+
**externas** desde un repo/dir/paquete (con estructura `skills/<nombre>/SKILL.md`, la misma
|
|
23
23
|
de dai), **convertidas para los 3 asistentes** (Claude copia · Cursor `skillToCursor`
|
|
24
24
|
· Copilot `skillToPrompt` → `.github/prompts/`).
|
|
25
25
|
|
|
26
|
+
- **Tres fuentes:** un **git URL** (`github.com/org/skills[#ref]` → clone), un **path
|
|
27
|
+
local**, o un **paquete npm** (`npm:@scope/pkg[@version]` → `npm pack` a un temp,
|
|
28
|
+
respetando el `.npmrc` del cwd, así resuelve registries privados con scope). Es común
|
|
29
|
+
distribuir skills como paquete npm (una org publica sus componentes + skills juntas);
|
|
30
|
+
materializarlo a mano era fricción de más.
|
|
31
|
+
|
|
26
32
|
- **`dai skills` es el namespace canónico** de las operaciones de skills, consistente
|
|
27
33
|
con `dai forge <verb>`. `dai skills install` (sin `--from`) instala las de dai;
|
|
28
34
|
**`dai install` queda como alias** silencioso (backward-compatible).
|
|
@@ -42,8 +48,9 @@ de dai), **convertidas para los 3 asistentes** (Claude copia · Cursor `skillToC
|
|
|
42
48
|
- **Se acepta pagar:** es **one-off** (dai no mantiene esas skills al día; re-corrés
|
|
43
49
|
`--from`). **Sin registro** → dai no sabe qué repos tienen skills externas, a
|
|
44
50
|
propósito: cero gatekeeping, bajo riesgo del equipo. Las fuentes remotas dependen de
|
|
45
|
-
git/red, y la **auth se delega en
|
|
46
|
-
|
|
51
|
+
git/red/npm, y la **auth se delega en la herramienta** (git: SSH o credential helper;
|
|
52
|
+
npm: el `.npmrc` del repo — dai no autentica): *si puedes `git clone` o `npm pack` la
|
|
53
|
+
fuente, dai instala desde ahí*.
|
|
47
54
|
|
|
48
55
|
## Alternativas consideradas
|
|
49
56
|
|
|
@@ -89,7 +89,7 @@ error de config más común. El mensaje da los dos caminos: `DAI_JIRA_PROJECT=PR
|
|
|
89
89
|
- **`dai doctor`** valida la clave de proyecto y que el archivo de campos parsee. Sigue
|
|
90
90
|
**sin** verificar que el token sirva — eso es red, y lo dice `dai publish`. El chequeo
|
|
91
91
|
ahora lo admite en voz alta en vez de dar un ✓ engañoso.
|
|
92
|
-
- **ClickUp queda con el mismo hueco de TLS.** `daiFetch` está listo para adoptarse
|
|
92
|
+
- **ClickUp queda con el mismo hueco de TLS.** `daiFetch` está listo para adoptarse allí
|
|
93
93
|
con un import; no lo hicimos ahora por alcance.
|
|
94
94
|
|
|
95
95
|
## Alternativas descartadas
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# ADR-0016 — Review inline: el `review.json` como puerta humana, y el CLI como validador
|
|
2
|
+
|
|
3
|
+
- **Estado:** aceptado
|
|
4
|
+
- **Fecha:** 2026-07-17
|
|
5
|
+
- **Decide:** lead / arquitecto de la metodología
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
`dai-review` dejaba **un comentario al final del hilo** de la PR con todos los hallazgos
|
|
10
|
+
en una lista. El reviewer humano tenía que leer "`src/checkout.ts:42` — el guard falla
|
|
11
|
+
abierto", abrir el archivo, buscar la línea, y reconstruir el contexto a mano. Por cada
|
|
12
|
+
hallazgo.
|
|
13
|
+
|
|
14
|
+
El review de Copilot, con todos sus defectos, hace algo mejor: deja **un comentario
|
|
15
|
+
anclado a cada `archivo:línea`**, clasificado `Low`/`Medium`/`High`, más un resumen
|
|
16
|
+
arriba. El hallazgo aparece **al lado del código del que habla**.
|
|
17
|
+
|
|
18
|
+
Técnicamente el gap era chico y estaba en un solo lugar: `dai forge comment` postea al
|
|
19
|
+
endpoint de **issues** (el hilo). El review inline es otro endpoint. No hacía falta una
|
|
20
|
+
arquitectura nueva.
|
|
21
|
+
|
|
22
|
+
Pero al abrirlo aparecieron tres problemas que sí son de diseño:
|
|
23
|
+
|
|
24
|
+
1. **El modelo inventa líneas.** Un LLM revisando código produce `path:line` que no
|
|
25
|
+
existen en el diff con una facilidad pasmosa. El forge responde `422` sin decir cuál
|
|
26
|
+
de los seis comentarios falló, y en GitHub el review es atómico: **un hallazgo
|
|
27
|
+
inventado tira los cinco buenos**.
|
|
28
|
+
2. **La skill posteaba sin gate** (ver 0.8.2). Con un comentario suelto ya era grave.
|
|
29
|
+
Con seis comentarios inline **firmados con el token del humano** —el forge los
|
|
30
|
+
atribuye a él como usuario, sin badge de bot— pesa mucho más.
|
|
31
|
+
3. **"Desatendido" no puede significar "sin criterio".** Hacía falta una forma de que un
|
|
32
|
+
review simple salga solo sin que eso implique postear cualquier cosa.
|
|
33
|
+
|
|
34
|
+
## Decisión
|
|
35
|
+
|
|
36
|
+
### 1. El contrato es un archivo, y ese archivo es la puerta humana
|
|
37
|
+
|
|
38
|
+
La skill deja de componer markdown y escribe un **`review.json`** en `.dai/reviews/<n>.json`.
|
|
39
|
+
El CLI lo valida y lo postea.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
skill (criterio) → .dai/reviews/22.json → dai forge review (mecánico)
|
|
43
|
+
hallazgos + severidad el humano lo edita valida vs. diff, filtra, postea
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Es la [ADR-0002](0002-agnostico-del-asistente.md) aplicada al review: el criterio es de
|
|
47
|
+
la skill, lo determinista es del CLI.
|
|
48
|
+
|
|
49
|
+
**Por qué un archivo y no una TUI.** Evaluamos [hunk](https://github.com/modem-dev/hunk),
|
|
50
|
+
que resuelve esto con una sesión interactiva en la terminal donde el humano navega los
|
|
51
|
+
hunks y el agente le anota comentarios. Lo bueno de robar es el **contrato**: el agente
|
|
52
|
+
emite un lote estructurado y la publicación es un paso aparte. Lo que no robamos es la
|
|
53
|
+
TUI: construirla es un proyecto entero y **ata el flujo a que el humano esté en tu
|
|
54
|
+
terminal** — justo lo contrario de la 0002. Un JSON es diff-eable, editable a mano,
|
|
55
|
+
auditable, y anda igual en Claude, Copilot o Cursor.
|
|
56
|
+
|
|
57
|
+
### 2. El CLI valida contra el diff antes de salir a la red
|
|
58
|
+
|
|
59
|
+
`dai forge review` trae el diff con **git** (local, por SSH — no gasta rate limit ni
|
|
60
|
+
depende de la API) y verifica que cada `path:line` **exista de verdad en el hunk**, del
|
|
61
|
+
lado declarado. Lo que no apunta al diff **no se postea**.
|
|
62
|
+
|
|
63
|
+
Esto es lo que más valor tiene del comando, más que postear. Es la diferencia entre un
|
|
64
|
+
review que entra y un `422` críptico que se lleva puestos los hallazgos buenos.
|
|
65
|
+
|
|
66
|
+
### 3. Nada se cae en silencio
|
|
67
|
+
|
|
68
|
+
Un hallazgo descartado o filtrado **se reporta**: en el preview del CLI y en un
|
|
69
|
+
`<details>` del propio resumen posteado. Un tope (`--max-comments`) que corta en silencio
|
|
70
|
+
se lee como "revisé todo" cuando no. Si dai suprime algo, lo dice.
|
|
71
|
+
|
|
72
|
+
### 4. `--yes` explícito; el desatendido es una excepción que se pide
|
|
73
|
+
|
|
74
|
+
Sin `--yes` no se postea nada, nunca: se muestra el preview y se corta. El modo
|
|
75
|
+
desatendido existe —`--yes --min-severity medium --min-confidence 0.8 --max-comments N`—
|
|
76
|
+
pero es una **excepción que el humano tipea**, no un default al que se llega por descuido.
|
|
77
|
+
|
|
78
|
+
`confidence` es lo que lo hace usable: por debajo del umbral el hallazgo no se postea y
|
|
79
|
+
queda listado. Es el equivalente honesto del *"Comments suppressed due to low confidence"*
|
|
80
|
+
de Copilot.
|
|
81
|
+
|
|
82
|
+
### 5. `event: COMMENT`, nunca `APPROVE`
|
|
83
|
+
|
|
84
|
+
Ni siquiera en desatendido, ni por configuración. dai comenta; la aprobación la firma un
|
|
85
|
+
humano ([Art. 5](../MANIFIESTO.md#art-5)).
|
|
86
|
+
|
|
87
|
+
### 6. Cada comentario inline lleva marca de dai
|
|
88
|
+
|
|
89
|
+
El review sale con el token del humano, así que el forge lo atribuye a él **sin badge de
|
|
90
|
+
bot** — a diferencia de Copilot, que postea vía GitHub App y muestra el badge `AI`. Sin
|
|
91
|
+
una marca en el cuerpo, el compañero ve seis juicios sobre su código firmados por una
|
|
92
|
+
persona, sin forma de saber que los escribió una máquina. Cada comentario cierra con una
|
|
93
|
+
línea que lo dice.
|
|
94
|
+
|
|
95
|
+
## Consecuencias
|
|
96
|
+
|
|
97
|
+
**A favor**
|
|
98
|
+
|
|
99
|
+
- El hallazgo aparece al lado del código. El reviewer humano deja de reconstruir contexto.
|
|
100
|
+
- El validador de posiciones convierte el error más común del LLM en un descarte legible,
|
|
101
|
+
antes de la red.
|
|
102
|
+
- El `review.json` es auditable y editable: el humano puede bajar una severidad o borrar
|
|
103
|
+
un hallazgo sin pelearse con un prompt.
|
|
104
|
+
- Sirve igual en GitHub y GitLab, y con cualquier asistente.
|
|
105
|
+
|
|
106
|
+
**En contra / a asumir**
|
|
107
|
+
|
|
108
|
+
- **GitLab no es atómico, y no lo podemos fingir.** GitHub postea resumen + N inline en
|
|
109
|
+
un solo `POST` (o entra todo o no entra nada). GitLab necesita 1 nota para el resumen y
|
|
110
|
+
N `discussions` separadas: si la tercera falla, las dos primeras **ya están
|
|
111
|
+
publicadas**. Se mitiga validando todo antes de la primera llamada, pero cuando falla
|
|
112
|
+
igual, el CLI **reporta qué entró y qué no** en vez de prometer una atomicidad que no
|
|
113
|
+
tiene.
|
|
114
|
+
- GitLab exige los tres shas de `diff_refs` en cada comentario: `getPR` tuvo que dejar de
|
|
115
|
+
descartarlos.
|
|
116
|
+
- Un `review.json` a medio editar no debe commitearse: `dai init` agrega `.dai/reviews/`
|
|
117
|
+
al `.gitignore` del repo (`.dai/` sigue versionándose — ahí vive `jira-fields.json`).
|
|
118
|
+
|
|
119
|
+
**Fuera de alcance, a propósito**
|
|
120
|
+
|
|
121
|
+
- **Bloques `suggestion`** (el botón "Apply suggestion"). Son valiosos pero la sintaxis
|
|
122
|
+
difiere entre GitHub y GitLab; el schema queda abierto para sumarlos después.
|
|
123
|
+
- **Cuenta bot / GitHub App** para que los reviews salgan marcados como IA como los de
|
|
124
|
+
Copilot. Una cuenta bot es solo **otro token en el `.env`** (cero código); una GitHub
|
|
125
|
+
App sí es trabajo real (JWT + installation token). Es una decisión de operación del
|
|
126
|
+
equipo, no del CLI, y por eso no la cierra esta ADR.
|
|
127
|
+
- **La calidad del review en sí.** dai no compite en catálogos de bugs ni reglas: eso no
|
|
128
|
+
es su dominio. Lo suyo es la trazabilidad y que el hallazgo aterrice donde sirve.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# ADR-0017 — La config de dai vive en `.env.dai`, no en el `.env` del equipo
|
|
2
|
+
|
|
3
|
+
- **Estado:** aceptado
|
|
4
|
+
- **Fecha:** 2026-07-18
|
|
5
|
+
- **Decide:** lead / arquitecto de la metodología
|
|
6
|
+
|
|
7
|
+
## Contexto
|
|
8
|
+
|
|
9
|
+
dai guarda su config y sus secretos (token del tracker, email, plantilla de URL) en
|
|
10
|
+
variables de entorno, y hasta ahora las escribía en el `.env` del repo, con la premisa de
|
|
11
|
+
que ese `.env` está **gitignored** (por eso `dai init` lo agregaba al `.gitignore` y el
|
|
12
|
+
loader avisaba "NUNCA commitees tokens").
|
|
13
|
+
|
|
14
|
+
Esa premisa se rompe en muchas empresas: **versionan el `.env`** como política (mismas
|
|
15
|
+
variables públicas para todo el equipo y el CI). Pasó de verdad en un repo de frontend
|
|
16
|
+
corporativo: el `.env` estaba trackeado con `VITE_*` públicas, y `dai init`
|
|
17
|
+
|
|
18
|
+
1. le **inyectaba** sus claves `DAI_*` a un archivo compartido del equipo, y
|
|
19
|
+
2. le agregaba `.env` al `.gitignore` — inútil, porque git no ignora un archivo ya
|
|
20
|
+
trackeado, y encima confuso (parece que lo protege y no lo hace).
|
|
21
|
+
|
|
22
|
+
El día que un dev completara `DAI_JIRA_TOKEN` en ese `.env` versionado, git lo marcaba
|
|
23
|
+
para commit: **un secreto a un empujón de filtrarse** al historial del repo corporativo.
|
|
24
|
+
|
|
25
|
+
## Decisión
|
|
26
|
+
|
|
27
|
+
dai deja de tocar el `.env` del equipo. Toda su config vive en archivos **propios**:
|
|
28
|
+
|
|
29
|
+
| Archivo | Versionado | Quién lo maneja | Contenido |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| `.env` | según el equipo | el equipo | dai **no lo escribe**; solo lo **lee** (compat) |
|
|
32
|
+
| `.env.dai` | **no** (gitignored) | cada dev | config + secretos de dai (token, email) |
|
|
33
|
+
| `.env.dai.example` | sí | dai / el equipo | plantilla: mismas claves, valores vacíos |
|
|
34
|
+
|
|
35
|
+
- **`dai init`** crea `.env.dai` (real, ignorado) y `.env.dai.example` (plantilla
|
|
36
|
+
versionada), de forma aditiva, y **nunca** modifica `.env`/`.env.example`.
|
|
37
|
+
- **`reconcileGitignore`** ignora `.env.dai` (su archivo), **no** `.env`: el `.env` del
|
|
38
|
+
equipo es del equipo, y muchas orgs lo versionan a propósito. `.env.dai.example` no
|
|
39
|
+
matchea el patrón exacto `.env.dai`, así que se versiona sin negación extra.
|
|
40
|
+
- **El loader** (`loadDaiEnv`) lee `.env.dai` **y** `.env`. Precedencia:
|
|
41
|
+
**entorno (shell/CI) > `.env.dai` > `.env`**. Se logra cargando `.env.dai` primero,
|
|
42
|
+
porque el loader es "primero-gana". Seguir leyendo `.env` mantiene compatibilidad con
|
|
43
|
+
repos previos que tienen los `DAI_*` ahí — no se rompe nada.
|
|
44
|
+
|
|
45
|
+
## Consecuencias
|
|
46
|
+
|
|
47
|
+
- **A favor:** dai no ensucia ni pone en riesgo un archivo compartido del equipo. El
|
|
48
|
+
secreto vive en un archivo que git ignora de verdad (no trackeado). Funciona igual en
|
|
49
|
+
equipos que versionan el `.env` y en los que no. Los repos viejos siguen andando (se
|
|
50
|
+
lee `.env`).
|
|
51
|
+
- **En contra:** una convención más de archivos (`.env.dai`, `.env.dai.example`) que
|
|
52
|
+
documentar. Un repo que ya tenía `DAI_*` en un `.env` gitignored puede migrarlos a
|
|
53
|
+
`.env.dai` cuando quiera; no es urgente, porque el loader sigue leyendo `.env`.
|
|
54
|
+
- **Vite:** el nombre `.env.dai` solo lo cargaría Vite con `vite --mode dai` (raro), y
|
|
55
|
+
las claves de dai no llevan prefijo `VITE_`, así que nunca van al bundle del cliente.
|
|
56
|
+
|
|
57
|
+
## Alternativas descartadas
|
|
58
|
+
|
|
59
|
+
- **Destrackear el `.env`** (`git rm --cached`): rompe la convención del equipo y les saca
|
|
60
|
+
del control de versiones las `VITE_*` públicas que comparten a propósito.
|
|
61
|
+
- **Secreto solo por variable de shell:** anda hoy (el loader no pisa el entorno), pero
|
|
62
|
+
obliga a `source` en cada sesión: fricción para todo el equipo, sin plantilla que guíe.
|
|
63
|
+
- **Seguir usando `.env` y forzar el `.gitignore`:** es justo lo que fallaba — inerte
|
|
64
|
+
sobre un archivo ya trackeado, y peligroso el día que alguien escribe el token.
|
package/docs/adr/README.md
CHANGED
|
@@ -21,6 +21,8 @@ decisión cambia, se escribe un ADR nuevo que supersede al viejo. Molde en
|
|
|
21
21
|
| [0013](0013-skills-externas-install-from.md) | `dai skills install --from`: skills externas por-stack, sin registro ni gatekeeping | aceptado |
|
|
22
22
|
| [0014](0014-copilot-agent-skills.md) | Copilot lee `SKILL.md` nativo (Agent Skills): se elimina el adaptador `.prompt.md` — modifica la 0002 | aceptado |
|
|
23
23
|
| [0015](0015-jira-corporativo.md) | `dai publish` en Jira corporativo: campos propios declarados, `--parent`/`--issuetype`, TLS con CA (nunca apagar la verificación) | aceptado |
|
|
24
|
+
| [0016](0016-review-inline.md) | Review inline: `review.json` como contrato y puerta humana, el CLI valida las posiciones contra el diff, `--yes` explícito, nunca `APPROVE` | aceptado |
|
|
25
|
+
| [0017](0017-env-dai.md) | La config de dai vive en `.env.dai` (no versionado), no en el `.env` del equipo; el loader lee ambos con precedencia shell > `.env.dai` > `.env` | aceptado |
|
|
24
26
|
|
|
25
27
|
> Estas son las decisiones que cierran las "Decisiones abiertas" de
|
|
26
28
|
> [`METODOLOGIA.md §7`](../METODOLOGIA.md) y las enmiendas al
|
|
@@ -7,17 +7,18 @@
|
|
|
7
7
|
El PO llega con una idea (a veces un ticket de una línea). Antes de escribir specs,
|
|
8
8
|
la IA hace dos cosas, en orden:
|
|
9
9
|
|
|
10
|
-
1. **
|
|
11
|
-
`a-spec` (seguir), `reframe` (el problema real es otro) o `descartar` (no vale la
|
|
12
|
-
pena ahora). Un "no lo construyas" es un éxito del gate, no una falla.
|
|
13
|
-
2. **Pulido** (`grill-user-story`) — interroga hasta que la US es **testeable por
|
|
10
|
+
1. **Pulido** (`grill-user-story`) — interroga hasta que la US es **testeable por
|
|
14
11
|
construcción** (INVEST + Gherkin) y la publica en el tracker.
|
|
12
|
+
2. **Gate 0** (`grill-intent`) — con la US ya formada, desafía el *problema* detrás
|
|
13
|
+
(no la solución). Veredicto: `a-spec` (seguir), `reframe` (el problema real es otro)
|
|
14
|
+
o `descartar` (no vale la pena ahora). Un "no lo construyas" es un éxito del gate,
|
|
15
|
+
no una falla.
|
|
15
16
|
|
|
16
17
|
## Herramientas
|
|
17
18
|
|
|
18
|
-
- `/grill-intent` → `openspec/intents/<fecha-slug>/intent.md`
|
|
19
19
|
- `/grill-user-story` → US en formato [`formato-us.md`](../../templates/formato-us.md),
|
|
20
20
|
publicada en Jira/ClickUp (o `.md` de fallback).
|
|
21
|
+
- `/grill-intent` → `openspec/intents/<fecha-slug>/intent.md`
|
|
21
22
|
- Gate de entrada: [`definition-of-ready.md`](../../templates/definition-of-ready.md).
|
|
22
23
|
|
|
23
24
|
## Qué firma el humano
|
package/docs/detalle/03-ramas.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## En qué consiste en detalle
|
|
6
6
|
|
|
7
|
-
El dev
|
|
7
|
+
El dev empieza la implementación **atándola al QUÉ**: la branch y el `implements.yaml`
|
|
8
8
|
salen del mismo ID del tracker, así el link no puede quedar mal tipeado.
|
|
9
9
|
|
|
10
10
|
## Herramientas
|
|
@@ -21,7 +21,7 @@ dai link-us ABC-482 --us us.md
|
|
|
21
21
|
|
|
22
22
|
## Qué firma el humano
|
|
23
23
|
|
|
24
|
-
El dev **elige qué US
|
|
24
|
+
El dev **elige qué US toma**. El resto es mecánico y determinista (el CLI), no
|
|
25
25
|
criterio humano — por eso el key **no se tipea a mano** ([Art. 8](../MANIFIESTO.md#art-8), Art. 9).
|
|
26
26
|
|
|
27
27
|
## Antipatrones
|
package/docs/detalle/04-tdd.md
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
# Paso 4 —
|
|
1
|
+
# Paso 4 — Implementación: el agente construye con TDD (`/opsx:apply`)
|
|
2
2
|
|
|
3
3
|
← vuelve a [`SCRUM-CON-IA.md`](../SCRUM-CON-IA.md)
|
|
4
4
|
|
|
5
5
|
## En qué consiste en detalle
|
|
6
6
|
|
|
7
|
-
El CÓMO
|
|
7
|
+
El CÓMO **lo implementa el agente** con `/opsx:apply`: aplica las tareas que salieron de
|
|
8
|
+
`opsx:propose`, escribiendo **test primero**, un comportamiento a la vez:
|
|
8
9
|
|
|
9
10
|
```
|
|
10
|
-
RED →
|
|
11
|
+
RED → el agente escribe UN test que falla (un criterio de aceptación)
|
|
11
12
|
GREEN → el código mínimo para que pase
|
|
12
|
-
REFACTOR →
|
|
13
|
+
REFACTOR → limpia, con los tests en verde
|
|
13
14
|
```
|
|
14
15
|
|
|
15
16
|
*Vertical slices* (un test → una implementación → repetir), **no** horizontal
|
|
16
|
-
(todos los tests, después todo el código).
|
|
17
|
+
(todos los tests, después todo el código). Se verifica por la **interfaz pública**.
|
|
17
18
|
|
|
18
19
|
## Herramientas
|
|
19
20
|
|
|
20
|
-
-
|
|
21
|
-
|
|
21
|
+
- **`/opsx:apply`** — el paso donde el agente implementa las tareas del change.
|
|
22
|
+
- Skill [`tdd`](../../skills/tdd/SKILL.md) — la disciplina que `/opsx:apply` sigue: el
|
|
23
|
+
loop red-green-refactor y qué es un buen test.
|
|
22
24
|
|
|
23
25
|
## Qué firma el humano
|
|
24
26
|
|
|
25
|
-
El
|
|
26
|
-
|
|
27
|
+
El agente escribe el test y el código; el **dev decide qué comportamientos importa
|
|
28
|
+
testear** (no se testea todo), valida cada slice, y **es responsable del resultado — no
|
|
29
|
+
la IA** ([Art. 7](../MANIFIESTO.md#art-7)). Ese es el antídoto del vibe coding: la
|
|
30
|
+
revisión minuciosa de lo que produjo el agente (paso 6, code review propio).
|
|
27
31
|
|
|
28
32
|
## Antipatrones
|
|
29
33
|
|
|
34
|
+
- **Aceptar lo que sale sin revisarlo** → vibe coding con otra cara. El agente propone;
|
|
35
|
+
el dev responde por el código.
|
|
30
36
|
- **Horizontal slicing** (todos los tests juntos) → tests de la *forma imaginada*, no
|
|
31
37
|
del comportamiento real.
|
|
32
38
|
- **Testear lo interno** (mocks de colaboradores, métodos privados) → el test se rompe
|
|
@@ -8,16 +8,19 @@ Dos revisiones distintas:
|
|
|
8
8
|
|
|
9
9
|
1. **El dev revisa su propia implementación** — la que produjo la IA, minucioso y con
|
|
10
10
|
criterio (correctitud, casos borde, seguridad, calidad). Es responsable del código, no
|
|
11
|
-
la IA (anti vibe-coding).
|
|
11
|
+
la IA (anti vibe-coding). Solo con eso en orden, y todo **commiteado**, crea la PR.
|
|
12
12
|
2. **Un partner revisa la PR** y **firma** aprobación/rechazo. Se apoya en la skill
|
|
13
13
|
`dai-review` para un primer pase consciente de la metodología: corre `dai check` (¿la US
|
|
14
|
-
quedó atrasada?), valida el DoD, revisa el código (
|
|
15
|
-
|
|
14
|
+
quedó atrasada?), valida el DoD, revisa el código (severidad low/medium/high) y deja un
|
|
15
|
+
**review inline** — un resumen + **un comentario anclado a cada `archivo:línea`**. La
|
|
16
|
+
skill valida cada posición contra el diff (descarta lo que el modelo inventó), te muestra
|
|
17
|
+
el preview y **espera tu OK antes de postear** ([ADR-0016](../adr/0016-review-inline.md)).
|
|
16
18
|
|
|
17
19
|
## Herramientas
|
|
18
20
|
|
|
19
|
-
- Skill [`dai-review`](../../skills/dai-review/SKILL.md) — GitHub y GitLab
|
|
20
|
-
MCP del forge o por `dai forge
|
|
21
|
+
- Skill [`dai-review`](../../skills/dai-review/SKILL.md) — GitHub y GitLab. Postea el review
|
|
22
|
+
inline por el MCP del forge o por `dai forge review <ref> --from <review.json>` (token);
|
|
23
|
+
`dai forge comment` queda como fallback simple sin anclar.
|
|
21
24
|
- `dai check` ([ADR-0003](../adr/0003-deteccion-y-estampado-son-comandos.md)).
|
|
22
25
|
- Gate de cierre: [`definition-of-done.md`](../../templates/definition-of-done.md).
|
|
23
26
|
|
package/docs/detalle/08-daily.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
15 minutos: qué hice, qué voy a hacer, qué me traba. Es **sincronización**, no
|
|
8
8
|
reporte de estado. Se hace **a mano, sin IA, a propósito**.
|
|
9
9
|
|
|
10
|
-
## Por qué no metemos IA
|
|
10
|
+
## Por qué no metemos IA aquí
|
|
11
11
|
|
|
12
12
|
La IA *podría* auto-generar el "qué se hizo" desde git + el tracker. **No lo hacemos**:
|
|
13
13
|
el daily es donde el equipo se **apropia** del proceso, lo entiende y se coordina de
|
package/docs/detalle/README.md
CHANGED
|
@@ -9,7 +9,7 @@ los antipatrones a evitar.
|
|
|
9
9
|
| [01](01-refinamiento.md) | Refinamiento (idea → US testeable) | ●●● |
|
|
10
10
|
| [02](02-planning.md) | Planning (derivar el CÓMO) | ●● |
|
|
11
11
|
| [03](03-ramas.md) | Rama ligada al QUÉ | ●●● |
|
|
12
|
-
| [04](04-tdd.md) |
|
|
12
|
+
| [04](04-tdd.md) | Implementación (`/opsx:apply`, con TDD) | ●●● |
|
|
13
13
|
| [05](05-smoke.md) | Smoke end-to-end | ●● |
|
|
14
14
|
| [06](06-code-review.md) | Code review (IA + partner) | ●● |
|
|
15
15
|
| [07](07-merge-trazabilidad.md) | Merge + trazabilidad | ●●● |
|
package/docs/glosario.md
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
| **`implements.yaml`** | El archivo, en el change del repo, que contiene ese link. Lo genera `link-us`. Ejemplo lleno + árbol de dónde vive entre los artefactos de OpenSpec: [ADR-0004](adr/0004-ubicacion-y-schema-implements.md). |
|
|
25
25
|
| **Trazabilidad inversa / cobertura** | El mapa "quién implementó este QUÉ". **Se genera, nunca se escribe.** |
|
|
26
26
|
| **Índice / router** | La tabla central que dice qué ID vive en qué repos. Es un router, **no un almacén**: no guarda el detalle. |
|
|
27
|
-
| **Federación (dos niveles)** | Cómo se guarda la trazabilidad a escala: Nivel 1 = índice central chico; Nivel 2 = detalle en cada repo, resuelto on-demand. *(Es un eje distinto de los niveles de ceremonia N1/N2/N3:
|
|
27
|
+
| **Federación (dos niveles)** | Cómo se guarda la trazabilidad a escala: Nivel 1 = índice central chico; Nivel 2 = detalle en cada repo, resuelto on-demand. *(Es un eje distinto de los niveles de ceremonia N1/N2/N3: aquí "nivel" es dónde vive el dato, no el tamaño del equipo.)* |
|
|
28
28
|
| **Matriz de trazabilidad** | La vista "repo × versión × estado (al día / atrasado)". Derivada, no mantenida a mano. |
|
|
29
29
|
|
|
30
30
|
## El versionado
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
| **PR / MR (Pull / Merge Request)** | La unidad revisable del CÓMO. En dai lleva **dos activos**, y el review cubre ambos: (1) la **implementación** (el código) y (2) el **spec trazable** (el `implements.yaml` con el link a la US y el `@version` verificado). Sin el segundo, el CI bloquea el PR. Template en `../templates/pull-request.md`. |
|
|
47
47
|
| **Change** | La unidad de trabajo de OpenSpec (proposal + design + tasks + specs). |
|
|
48
48
|
| **ADR (Architecture Decision Record)** | El registro de una decisión estructural: contexto, decisión, consecuencias. Chico e **inmutable** — si algo cambia, se escribe uno nuevo que supersede al viejo. Template en `../templates/adr.md`; los de dai, en [`adr/`](adr/). |
|
|
49
|
-
| **TDD (Test-Driven Development)** | Escribir el test **antes** que el código: RED (test que falla) → GREEN (código mínimo) → REFACTOR. En dai
|
|
49
|
+
| **TDD (Test-Driven Development)** | Escribir el test **antes** que el código: RED (test que falla) → GREEN (código mínimo) → REFACTOR. En dai lo aplica el **agente** dentro de `/opsx:apply` (disciplina de la skill `tdd`): cada AC se vuelve un test. El dev valida y es responsable. Es el antídoto del vibe coding. |
|
|
50
50
|
| **Vertical slice** | Un test → una implementación → repetir. Lo opuesto a "todos los tests, después todo el código". |
|
|
51
51
|
| **Smoke** | Escenario end-to-end que verifica que el flujo grueso no se rompió. |
|
|
52
52
|
|
package/docs/guias/dev.md
CHANGED
|
@@ -18,12 +18,14 @@
|
|
|
18
18
|
|
|
19
19
|
## Tu día a día
|
|
20
20
|
|
|
21
|
-
1. **
|
|
21
|
+
1. **Tomas una US** que cumple el [DoR](../../templates/definition-of-ready.md) → `/link-us ABC-###`. Crea la rama y el
|
|
22
22
|
`implements.yaml` **desde el ID, sin que tipees el key a mano** (Art. 8, Art. 9).
|
|
23
23
|
2. **Armas el CÓMO** → `opsx:explore` → `opsx:propose`. OpenSpec genera
|
|
24
24
|
`design.md`/`tasks.md`; tú validas y ajustas. Las tareas nacen del cómo.
|
|
25
|
-
3. **
|
|
26
|
-
|
|
25
|
+
3. **El agente implementa el CÓMO** → `/opsx:apply`. Aplica las tareas escribiendo
|
|
26
|
+
test-primero (TDD, vertical slices: RED → GREEN → refactor), por la **interfaz
|
|
27
|
+
pública** (Art. 7). Tú decides qué comportamientos importa testear; el agente los
|
|
28
|
+
construye.
|
|
27
29
|
4. **Smoke** → ejecutas el escenario end-to-end del flujo.
|
|
28
30
|
5. **Revisas la implementación de la IA** (code review propio) → minucioso y con criterio:
|
|
29
31
|
correctitud, casos borde, seguridad, calidad. **Eres responsable del código, no la IA**
|
|
@@ -33,7 +35,8 @@
|
|
|
33
35
|
arma la PR **precargada** (US + estado del check + links; los **dos activos**: código +
|
|
34
36
|
spec trazable) y la asignas a un partner.
|
|
35
37
|
7. **Review de un partner** → un compañero revisa tu PR y **firma** aprobación/rechazo
|
|
36
|
-
(Art. 5). Se apoya en la skill `/dai-review` para un primer pase
|
|
38
|
+
(Art. 5). Se apoya en la skill `/dai-review` para un primer pase: un **review inline**
|
|
39
|
+
(resumen + un comentario por línea), que le muestra el preview y espera su OK antes de postear.
|
|
37
40
|
*(Tu PR la revisas tú en el paso 5; la de un compañero, lo ayudas con la skill.)*
|
|
38
41
|
8. **Verificas el DoD** → [`definition-of-done.md`](../../templates/definition-of-done.md) antes de mergear.
|
|
39
42
|
9. **Merge → se estampa la cobertura** con `dai stamp` (lo corres tú tras mergear, o el CI
|
|
@@ -45,7 +48,7 @@
|
|
|
45
48
|
## La trampa a evitar
|
|
46
49
|
|
|
47
50
|
**Vibe coding.** Nada de codear sobre una idea vaga o "improvisar y después vemos".
|
|
48
|
-
Si no hay US con criterios testeables, no
|
|
51
|
+
Si no hay US con criterios testeables, no empieces: falta el [DoR](../../templates/definition-of-ready.md). La disciplina
|
|
49
52
|
—US clara → design → test → código— es lo que separa esto de pedirle cosas a un chat.
|
|
50
53
|
|
|
51
54
|
## Cuando el QUÉ cambia
|
|
@@ -59,8 +62,8 @@ te avisa: el link versionado lo hace [Art. 11](../MANIFIESTO.md#art-11).
|
|
|
59
62
|
- `/link-us`
|
|
60
63
|
- `/opsx:explore`
|
|
61
64
|
- `/opsx:propose`
|
|
62
|
-
- `/opsx:apply`
|
|
63
|
-
- `/tdd`
|
|
65
|
+
- `/opsx:apply` — el agente implementa las tareas (con TDD)
|
|
66
|
+
- `/tdd` — la disciplina TDD que aplica el paso anterior
|
|
64
67
|
- `/dai-review`
|
|
65
68
|
- `dai check` · `dai pr` · `dai stamp` · `dai done` (limpieza, opcional)
|
|
66
69
|
- `definition-of-done.md`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Guías por rol
|
|
2
|
+
|
|
3
|
+
Un camino corto según quién eres. Cada guía te dice de qué eres **dueño**, qué **no tocas**,
|
|
4
|
+
y tu **día a día**.
|
|
5
|
+
|
|
6
|
+
- [**Guía del PO / funcional**](./po) — dueño del **QUÉ**: defines las User Stories y el
|
|
7
|
+
porqué, nunca el CÓMO. Entrás por `grill-user-story`, `grill-epic` o `doc-to-backlog`.
|
|
8
|
+
- [**Guía del dev / ingeniero**](./dev) — dueño del **CÓMO** y del **link**: el agente
|
|
9
|
+
implementa con `/opsx:apply`, tú revisas y autoras el `implements.yaml`.
|
|
10
|
+
- [**Guía del lead / SM / arquitecto**](./lead) — custodio de las **invariantes** y del
|
|
11
|
+
**nivel de ceremonia** (N1 / N2 / N3): haces que el método se cumpla y se aligere donde
|
|
12
|
+
corresponde.
|
package/docs/guias/lead.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
|
|
24
24
|
## Tus decisiones clave
|
|
25
25
|
|
|
26
|
-
### 1. ¿En qué nivel
|
|
26
|
+
### 1. ¿En qué nivel empieza el equipo?
|
|
27
27
|
- **1 dev / 1 repo →** N1 (OpenSpec solo, cero herramientas externas).
|
|
28
28
|
- **Equipo compacto →** N2 (US en el gestor + `implements.yaml`).
|
|
29
29
|
- **Muchos repos + equipos separados →** N3 (Jira hub, CI estampa, matriz de ambientes).
|
package/docs/guias/po.md
CHANGED
|
@@ -18,13 +18,17 @@
|
|
|
18
18
|
|
|
19
19
|
## Tu día a día
|
|
20
20
|
|
|
21
|
-
1. **Nace una idea** → creas el ticket en el gestor (nace con ID,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
1. **Nace una idea — o llega un documento** → creas el ticket en el gestor (nace con ID,
|
|
22
|
+
aunque sea vago). Si en cambio partes de un **documento de análisis** (PDF, Word),
|
|
23
|
+
`/doc-to-backlog` lo convierte en un **backlog candidato** de épicas + US para que
|
|
24
|
+
priorices y valides. Y si algo es **demasiado grande** para una sola US,
|
|
25
|
+
`/grill-epic` lo parte en varias.
|
|
26
|
+
2. **Pulir el QUÉ** → ejecutas `/grill-user-story`. La IA te **interroga** hasta que
|
|
26
27
|
la US es testeable (INVEST + Gherkin) y la publica en el gestor. La IA no
|
|
27
28
|
inventa requerimientos: te los saca a preguntas. Tú respondes y decides.
|
|
29
|
+
3. **Gate 0** → ejecutas `/grill-intent` sobre la US ya formada. La IA te desafía el
|
|
30
|
+
*problema*: ¿es el correcto? ¿quién lo sufre? ¿qué pasa si no lo hacemos? Un veredicto
|
|
31
|
+
válido es *"no lo construyas"* — eso es el gate haciendo su trabajo (Art. 4).
|
|
28
32
|
4. **Verificas el [DoR](../../templates/definition-of-ready.md)** → antes de que entre al sprint, la US cumple el
|
|
29
33
|
[`definition-of-ready.md`](../../templates/definition-of-ready.md).
|
|
30
34
|
5. **Demo** → aceptas o rechazas contra los mismos criterios que ya eran tests.
|
|
@@ -44,7 +48,9 @@ el CI (Art. 10).
|
|
|
44
48
|
|
|
45
49
|
## Tus herramientas
|
|
46
50
|
|
|
47
|
-
- `/
|
|
48
|
-
- `/grill-
|
|
51
|
+
- `/doc-to-backlog` — un documento (PDF/Word) → backlog candidato de épicas + US
|
|
52
|
+
- `/grill-epic` — algo grande → una épica partida en varias US
|
|
53
|
+
- `/grill-user-story` — una US funcional y testeable
|
|
54
|
+
- `/grill-intent` — Gate 0: desafía el problema de la US antes del spec
|
|
49
55
|
- el gestor de proyectos
|
|
50
56
|
- [`definition-of-ready.md`](../../templates/definition-of-ready.md)
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: home
|
|
3
|
+
|
|
4
|
+
hero:
|
|
5
|
+
name: dai
|
|
6
|
+
text: Desarrollo Asistido por IA
|
|
7
|
+
tagline: La documentación del método — el manifiesto, las decisiones (ADRs) y las guías por rol. Todo buscable con ⌘K.
|
|
8
|
+
actions:
|
|
9
|
+
- theme: brand
|
|
10
|
+
text: Empezar
|
|
11
|
+
link: /PROBAR
|
|
12
|
+
- theme: alt
|
|
13
|
+
text: El manifiesto
|
|
14
|
+
link: /MANIFIESTO
|
|
15
|
+
- theme: alt
|
|
16
|
+
text: ↩ Volver a la landing
|
|
17
|
+
link: https://dforce2055.github.io/dai/
|
|
18
|
+
|
|
19
|
+
features:
|
|
20
|
+
- icon: 📐
|
|
21
|
+
title: El método
|
|
22
|
+
details: Manifiesto, metodología y el Scrum con IA en 10 pasos. El porqué antes que el cómo.
|
|
23
|
+
link: /MANIFIESTO
|
|
24
|
+
linkText: Leer el manifiesto
|
|
25
|
+
- icon: 🧭
|
|
26
|
+
title: Las decisiones (ADRs)
|
|
27
|
+
details: Cada decisión de diseño, registrada — del contrato del ac_hash al review inline. Por qué dai es como es.
|
|
28
|
+
link: /adr/
|
|
29
|
+
linkText: Ver los ADRs
|
|
30
|
+
- icon: 🧑💻
|
|
31
|
+
title: Guías por rol
|
|
32
|
+
details: Caminos cortos según quién sos — PO / analista, dev, o lead. Directo a lo que te toca.
|
|
33
|
+
link: /guias/dev
|
|
34
|
+
linkText: Ir a las guías
|
|
35
|
+
---
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<defs><radialGradient id="favc" cx="0.5" cy="0.5" r="0.5">
|
|
3
|
+
<stop offset="0.35" stop-color="#F4B41A"/><stop offset="1" stop-color="#D98E04"/>
|
|
4
|
+
</radialGradient></defs>
|
|
5
|
+
<g fill="url(#favc)"><path d="M50.00 4.00 L52.00 29.00 L48.00 29.00 Z"/><path d="M67.60 7.50 L59.88 31.36 L56.19 29.83 Z"/><path d="M82.53 17.47 L66.26 36.56 L63.44 33.74 Z"/><path d="M92.50 32.40 L70.17 43.81 L68.64 40.12 Z"/><path d="M96.00 50.00 L71.00 52.00 L71.00 48.00 Z"/><path d="M92.50 67.60 L68.64 59.88 L70.17 56.19 Z"/><path d="M82.53 82.53 L63.44 66.26 L66.26 63.44 Z"/><path d="M67.60 92.50 L56.19 70.17 L59.88 68.64 Z"/><path d="M50.00 96.00 L48.00 71.00 L52.00 71.00 Z"/><path d="M32.40 92.50 L40.12 68.64 L43.81 70.17 Z"/><path d="M17.47 82.53 L33.74 63.44 L36.56 66.26 Z"/><path d="M7.50 67.60 L29.83 56.19 L31.36 59.88 Z"/><path d="M4.00 50.00 L29.00 48.00 L29.00 52.00 Z"/><path d="M7.50 32.40 L31.36 40.12 L29.83 43.81 Z"/><path d="M17.47 17.47 L36.56 33.74 L33.74 36.56 Z"/><path d="M32.40 7.50 L43.81 29.83 L40.12 31.36 Z"/></g>
|
|
6
|
+
|
|
7
|
+
<circle cx="50" cy="50" r="19" fill="none" stroke="#74ACDF" stroke-width="2.3"/>
|
|
8
|
+
<circle cx="50" cy="50" r="15" fill="#14305C"/><path d="M43.5 44.9 L39.5 50 L43.5 55.1
|
|
9
|
+
M56.5 44.9 L60.5 50 L56.5 55.1
|
|
10
|
+
M51.8 44.4 L48.2 55.6"
|
|
11
|
+
fill="none" stroke="#EAF4FB" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<defs><radialGradient id="sol-link" cx="0.5" cy="0.5" r="0.5">
|
|
3
|
+
<stop offset="0.35" stop-color="#F4B41A"/><stop offset="1" stop-color="#D98E04"/>
|
|
4
|
+
</radialGradient></defs>
|
|
5
|
+
<g fill="url(#sol-link)"><path d="M50.00 6.00 L51.12 32.00 L48.88 32.00 Z"/><path d="M57.61 11.75 L54.61 32.56 L52.41 32.13 Z"/><path d="M66.84 9.35 L57.92 33.80 L55.85 32.94 Z"/><path d="M71.67 17.57 L60.93 35.66 L59.07 34.41 Z"/><path d="M81.11 18.89 L63.52 38.06 L61.94 36.48 Z"/><path d="M82.43 28.33 L65.59 40.93 L64.34 39.07 Z"/><path d="M90.65 33.16 L67.06 44.15 L66.20 42.08 Z"/><path d="M88.25 42.39 L67.87 47.59 L67.44 45.39 Z"/><path d="M94.00 50.00 L68.00 51.12 L68.00 48.88 Z"/><path d="M88.25 57.61 L67.44 54.61 L67.87 52.41 Z"/><path d="M90.65 66.84 L66.20 57.92 L67.06 55.85 Z"/><path d="M82.43 71.67 L64.34 60.93 L65.59 59.07 Z"/><path d="M81.11 81.11 L61.94 63.52 L63.52 61.94 Z"/><path d="M71.67 82.43 L59.07 65.59 L60.93 64.34 Z"/><path d="M66.84 90.65 L55.85 67.06 L57.92 66.20 Z"/><path d="M57.61 88.25 L52.41 67.87 L54.61 67.44 Z"/><path d="M50.00 94.00 L48.88 68.00 L51.12 68.00 Z"/><path d="M42.39 88.25 L45.39 67.44 L47.59 67.87 Z"/><path d="M33.16 90.65 L42.08 66.20 L44.15 67.06 Z"/><path d="M28.33 82.43 L39.07 64.34 L40.93 65.59 Z"/><path d="M18.89 81.11 L36.48 61.94 L38.06 63.52 Z"/><path d="M17.57 71.67 L34.41 59.07 L35.66 60.93 Z"/><path d="M9.35 66.84 L32.94 55.85 L33.80 57.92 Z"/><path d="M11.75 57.61 L32.13 52.41 L32.56 54.61 Z"/><path d="M6.00 50.00 L32.00 48.88 L32.00 51.12 Z"/><path d="M11.75 42.39 L32.56 45.39 L32.13 47.59 Z"/><path d="M9.35 33.16 L33.80 42.08 L32.94 44.15 Z"/><path d="M17.57 28.33 L35.66 39.07 L34.41 40.93 Z"/><path d="M18.89 18.89 L38.06 36.48 L36.48 38.06 Z"/><path d="M28.33 17.57 L40.93 34.41 L39.07 35.66 Z"/><path d="M33.16 9.35 L44.15 32.94 L42.08 33.80 Z"/><path d="M42.39 11.75 L47.59 32.13 L45.39 32.56 Z"/></g>
|
|
6
|
+
|
|
7
|
+
<circle cx="50" cy="50" r="15.5" fill="none" stroke="#74ACDF" stroke-width="2.3"/>
|
|
8
|
+
<circle cx="50" cy="50" r="12" fill="#14305C"/>
|
|
9
|
+
<line x1="45" y1="50" x2="55" y2="50" stroke="#EAF4FB" stroke-width="2.2" stroke-linecap="round"/>
|
|
10
|
+
<circle cx="45" cy="50" r="2.5" fill="#EAF4FB"/>
|
|
11
|
+
<circle cx="55" cy="50" r="2.5" fill="#EAF4FB"/>
|
|
12
|
+
</svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
|
2
|
+
<defs><radialGradient id="sol-code" cx="0.5" cy="0.5" r="0.5">
|
|
3
|
+
<stop offset="0.35" stop-color="#F4B41A"/><stop offset="1" stop-color="#D98E04"/>
|
|
4
|
+
</radialGradient></defs>
|
|
5
|
+
<g fill="url(#sol-code)"><path d="M50.00 6.00 L51.12 32.00 L48.88 32.00 Z"/><path d="M57.61 11.75 L54.61 32.56 L52.41 32.13 Z"/><path d="M66.84 9.35 L57.92 33.80 L55.85 32.94 Z"/><path d="M71.67 17.57 L60.93 35.66 L59.07 34.41 Z"/><path d="M81.11 18.89 L63.52 38.06 L61.94 36.48 Z"/><path d="M82.43 28.33 L65.59 40.93 L64.34 39.07 Z"/><path d="M90.65 33.16 L67.06 44.15 L66.20 42.08 Z"/><path d="M88.25 42.39 L67.87 47.59 L67.44 45.39 Z"/><path d="M94.00 50.00 L68.00 51.12 L68.00 48.88 Z"/><path d="M88.25 57.61 L67.44 54.61 L67.87 52.41 Z"/><path d="M90.65 66.84 L66.20 57.92 L67.06 55.85 Z"/><path d="M82.43 71.67 L64.34 60.93 L65.59 59.07 Z"/><path d="M81.11 81.11 L61.94 63.52 L63.52 61.94 Z"/><path d="M71.67 82.43 L59.07 65.59 L60.93 64.34 Z"/><path d="M66.84 90.65 L55.85 67.06 L57.92 66.20 Z"/><path d="M57.61 88.25 L52.41 67.87 L54.61 67.44 Z"/><path d="M50.00 94.00 L48.88 68.00 L51.12 68.00 Z"/><path d="M42.39 88.25 L45.39 67.44 L47.59 67.87 Z"/><path d="M33.16 90.65 L42.08 66.20 L44.15 67.06 Z"/><path d="M28.33 82.43 L39.07 64.34 L40.93 65.59 Z"/><path d="M18.89 81.11 L36.48 61.94 L38.06 63.52 Z"/><path d="M17.57 71.67 L34.41 59.07 L35.66 60.93 Z"/><path d="M9.35 66.84 L32.94 55.85 L33.80 57.92 Z"/><path d="M11.75 57.61 L32.13 52.41 L32.56 54.61 Z"/><path d="M6.00 50.00 L32.00 48.88 L32.00 51.12 Z"/><path d="M11.75 42.39 L32.56 45.39 L32.13 47.59 Z"/><path d="M9.35 33.16 L33.80 42.08 L32.94 44.15 Z"/><path d="M17.57 28.33 L35.66 39.07 L34.41 40.93 Z"/><path d="M18.89 18.89 L38.06 36.48 L36.48 38.06 Z"/><path d="M28.33 17.57 L40.93 34.41 L39.07 35.66 Z"/><path d="M33.16 9.35 L44.15 32.94 L42.08 33.80 Z"/><path d="M42.39 11.75 L47.59 32.13 L45.39 32.56 Z"/></g>
|
|
6
|
+
|
|
7
|
+
<circle cx="50" cy="50" r="16" fill="none" stroke="#74ACDF" stroke-width="2.3"/>
|
|
8
|
+
<circle cx="50" cy="50" r="12.8" fill="#14305C"/><path d="M44.5 46.43 L40.5 50 L44.5 53.57
|
|
9
|
+
M55.5 46.43 L59.5 50 L55.5 53.57
|
|
10
|
+
M51.8 45.93 L48.2 54.07"
|
|
11
|
+
fill="none" stroke="#EAF4FB" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|