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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/skills/documentation-writer/SKILL.md +45 -0
  3. data/.agents/skills/gem-release/SKILL.md +116 -0
  4. data/.agents/skills/quality-code/SKILL.md +51 -0
  5. data/.agents/skills/sentry/SKILL.md +135 -0
  6. data/.agents/skills/sentry/references/api-endpoints.md +147 -0
  7. data/.agents/skills/sentry/scripts/sentry.rb +194 -0
  8. data/.agents/skills/skill-builder/SKILL.md +293 -0
  9. data/.agents/skills/skill-manager/SKILL.md +225 -0
  10. data/.agents/skills/skill-manager/scripts/sync.rb +356 -0
  11. data/.agents/skills/yard/SKILL.md +311 -0
  12. data/.agents/skills/yard/references/tipos.md +144 -0
  13. data/CHANGELOG.md +14 -0
  14. data/CLAUDE.md +28 -225
  15. data/README.md +5 -3
  16. data/lib/bug_bunny/consumer.rb +21 -5
  17. data/lib/bug_bunny/otel.rb +47 -0
  18. data/lib/bug_bunny/producer.rb +13 -4
  19. data/lib/bug_bunny/request.rb +14 -2
  20. data/lib/bug_bunny/version.rb +1 -1
  21. data/lib/bug_bunny.rb +1 -0
  22. data/skill/SKILL.md +253 -0
  23. data/skill/references/client-middleware.md +161 -0
  24. data/skill/references/consumer.md +122 -0
  25. data/skill/references/controller.md +105 -0
  26. data/skill/references/errores.md +97 -0
  27. data/skill/references/resource.md +116 -0
  28. data/skill/references/routing.md +82 -0
  29. data/skill/references/testing.md +138 -0
  30. data/skills.lock +30 -0
  31. data/skills.yml +40 -0
  32. data/spec/integration/consumer_middleware_spec.rb +23 -2
  33. data/spec/unit/consumer_spec.rb +138 -6
  34. data/spec/unit/otel_spec.rb +54 -0
  35. data/spec/unit/producer_spec.rb +187 -0
  36. data/spec/unit/request_spec.rb +51 -0
  37. metadata +28 -29
  38. data/.agents/skills/rabbitmq-expert/SKILL.md +0 -1555
  39. data/.claude/commands/gem-ai-setup.md +0 -174
  40. data/.claude/commands/pr.md +0 -53
  41. data/.claude/commands/release.md +0 -52
  42. data/.claude/commands/rubocop.md +0 -22
  43. data/.claude/commands/service-ai-setup.md +0 -168
  44. data/.claude/commands/test.md +0 -28
  45. data/.claude/commands/yard.md +0 -46
  46. data/docs/_index.md +0 -50
  47. data/docs/ai/_index.md +0 -56
  48. data/docs/ai/antipatterns.md +0 -166
  49. data/docs/ai/api.md +0 -251
  50. data/docs/ai/architecture.md +0 -92
  51. data/docs/ai/errors.md +0 -158
  52. data/docs/ai/faq_external.md +0 -133
  53. data/docs/ai/faq_internal.md +0 -86
  54. data/docs/ai/glossary.md +0 -45
  55. data/docs/concepts.md +0 -140
  56. data/docs/howto/controller.md +0 -194
  57. data/docs/howto/middleware_client.md +0 -119
  58. data/docs/howto/middleware_consumer.md +0 -127
  59. data/docs/howto/rails.md +0 -214
  60. data/docs/howto/resource.md +0 -200
  61. data/docs/howto/routing.md +0 -133
  62. data/docs/howto/testing.md +0 -259
  63. data/docs/howto/tracing.md +0 -119
