bug_bunny 4.8.0 → 4.9.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.
- checksums.yaml +4 -4
- data/.agents/skills/documentation-writer/SKILL.md +45 -0
- data/.agents/skills/gem-release/SKILL.md +116 -0
- data/.agents/skills/quality-code/SKILL.md +51 -0
- data/.agents/skills/sentry/SKILL.md +135 -0
- data/.agents/skills/sentry/references/api-endpoints.md +147 -0
- data/.agents/skills/sentry/scripts/sentry.rb +194 -0
- data/.agents/skills/skill-builder/SKILL.md +293 -0
- data/.agents/skills/skill-manager/SKILL.md +225 -0
- data/.agents/skills/skill-manager/scripts/sync.rb +356 -0
- data/.agents/skills/yard/SKILL.md +311 -0
- data/.agents/skills/yard/references/tipos.md +144 -0
- data/CHANGELOG.md +14 -0
- data/CLAUDE.md +28 -225
- data/README.md +5 -3
- data/lib/bug_bunny/consumer.rb +21 -5
- data/lib/bug_bunny/otel.rb +47 -0
- data/lib/bug_bunny/producer.rb +13 -4
- data/lib/bug_bunny/request.rb +14 -2
- data/lib/bug_bunny/version.rb +1 -1
- data/lib/bug_bunny.rb +1 -0
- data/skill/SKILL.md +253 -0
- data/skill/references/client-middleware.md +161 -0
- data/skill/references/consumer.md +122 -0
- data/skill/references/controller.md +105 -0
- data/skill/references/errores.md +97 -0
- data/skill/references/resource.md +116 -0
- data/skill/references/routing.md +82 -0
- data/skill/references/testing.md +138 -0
- data/skills.lock +30 -0
- data/skills.yml +40 -0
- data/spec/integration/consumer_middleware_spec.rb +23 -2
- data/spec/unit/consumer_spec.rb +138 -6
- data/spec/unit/otel_spec.rb +54 -0
- data/spec/unit/producer_spec.rb +187 -0
- data/spec/unit/request_spec.rb +51 -0
- metadata +28 -29
- data/.agents/skills/rabbitmq-expert/SKILL.md +0 -1555
- data/.claude/commands/gem-ai-setup.md +0 -174
- data/.claude/commands/pr.md +0 -53
- data/.claude/commands/release.md +0 -52
- data/.claude/commands/rubocop.md +0 -22
- data/.claude/commands/service-ai-setup.md +0 -168
- data/.claude/commands/test.md +0 -28
- data/.claude/commands/yard.md +0 -46
- data/docs/_index.md +0 -50
- data/docs/ai/_index.md +0 -56
- data/docs/ai/antipatterns.md +0 -166
- data/docs/ai/api.md +0 -251
- data/docs/ai/architecture.md +0 -92
- data/docs/ai/errors.md +0 -158
- data/docs/ai/faq_external.md +0 -133
- data/docs/ai/faq_internal.md +0 -86
- data/docs/ai/glossary.md +0 -45
- data/docs/concepts.md +0 -140
- data/docs/howto/controller.md +0 -194
- data/docs/howto/middleware_client.md +0 -119
- data/docs/howto/middleware_consumer.md +0 -127
- data/docs/howto/rails.md +0 -214
- data/docs/howto/resource.md +0 -200
- data/docs/howto/routing.md +0 -133
- data/docs/howto/testing.md +0 -259
- data/docs/howto/tracing.md +0 -119
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# Helper para interactuar con la API de Sentry self-hosted de Wispro.
|
|
5
|
+
# Uso: ruby sentry.rb <comando> [opciones]
|
|
6
|
+
#
|
|
7
|
+
# Comandos:
|
|
8
|
+
# projects — Lista todos los proyectos
|
|
9
|
+
# issues <project_slug> [opciones] — Lista issues de un proyecto
|
|
10
|
+
# issue <issue_id> — Detalle de un issue
|
|
11
|
+
# events <issue_id> [--full] — Eventos de un issue
|
|
12
|
+
# search <project_slug> <query> — Busca issues por texto
|
|
13
|
+
# resolve <issue_id> — Resuelve un issue
|
|
14
|
+
# ignore <issue_id> — Ignora un issue
|
|
15
|
+
# assign <issue_id> <username> — Asigna un issue
|
|
16
|
+
|
|
17
|
+
require 'net/http'
|
|
18
|
+
require 'uri'
|
|
19
|
+
require 'json'
|
|
20
|
+
require 'openssl'
|
|
21
|
+
|
|
22
|
+
module Sentry
|
|
23
|
+
URL = ENV['SENTRY_URL'] || 'https://sentry.cloud.wispro.co'
|
|
24
|
+
TOKEN = ENV['SENTRY_TOKEN']
|
|
25
|
+
ORG = ENV['SENTRY_ORG'] || 'wispro'
|
|
26
|
+
|
|
27
|
+
class << self
|
|
28
|
+
def run(args)
|
|
29
|
+
unless TOKEN
|
|
30
|
+
puts "ERROR: SENTRY_TOKEN no configurado en el entorno."
|
|
31
|
+
exit 1
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
command = args.shift
|
|
35
|
+
case command
|
|
36
|
+
when 'projects' then projects
|
|
37
|
+
when 'issues' then issues(args)
|
|
38
|
+
when 'issue' then issue(args.first)
|
|
39
|
+
when 'events' then events(args)
|
|
40
|
+
when 'search' then search(args)
|
|
41
|
+
when 'resolve' then update_status(args.first, 'resolved')
|
|
42
|
+
when 'ignore' then update_status(args.first, 'ignored')
|
|
43
|
+
when 'assign' then assign(args[0], args[1])
|
|
44
|
+
else
|
|
45
|
+
puts USAGE
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
USAGE = <<~TEXT
|
|
52
|
+
Uso: ruby sentry.rb <comando> [opciones]
|
|
53
|
+
|
|
54
|
+
Comandos:
|
|
55
|
+
projects Lista todos los proyectos
|
|
56
|
+
issues <project_slug> [--period=24h] Lista issues (default: 24h, unresolved)
|
|
57
|
+
issue <issue_id> Detalle de un issue
|
|
58
|
+
events <issue_id> [--full] Eventos de un issue
|
|
59
|
+
search <project_slug> <query> Busca issues por texto
|
|
60
|
+
resolve <issue_id> Resuelve un issue
|
|
61
|
+
ignore <issue_id> Ignora un issue
|
|
62
|
+
assign <issue_id> <username> Asigna un issue
|
|
63
|
+
TEXT
|
|
64
|
+
|
|
65
|
+
def projects
|
|
66
|
+
data = get("/organizations/#{ORG}/projects/")
|
|
67
|
+
data.each do |p|
|
|
68
|
+
puts " #{p['slug'].ljust(30)} #{p['name']}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def issues(args)
|
|
73
|
+
slug = args.shift
|
|
74
|
+
period = extract_flag(args, '--period') || '24h'
|
|
75
|
+
|
|
76
|
+
data = get("/projects/#{ORG}/#{slug}/issues/?statsPeriod=#{period}&query=is:unresolved")
|
|
77
|
+
print_issues(data)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def issue(issue_id)
|
|
81
|
+
data = get("/organizations/#{ORG}/issues/#{issue_id}/")
|
|
82
|
+
puts " ##{data['shortId']} — #{data['title']}"
|
|
83
|
+
puts " Level: #{data['level']} | Count: #{data['count']} | Users: #{data['userCount']}"
|
|
84
|
+
puts " First: #{data['firstSeen']} | Last: #{data['lastSeen']}"
|
|
85
|
+
puts " Status: #{data['status']}"
|
|
86
|
+
puts " Assigned: #{data.dig('assignedTo', 'name') || 'nadie'}"
|
|
87
|
+
puts " Link: #{data['permalink']}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def events(args)
|
|
91
|
+
issue_id = args.shift
|
|
92
|
+
full = args.include?('--full')
|
|
93
|
+
params = full ? '?full=true&limit=3' : '?limit=5'
|
|
94
|
+
|
|
95
|
+
data = get("/organizations/#{ORG}/issues/#{issue_id}/events/#{params}")
|
|
96
|
+
data.each do |event|
|
|
97
|
+
puts "\n Event #{event['eventID'][0..7]} — #{event['dateCreated']}"
|
|
98
|
+
puts " #{event['title']}"
|
|
99
|
+
|
|
100
|
+
next unless full && event['entries']
|
|
101
|
+
|
|
102
|
+
event['entries'].each do |entry|
|
|
103
|
+
next unless entry['type'] == 'exception'
|
|
104
|
+
|
|
105
|
+
entry.dig('data', 'values')&.each do |exc|
|
|
106
|
+
puts " Exception: #{exc['type']}: #{exc['value']}"
|
|
107
|
+
frames = exc.dig('stacktrace', 'frames') || []
|
|
108
|
+
frames.select { |f| f['inApp'] }.last(5).each do |frame|
|
|
109
|
+
puts " #{frame['filename']}:#{frame['lineNo']} in #{frame['function']}"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def search(args)
|
|
117
|
+
slug = args.shift
|
|
118
|
+
query = args.join(' ')
|
|
119
|
+
data = get("/projects/#{ORG}/#{slug}/issues/?query=#{URI.encode_www_form_component(query)}&statsPeriod=24h")
|
|
120
|
+
print_issues(data)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def update_status(issue_id, status)
|
|
124
|
+
data = put("/organizations/#{ORG}/issues/#{issue_id}/", { status: status })
|
|
125
|
+
puts " Issue ##{issue_id} → #{data['status']}"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def assign(issue_id, username)
|
|
129
|
+
data = put("/organizations/#{ORG}/issues/#{issue_id}/", { assignedTo: username })
|
|
130
|
+
puts " Issue ##{issue_id} → asignado a #{data.dig('assignedTo', 'name') || username}"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def print_issues(data)
|
|
134
|
+
if data.empty?
|
|
135
|
+
puts " Sin issues encontrados."
|
|
136
|
+
return
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
data.each do |i|
|
|
140
|
+
level = i['level'].upcase.ljust(7)
|
|
141
|
+
count = "x#{i['count']}".ljust(6)
|
|
142
|
+
puts " #{level} #{count} ##{i['shortId'].ljust(15)} #{i['title'][0..80]}"
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# --- HTTP ---
|
|
147
|
+
|
|
148
|
+
def get(path)
|
|
149
|
+
request(:get, path)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def put(path, body)
|
|
153
|
+
request(:put, path, body)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def request(method, path, body = nil)
|
|
157
|
+
uri = URI.parse("#{URL}/api/0#{path}")
|
|
158
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
159
|
+
http.use_ssl = uri.scheme == 'https'
|
|
160
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
161
|
+
|
|
162
|
+
req = case method
|
|
163
|
+
when :get then Net::HTTP::Get.new(uri)
|
|
164
|
+
when :put then Net::HTTP::Put.new(uri)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
req['Authorization'] = "Bearer #{TOKEN}"
|
|
168
|
+
req['Content-Type'] = 'application/json'
|
|
169
|
+
req.body = JSON.generate(body) if body
|
|
170
|
+
|
|
171
|
+
response = http.request(req)
|
|
172
|
+
|
|
173
|
+
unless response.code.start_with?('2')
|
|
174
|
+
puts " ERROR: HTTP #{response.code} — #{response.body[0..200]}"
|
|
175
|
+
exit 1
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
JSON.parse(response.body)
|
|
179
|
+
rescue StandardError => e
|
|
180
|
+
puts " ERROR: #{e.message}"
|
|
181
|
+
exit 1
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def extract_flag(args, flag)
|
|
185
|
+
idx = args.index { |a| a.start_with?(flag) }
|
|
186
|
+
return nil unless idx
|
|
187
|
+
|
|
188
|
+
value = args.delete_at(idx)
|
|
189
|
+
value.include?('=') ? value.split('=', 2).last : args.delete_at(idx)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
Sentry.run(ARGV.dup) if __FILE__ == $PROGRAM_NAME
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-builder
|
|
3
|
+
description: Genera o actualiza la skill empaquetada (`skill/`) para cualquier proyecto Ruby (gema o servicio). Detecta automáticamente el tipo de proyecto y analiza el código correspondiente. Soporta desde un SKILL.md simple hasta skills con references y scripts. Es invocada por `skill-manager`, `gem-release` (regeneración completa) y `quality-code` (actualización incremental).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill Builder
|
|
7
|
+
|
|
8
|
+
Sos un experto en crear skills de conocimiento para proyectos Ruby. Tu objetivo es generar o actualizar `skill/SKILL.md` — un artefacto autocontenido que permite a cualquier agente de IA responder preguntas sobre integración, arquitectura, API, errores y antipatrones del proyecto.
|
|
9
|
+
|
|
10
|
+
## Detección de tipo de proyecto
|
|
11
|
+
|
|
12
|
+
- **Gema**: existe `.gemspec` en la raíz.
|
|
13
|
+
- **Servicio**: existe `config/application.rb`.
|
|
14
|
+
- Si ambos existen, priorizar gema.
|
|
15
|
+
|
|
16
|
+
**Distribución en gemas:** La skill queda en `skill/` en la raíz del repositorio. Al publicar con `gem-release`, `skill/` se empaqueta en el `.gem`, de modo que los consumidores acceden a la skill directamente desde la gema instalada (`Gem.loaded_specs["[name]"].gem_dir + "/skill/"`) sin descargas adicionales.
|
|
17
|
+
|
|
18
|
+
**Distribución en servicios:** La skill queda en `skill/` en la raíz del repositorio. Los consumidores la descargan vía `skill-manager sync` desde GitHub.
|
|
19
|
+
|
|
20
|
+
## Escenarios de Complejidad
|
|
21
|
+
|
|
22
|
+
La estructura de `skill/` depende de la complejidad del proyecto. `skill-manager` determina el escenario inicial, pero puede evolucionar con el tiempo:
|
|
23
|
+
|
|
24
|
+
### Escenario 1 — Proyecto simple
|
|
25
|
+
```
|
|
26
|
+
skill/
|
|
27
|
+
SKILL.md
|
|
28
|
+
```
|
|
29
|
+
La skill entera cabe en un solo archivo. Secciones autocontenidas de ≤400 tokens.
|
|
30
|
+
|
|
31
|
+
### Escenario 2 — Con referencias
|
|
32
|
+
```
|
|
33
|
+
skill/
|
|
34
|
+
SKILL.md
|
|
35
|
+
references/
|
|
36
|
+
api-detallada.md
|
|
37
|
+
errores.md
|
|
38
|
+
```
|
|
39
|
+
Cuando la API o contratos son extensos, o el catálogo de errores es grande.
|
|
40
|
+
|
|
41
|
+
### Escenario 3 — Con scripts
|
|
42
|
+
```
|
|
43
|
+
skill/
|
|
44
|
+
SKILL.md
|
|
45
|
+
scripts/
|
|
46
|
+
diagnostico.rb
|
|
47
|
+
```
|
|
48
|
+
Cuando el proyecto necesita herramientas ejecutables (diagnóstico, migración, validación).
|
|
49
|
+
|
|
50
|
+
### Escenario 4 — Completa
|
|
51
|
+
```
|
|
52
|
+
skill/
|
|
53
|
+
SKILL.md
|
|
54
|
+
references/
|
|
55
|
+
api-detallada.md
|
|
56
|
+
errores.md
|
|
57
|
+
scripts/
|
|
58
|
+
diagnostico.rb
|
|
59
|
+
migration_helper.rb
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Criterios para escalar
|
|
63
|
+
|
|
64
|
+
- **→ references/** cuando una sección de `SKILL.md` supera los 400 tokens y es conocimiento de referencia (API, contratos, errores, catálogos).
|
|
65
|
+
- **→ scripts/** cuando el proyecto necesita herramientas ejecutables para diagnóstico, migración o validación que complementen el conocimiento.
|
|
66
|
+
|
|
67
|
+
## Modos de Ejecución
|
|
68
|
+
|
|
69
|
+
- **Completo** (invocado por `gem-release` o manualmente): Regenera la skill desde cero analizando todo el código.
|
|
70
|
+
- **Incremental** (invocado por `quality-code`): Actualiza solo las secciones afectadas por el diff del PR.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Paso 1 — Descubrir el estado actual
|
|
75
|
+
|
|
76
|
+
Leer en orden:
|
|
77
|
+
1. `skill/SKILL.md` — si existe, es la skill actual.
|
|
78
|
+
2. `skill/references/` — referencias existentes.
|
|
79
|
+
3. `skill/scripts/` — scripts existentes.
|
|
80
|
+
4. `CLAUDE.md` — propósito del artefacto, arquitectura, decisiones clave.
|
|
81
|
+
|
|
82
|
+
Según el tipo de proyecto:
|
|
83
|
+
|
|
84
|
+
**Si es gema:**
|
|
85
|
+
5. `.gemspec` — nombre, descripción, dependencias.
|
|
86
|
+
6. `lib/` — API pública, responsabilidades de clases, firmas de métodos.
|
|
87
|
+
7. `spec/` o `test/` — patrones de uso, casos borde, errores esperados.
|
|
88
|
+
|
|
89
|
+
**Si es servicio:**
|
|
90
|
+
5. `config/application.rb` — nombre, configuración.
|
|
91
|
+
6. `config/routes.rb` — endpoints HTTP expuestos.
|
|
92
|
+
7. `app/` — controllers, models, services, jobs.
|
|
93
|
+
8. Queues/mensajería — contratos de eventos (Sidekiq, ActiveJob, etc.).
|
|
94
|
+
9. `db/migrate/` — esquema y evolución del modelo de datos.
|
|
95
|
+
10. `spec/` o `test/` — patrones de uso, casos borde, errores esperados.
|
|
96
|
+
|
|
97
|
+
En modo **incremental**, analizar también `git diff [PRIMARY_BRANCH]...HEAD` para identificar qué cambió.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Paso 2 — Analizar el código y determinar escenario
|
|
102
|
+
|
|
103
|
+
**Común a ambos tipos:**
|
|
104
|
+
- **Arquitectura**: Flujo de datos, componentes core, thread safety, dependencias.
|
|
105
|
+
- **Uso**: Ejemplos de integración, patrones comunes.
|
|
106
|
+
- **Errores**: Excepciones personalizadas, causas, resoluciones.
|
|
107
|
+
- **Antipatrones**: Usos incorrectos identificados en tests o código.
|
|
108
|
+
- **Scripts necesarios**: ¿Hay flujos de diagnóstico, migración o validación que justifiquen un script?
|
|
109
|
+
|
|
110
|
+
**Específico de gemas:**
|
|
111
|
+
- **API Pública**: Bloque de configuración, clases principales, métodos públicos, parámetros.
|
|
112
|
+
|
|
113
|
+
**Específico de servicios:**
|
|
114
|
+
- **Contratos**: Endpoints HTTP, queues, eventos publicados/consumidos, webhooks.
|
|
115
|
+
- **Infraestructura**: Variables de entorno, servicios externos, bases de datos.
|
|
116
|
+
|
|
117
|
+
Con base en el análisis, determiná qué escenario de complejidad corresponde (1-4). Si la skill ya existe, evaluá si el escenario debe escalar.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Paso 3 — Generar la Skill
|
|
122
|
+
|
|
123
|
+
Generar `skill/SKILL.md` (y `references/` o `scripts/` si el escenario lo requiere).
|
|
124
|
+
|
|
125
|
+
### Reglas de escritura (RAG-optimized)
|
|
126
|
+
|
|
127
|
+
1. **Idioma: español** — Todo el contenido en español. Mantener términos técnicos estándar (ej: "middleware", "routing").
|
|
128
|
+
2. **Cada sección <= 400 tokens** — Autocontenida, sin asumir contexto de otras secciones. Si una sección supera este límite, extraerla a `references/`.
|
|
129
|
+
3. **Sin prosa introductoria** — Ir directo al contenido técnico.
|
|
130
|
+
4. **Sin frontmatter complejo** — No incluir version, profile o audiences.
|
|
131
|
+
5. **Sin duplicación** — Si un tema está en `references/`, la skill solo lo referencia.
|
|
132
|
+
|
|
133
|
+
### Estructura de SKILL.md
|
|
134
|
+
|
|
135
|
+
#### Titulo y Descripcion
|
|
136
|
+
|
|
137
|
+
```markdown
|
|
138
|
+
# [Nombre] Expert
|
|
139
|
+
|
|
140
|
+
Skill de conocimiento completo sobre [Nombre]. Consultame para cualquier pregunta sobre integración, arquitectura, API, errores y antipatrones.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Glosario
|
|
144
|
+
|
|
145
|
+
Términos del dominio. Formato: `**Término** — Definición concisa (1-3 líneas).`
|
|
146
|
+
|
|
147
|
+
#### Arquitectura
|
|
148
|
+
|
|
149
|
+
- Responsabilidad core.
|
|
150
|
+
- Mapa de componentes (diagrama ASCII).
|
|
151
|
+
- Flujo en runtime y decisiones de diseño.
|
|
152
|
+
|
|
153
|
+
**Formato de diagramas ASCII:**
|
|
154
|
+
- Cajas con `┌─┐└─┘`, flechas con `────>` (horizontal) y `│▼` (vertical).
|
|
155
|
+
- Máximo 4-5 componentes por diagrama. Si hay más, dividir en sub-diagramas por capa.
|
|
156
|
+
- Sin texto decorativo fuera de las cajas.
|
|
157
|
+
|
|
158
|
+
Ejemplo:
|
|
159
|
+
```
|
|
160
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
161
|
+
│ Request │────>│ Middleware│────>│ Handler │
|
|
162
|
+
└──────────┘ └──────────┘ └──────────┘
|
|
163
|
+
│
|
|
164
|
+
▼
|
|
165
|
+
┌──────────┐
|
|
166
|
+
│ Cache │
|
|
167
|
+
└──────────┘
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
#### API Publica (gemas)
|
|
171
|
+
|
|
172
|
+
- Bloque de configuración (tipos, defaults, restricciones).
|
|
173
|
+
- Clases y métodos (firma, parámetros, retorno).
|
|
174
|
+
- Ejemplos de código para operaciones principales.
|
|
175
|
+
- Si la API es extensa, mantener un resumen acá y extraer el detalle a `references/api-detallada.md`.
|
|
176
|
+
|
|
177
|
+
#### Contratos (servicios)
|
|
178
|
+
|
|
179
|
+
- Endpoints HTTP (método, path, parámetros, respuesta).
|
|
180
|
+
- Queues y eventos (nombre, payload, productor/consumidor).
|
|
181
|
+
- Webhooks (si aplica).
|
|
182
|
+
- Si los contratos son extensos, extraer a `references/contratos.md`.
|
|
183
|
+
|
|
184
|
+
#### FAQ
|
|
185
|
+
|
|
186
|
+
Formato Q&A estricto. H3 para la pregunta, respuesta <= 150 palabras. Sin preámbulo.
|
|
187
|
+
|
|
188
|
+
#### Antipatrones
|
|
189
|
+
|
|
190
|
+
Qué NO hacer. Por cada uno: nombre, código incorrecto, razón y alternativa.
|
|
191
|
+
|
|
192
|
+
#### Errores
|
|
193
|
+
|
|
194
|
+
Catálogo de excepciones. Por cada una: nombre, causa, reproducción y resolución.
|
|
195
|
+
Si el catálogo es extenso, mantener los errores más comunes acá y extraer el catálogo completo a `references/errores.md`.
|
|
196
|
+
|
|
197
|
+
#### Referencias (si existen)
|
|
198
|
+
|
|
199
|
+
Índice de archivos en `references/` y `scripts/` con descripción de una línea.
|
|
200
|
+
|
|
201
|
+
```markdown
|
|
202
|
+
## Referencias
|
|
203
|
+
|
|
204
|
+
- [API Detallada](references/api-detallada.md) — Documentación completa de clases y métodos
|
|
205
|
+
- [Catálogo de Errores](references/errores.md) — Todas las excepciones con resolución
|
|
206
|
+
- [Diagnóstico](scripts/diagnostico.rb) — Script para verificar configuración en runtime
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Paso 4 — Actualizar README.md
|
|
212
|
+
|
|
213
|
+
Invocá la skill `documentation-writer` para auditar y actualizar el README.
|
|
214
|
+
|
|
215
|
+
**Regla fundamental:** El README es para **humanos** (devs que usan la gema/servicio). La skill (`skill/`) es para **agentes**. Son audiencias distintas. **Nunca referenciar `skill/` desde el README.**
|
|
216
|
+
|
|
217
|
+
### README de una gema (máx 150 líneas)
|
|
218
|
+
|
|
219
|
+
```markdown
|
|
220
|
+
# [Nombre de la gema]
|
|
221
|
+
|
|
222
|
+
Descripción en una línea.
|
|
223
|
+
|
|
224
|
+
## Instalación
|
|
225
|
+
|
|
226
|
+
gem 'nombre', '~> X.X'
|
|
227
|
+
|
|
228
|
+
## Quick Start
|
|
229
|
+
|
|
230
|
+
[Ejemplo mínimo funcional — copiar, pegar, funciona]
|
|
231
|
+
|
|
232
|
+
## Uso
|
|
233
|
+
|
|
234
|
+
[Ejemplos de las operaciones principales]
|
|
235
|
+
|
|
236
|
+
## Configuración
|
|
237
|
+
|
|
238
|
+
[Bloque de configuración con opciones, defaults y descripción]
|
|
239
|
+
|
|
240
|
+
## Contribuir
|
|
241
|
+
|
|
242
|
+
[Cómo correr tests, linting, etc.]
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### README de un servicio (máx 150 líneas)
|
|
246
|
+
|
|
247
|
+
```markdown
|
|
248
|
+
# [Nombre del servicio]
|
|
249
|
+
|
|
250
|
+
Descripción en una línea.
|
|
251
|
+
|
|
252
|
+
## Setup
|
|
253
|
+
|
|
254
|
+
[Pasos para levantar el servicio localmente: bin/setup, docker, etc.]
|
|
255
|
+
|
|
256
|
+
## Endpoints / Contratos
|
|
257
|
+
|
|
258
|
+
[Resumen de los endpoints o queues principales]
|
|
259
|
+
|
|
260
|
+
## Variables de entorno
|
|
261
|
+
|
|
262
|
+
[Lista de env vars necesarias]
|
|
263
|
+
|
|
264
|
+
## Testing
|
|
265
|
+
|
|
266
|
+
[Cómo correr tests]
|
|
267
|
+
|
|
268
|
+
## Deploy
|
|
269
|
+
|
|
270
|
+
[Cómo se despliega: branch, tag, Codefresh]
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Qué NO poner en el README
|
|
274
|
+
- Links a `skill/` ni a `skill/SKILL.md`
|
|
275
|
+
- Documentación interna para agentes
|
|
276
|
+
- Diagramas ASCII extensos (esos van en la skill)
|
|
277
|
+
- Catálogo completo de errores (eso va en la skill)
|
|
278
|
+
- FAQ técnico detallado (eso va en la skill)
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Paso 5 — Mostrar resumen y esperar aprobación
|
|
283
|
+
|
|
284
|
+
Mostrá un resumen de los cambios realizados:
|
|
285
|
+
- Tipo de proyecto detectado (gema o servicio).
|
|
286
|
+
- Escenario de complejidad determinado (y si escaló respecto al anterior).
|
|
287
|
+
- Secciones nuevas, modificadas o eliminadas en `SKILL.md`.
|
|
288
|
+
- Archivos nuevos o actualizados en `references/` o `scripts/`.
|
|
289
|
+
- Cambios en README.md.
|
|
290
|
+
|
|
291
|
+
Preguntá: "¿Querés ver el diff completo antes de escribir los archivos?"
|
|
292
|
+
|
|
293
|
+
**Esperá la aprobación explícita del desarrollador** antes de persistir los cambios.
|