@@ -0,0 +1,311 @@
1
+ ---
2
+ name: yard
3
+ description: Experto en documentación YARD para Ruby. Consultame para escribir documentación correcta con tags, tipos, directivas, duck types y patrones avanzados. Úsala SIEMPRE que necesites documentar código Ruby con YARD o auditar documentación existente.
4
+ ---
5
+
6
+ # YARD Expert
7
+
8
+ Skill de conocimiento completo sobre YARD (Yet Another Ruby Document). Consultame para escribir documentación correcta, auditar cobertura o resolver dudas sobre tags, tipos y directivas.
9
+
10
+ ## Glosario
11
+
12
+ **Tag** — Metadato prefijado con `@` que describe un aspecto del código (ej: `@param`, `@return`).
13
+
14
+ **Directiva** — Instrucción prefijada con `@!` que modifica el contexto de parsing (ej: `@!method`, `@!attribute`).
15
+
16
+ **Type specifier list** — Lista de tipos entre corchetes `[Type]` usada en tags como `@param` y `@return`.
17
+
18
+ **Duck type** — Tipo definido por interfaz, no por clase. Se escribe como `#method_name`.
19
+
20
+ **Reference tag** — Sintaxis `(see OBJECT)` que copia tags de otro objeto.
21
+
22
+ ## Anatomía de una documentación YARD
23
+
24
+ ```ruby
25
+ # Descripción breve del método (primera línea).
26
+ #
27
+ # Descripción extendida opcional. Puede tener múltiples párrafos,
28
+ # listas y ejemplos en markdown.
29
+ #
30
+ # @param name [Type] descripción del parámetro
31
+ # @return [Type] descripción del retorno
32
+ # @raise [ExceptionClass] cuándo se lanza
33
+ # @example Título del ejemplo
34
+ # resultado = mi_metodo("valor")
35
+ # # => "esperado"
36
+ def mi_metodo(name)
37
+ end
38
+ ```
39
+
40
+ **Reglas clave:**
41
+ - Primera línea: descripción breve, sin punto final si es corta.
42
+ - Línea vacía entre descripción y tags.
43
+ - Tags multilínea: indentar 2 espacios las líneas siguientes.
44
+ - Orden recomendado de tags: `@param` → `@option` → `@yield` → `@yieldparam` → `@yieldreturn` → `@return` → `@raise` → `@example`.
45
+
46
+ ## Sistema de Tipos
47
+
48
+ Ver catálogo completo en [references/tipos.md](references/tipos.md).
49
+
50
+ ### Tipos básicos
51
+ ```ruby
52
+ # @param name [String] un string
53
+ # @param count [Integer] un entero
54
+ # @param flag [Boolean] true o false (convención YARD, no existe en Ruby)
55
+ # @return [void] sin valor de retorno significativo
56
+ # @return [nil] retorna nil explícitamente
57
+ # @return [self] retorna self (métodos encadenables)
58
+ ```
59
+
60
+ ### Union types
61
+ ```ruby
62
+ # @param input [String, Symbol] acepta string o symbol
63
+ # @return [String, nil] puede retornar nil
64
+ ```
65
+
66
+ ### Generics (parametrized types)
67
+ ```ruby
68
+ # @param items [Array<String>] array de strings
69
+ # @param map [Hash<Symbol, Integer>] hash con keys symbol y values integer
70
+ # @return [Set<User>] set de usuarios
71
+ ```
72
+
73
+ ### Hashes con estructura
74
+ ```ruby
75
+ # @param opts [Hash{Symbol => String}] opciones con keys symbol
76
+ # @param data [Hash{String => Array<Integer>}] hash complejo
77
+ ```
78
+
79
+ ### Duck types
80
+ ```ruby
81
+ # @param io [#read] cualquier objeto que responda a #read
82
+ # @param callable [#call] cualquier objeto callable
83
+ # @param io [#read, #close] debe responder a ambos
84
+ ```
85
+
86
+ ### Order-dependent lists
87
+ ```ruby
88
+ # @return [Array(String, Integer, Hash)] exactamente 3 elementos en ese orden
89
+ ```
90
+
91
+ ### Literals
92
+ ```ruby
93
+ # @return [true] siempre retorna true
94
+ # @return [false, nil] retorna false o nil
95
+ ```
96
+
97
+ ## Tags principales
98
+
99
+ ### @param
100
+ ```ruby
101
+ # @param name [String] el nombre del usuario
102
+ # @param age [Integer] la edad (debe ser > 0)
103
+ def create(name, age); end
104
+ ```
105
+
106
+ ### @option (para hashes de opciones)
107
+ ```ruby
108
+ # @param opts [Hash] opciones de configuración
109
+ # @option opts [String] :host ("localhost") el hostname
110
+ # @option opts [Integer] :port (3000) el puerto
111
+ # @option opts [Boolean] :ssl (false) usar SSL
112
+ def connect(opts = {}); end
113
+ ```
114
+
115
+ ### @return
116
+ ```ruby
117
+ # @return [String] la representación en texto
118
+ # @return [void] no usar el valor de retorno
119
+ def to_s; end
120
+ ```
121
+
122
+ ### @yield y @yieldparam
123
+ ```ruby
124
+ # @yield [user, index] itera sobre cada usuario
125
+ # @yieldparam user [User] el usuario actual
126
+ # @yieldparam index [Integer] la posición en la lista
127
+ # @yieldreturn [Boolean] true para continuar, false para detener
128
+ def each_user(&block); end
129
+ ```
130
+
131
+ ### @raise
132
+ ```ruby
133
+ # @raise [ArgumentError] si el nombre está vacío
134
+ # @raise [ActiveRecord::RecordNotFound] si no existe el registro
135
+ def find!(name); end
136
+ ```
137
+
138
+ ### @example
139
+ ```ruby
140
+ # @example Uso básico
141
+ # user = User.find("john")
142
+ # user.name #=> "john"
143
+ #
144
+ # @example Con opciones
145
+ # user = User.find("john", include: :posts)
146
+ def find(name, **opts); end
147
+ ```
148
+
149
+ ### @see
150
+ ```ruby
151
+ # @see User#destroy método relacionado
152
+ # @see https://api.example.com/docs documentación externa
153
+ ```
154
+
155
+ ### @deprecated
156
+ ```ruby
157
+ # @deprecated Usar {#new_method} en su lugar desde v2.0.
158
+ def old_method; end
159
+ ```
160
+
161
+ ### @abstract
162
+ ```ruby
163
+ # @abstract Subclases deben implementar {#execute}.
164
+ class BaseCommand; end
165
+ ```
166
+
167
+ ### @note y @todo
168
+ ```ruby
169
+ # @note Este método no es thread-safe.
170
+ # @todo Agregar soporte para paginación.
171
+ def fetch_all; end
172
+ ```
173
+
174
+ ### @since y @api
175
+ ```ruby
176
+ # @since 1.5.0
177
+ # @api private
178
+ def internal_method; end
179
+ ```
180
+
181
+ ## Directivas
182
+
183
+ ### @!method (documentar métodos dinámicos)
184
+ ```ruby
185
+ class User
186
+ # @!method name
187
+ # @return [String] el nombre del usuario
188
+ # @!method name=(value)
189
+ # @param value [String] el nuevo nombre
190
+ attr_accessor :name
191
+ end
192
+ ```
193
+
194
+ ### @!attribute
195
+ ```ruby
196
+ # @!attribute [r] count
197
+ # @return [Integer] el conteo actual
198
+ # @!attribute [rw] name
199
+ # @return [String] el nombre
200
+ ```
201
+
202
+ ### @!macro (evitar repetición)
203
+ ```ruby
204
+ # @!macro [attach] property
205
+ # @!method $1
206
+ # @return [$2] el valor de $1
207
+ property :name, String
208
+ property :age, Integer
209
+ ```
210
+
211
+ ### @!group / @!endgroup
212
+ ```ruby
213
+ # @!group Validaciones
214
+
215
+ def validate_name; end
216
+ def validate_age; end
217
+
218
+ # @!endgroup
219
+ ```
220
+
221
+ ### @!scope y @!visibility
222
+ ```ruby
223
+ # @!scope class
224
+ # @!visibility private
225
+ ```
226
+
227
+ ## Reference tags
228
+ ```ruby
229
+ # @param user [String] el usuario
230
+ # @param host [String] el host
231
+ def clean(user, host); end
232
+
233
+ # @param (see #clean)
234
+ def activate(user, host); end
235
+ ```
236
+
237
+ ## Antipatrones
238
+
239
+ **Documentar lo obvio** — No repitas el nombre del método en la descripción.
240
+ ```ruby
241
+ # MAL:
242
+ # Gets the name.
243
+ # @return [String] the name
244
+ def name; end
245
+
246
+ # BIEN:
247
+ # @return [String] nombre completo del usuario (nombre + apellido)
248
+ def name; end
249
+ ```
250
+
251
+ **Omitir tipos** — Siempre especificá tipos en `@param` y `@return`.
252
+ ```ruby
253
+ # MAL:
254
+ # @param name el nombre
255
+
256
+ # BIEN:
257
+ # @param name [String] el nombre
258
+ ```
259
+
260
+ **Usar Boolean sin aclarar** — Ruby no tiene clase Boolean. Es una convención YARD.
261
+ ```ruby
262
+ # MAL:
263
+ # @return [TrueClass, FalseClass]
264
+
265
+ # BIEN:
266
+ # @return [Boolean] true si el usuario es admin
267
+ ```
268
+
269
+ **@return void sin explicar** — Usá void cuando el retorno no importa, no cuando no sabés.
270
+ ```ruby
271
+ # BIEN: método que muta estado, el retorno no importa
272
+ # @return [void]
273
+ def save!; end
274
+
275
+ # MAL: el retorno SÍ importa, no uses void
276
+ # @return [void]
277
+ def valid?; end
278
+ ```
279
+
280
+ ## FAQ
281
+
282
+ ### ¿Cómo documento un método que acepta **kwargs?
283
+ ```ruby
284
+ # @param name [String] el nombre
285
+ # @param opts [Hash] opciones adicionales
286
+ # @option opts [Integer] :timeout (30) segundos de espera
287
+ # @option opts [Boolean] :retry (true) reintentar en fallo
288
+ def fetch(name, **opts); end
289
+ ```
290
+
291
+ ### ¿Cómo documento un método con splat?
292
+ ```ruby
293
+ # @param args [Array<String>] lista variable de nombres
294
+ def process(*args); end
295
+ ```
296
+
297
+ ### ¿Cómo verifico la cobertura?
298
+ ```bash
299
+ bundle exec yard stats --list-undoc
300
+ ```
301
+
302
+ ### ¿Cómo genero la documentación?
303
+ ```bash
304
+ bundle exec yard doc
305
+ # Servidor local:
306
+ bundle exec yard server --reload
307
+ ```
308
+
309
+ ## Referencias
310
+
311
+ - [Tipos completos](references/tipos.md) — Catálogo exhaustivo de type specifications
@@ -0,0 +1,144 @@
1
+ # YARD — Catálogo completo de Type Specifications
2
+
3
+ Los tipos se especifican entre corchetes `[Type]` en tags como `@param`, `@return`, `@yield`, etc.
4
+
5
+ ## Tipos básicos
6
+
7
+ | Tipo | Descripción |
8
+ |---|---|
9
+ | `String` | Clase Ruby estándar |
10
+ | `Integer` | Clase Ruby estándar |
11
+ | `Float` | Clase Ruby estándar |
12
+ | `Symbol` | Clase Ruby estándar |
13
+ | `Boolean` | Convención YARD: `TrueClass` o `FalseClass` |
14
+ | `nil` | Valor nil literal |
15
+ | `void` | Sin valor de retorno significativo |
16
+ | `self` | Retorna self (métodos encadenables) |
17
+ | `true` | Literal true |
18
+ | `false` | Literal false |
19
+
20
+ ## Union types (múltiples tipos)
21
+
22
+ Separados por comas dentro de los corchetes:
23
+
24
+ ```
25
+ [String, Symbol] → String o Symbol
26
+ [Integer, nil] → Integer o nil
27
+ [String, Symbol, nil] → cualquiera de los tres
28
+ [Boolean, nil] → true, false o nil
29
+ ```
30
+
31
+ ## Parametrized types (generics)
32
+
33
+ Sintaxis: `Collection<ElementType>`
34
+
35
+ ```
36
+ [Array<String>] → array de strings
37
+ [Array<String, Symbol>] → array de strings y/o symbols
38
+ [Set<Integer>] → set de integers
39
+ [Hash<Symbol, String>] → hash con keys symbol, values string
40
+ [Hash<Symbol, Array<Integer>>] → hash con values que son arrays de integers
41
+ [Enumerator<User>] → enumerator de users
42
+ ```
43
+
44
+ ## Hash con estructura explícita
45
+
46
+ Sintaxis: `Hash{KeyType => ValueType}`
47
+
48
+ ```
49
+ [Hash{Symbol => String}] → hash con keys symbol, values string
50
+ [Hash{String => Object}] → hash con keys string, values cualquiera
51
+ [Hash{Symbol => Array<String>}] → hash con values que son arrays de strings
52
+ [Hash{String, Symbol => Integer}] → keys string o symbol, values integer
53
+ ```
54
+
55
+ ## Duck types
56
+
57
+ Prefijo `#` indica que el objeto responde a ese método:
58
+
59
+ ```
60
+ [#read] → cualquier objeto con método #read
61
+ [#call] → cualquier callable (Proc, Lambda, etc.)
62
+ [#to_s] → cualquier objeto convertible a string
63
+ [#read, #close] → debe responder a ambos métodos
64
+ [#each] → cualquier enumerable
65
+ ```
66
+
67
+ ## Order-dependent lists
68
+
69
+ Sintaxis: `Collection(Type1, Type2, ...)` — exactamente esos tipos en ese orden:
70
+
71
+ ```
72
+ [Array(String, Integer)] → array de exactamente 2 elementos: [string, integer]
73
+ [Array(String, Integer, Hash)] → array de exactamente 3 elementos en ese orden
74
+ ```
75
+
76
+ ## Combinaciones comunes
77
+
78
+ ```
79
+ [String, nil] → string nullable
80
+ [Array<String>] → array de strings
81
+ [Hash{Symbol => Object}] → options hash
82
+ [Boolean] → true/false
83
+ [void] → sin retorno
84
+ [self] → chainable
85
+ [#read, #write] → IO-like
86
+ [Integer, Float] → numeric
87
+ [String, Symbol] → string-like identifier
88
+ [Array<Hash{Symbol => String}>] → array de hashes
89
+ [Hash{Symbol => String, nil}] → hash con values nullable
90
+ ```
91
+
92
+ ## Patrones por contexto
93
+
94
+ ### Métodos de búsqueda
95
+ ```ruby
96
+ # @return [User, nil] el usuario o nil si no existe
97
+ def find(id); end
98
+
99
+ # @return [User] el usuario
100
+ # @raise [RecordNotFound] si no existe
101
+ def find!(id); end
102
+ ```
103
+
104
+ ### Métodos booleanos
105
+ ```ruby
106
+ # @return [Boolean] true si el usuario es admin
107
+ def admin?; end
108
+ ```
109
+
110
+ ### Métodos de mutación
111
+ ```ruby
112
+ # @return [void]
113
+ def save!; end
114
+
115
+ # @return [self] para encadenar
116
+ def where(conditions); end
117
+ ```
118
+
119
+ ### Métodos de colección
120
+ ```ruby
121
+ # @return [Array<User>] lista de usuarios
122
+ def all; end
123
+
124
+ # @yield [user] itera sobre cada usuario
125
+ # @yieldparam user [User]
126
+ # @return [Enumerator<User>] si no se pasa bloque
127
+ def each(&block); end
128
+ ```
129
+
130
+ ### Métodos con opciones
131
+ ```ruby
132
+ # @param opts [Hash{Symbol => Object}] opciones
133
+ # @option opts [Integer] :limit (10) máximo de resultados
134
+ # @option opts [Integer] :offset (0) desde dónde empezar
135
+ # @option opts [Symbol] :order (:asc) dirección del ordenamiento
136
+ def search(query, **opts); end
137
+ ```
138
+
139
+ ### Callbacks y Procs
140
+ ```ruby
141
+ # @param callback [Proc, #call] bloque a ejecutar
142
+ # @param filter [Proc<User, Boolean>] filtro que recibe user y retorna boolean
143
+ def on_create(callback); end
144
+ ```
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.9.0] - 2026-04-05
4
+
5
+ ### ✨ New Features
6
+ * **OTel messaging semantic conventions:** BugBunny ahora emite los campos del estándar [OpenTelemetry semantic conventions for messaging](https://opentelemetry.io/docs/specs/otel/trace/semantic-conventions/messaging/) tanto en los headers AMQP de publish/reply como en los log events del consumer. Los campos emitidos son `messaging.system` (`"rabbitmq"`), `messaging.operation` (`"publish"` / `"process"`), `messaging.destination.name`, `messaging.rabbitmq.destination.routing_key` y `messaging.message.id` (cuando hay `correlation_id`). Permite que dashboards OTel-native (Tempo, Jaeger, Honeycomb) rendericen correctamente los spans de RabbitMQ y que ExisRay los consuma automáticamente desde `properties.headers`.
7
+ * **`BugBunny::OTel` module:** Nuevo módulo con las constantes de las claves OTel y el helper `messaging_headers` para construir el hash de campos. Los headers del usuario pueden sobrescribir valores OTel como escape hatch, pero `x-http-method` sigue siendo inmutable.
8
+
9
+ ## [4.8.1] - 2026-04-04
10
+
11
+ ### Mejoras internas
12
+ * **Skills System:** Migración completa del sistema de documentación AI de `docs/` y `.claude/commands/` al nuevo estándar de skills. La documentación AI ahora se distribuye como `skill/SKILL.md` empaquetada en la gema, con 7 archivos de referencia detallados en `skill/references/`.
13
+ * **CLAUDE.md simplificado:** Se eliminaron ~230 líneas de instrucciones hardcodeadas. `CLAUDE.md` ahora delega el conocimiento a las skills en `.agents/skills/` y `skill/`.
14
+ * **Gemspec:** `documentation_uri` actualizado de `docs` a `skill/` para apuntar a la ubicación correcta de la documentación.
15
+ * **Skills de desarrollo:** Se incorporan 7 skills locales en `.agents/skills/` (documentation-writer, gem-release, quality-code, sentry, skill-builder, skill-manager, yard) con `skills.yml` como manifiesto de dependencias.
16
+
3
17
  ## [4.8.0] - 2026-04-02
4
18
 
5
19
  ### ✨ AI Documentation Standard (v4.3)