siesa-agents 2.1.57 → 2.1.58

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.
@@ -0,0 +1,131 @@
1
+ ---
2
+ name: skill-jira-ext
3
+ description:
4
+ Personaliza la sincronización base de Siesa-Agents
5
+ allowed-tools: Read, Grep, Glob, Bash, Write
6
+
7
+ storiesFolder: '_bmad-output/implementation-artifacts/'
8
+ outputFile: '_bmad-output/jira_docs/project_config.yaml'
9
+ ---
10
+
11
+ # Personalización de Sincronización Jira: Jerarquía Personalizada y Sincronización Granular
12
+
13
+ Este skill extiende la funcionalidad base de sincronización con Jira permitiendo jerarquías personalizadas y alcances de sincronización específicos.
14
+
15
+ ## Paso 1: Configuración de Jerarquía (Opcional)
16
+
17
+ **Acción Inicial:**
18
+ Antes de proceder con cualquier configuración, PREGUNTA al usuario:
19
+ "¿Deseas habilitar la configuración de Jerarquía Personalizada (Ej: Subproyecto -> Feature -> Epic)? (La jerarquía por defecto es Proyecto -> Epic -> Story)"
20
+ Opciones:
21
+ - Sí
22
+ - No
23
+
24
+ ### Opción A: Usuario responde "Sí" (Configuración de Jerarquía Personalizada)
25
+
26
+ Si el usuario selecciona "Sí", procede con las siguientes instrucciones para configurar la jerarquía extendida:
27
+
28
+ **Instrucción de Jerarquía Personalizada:**
29
+
30
+ 1. **Solicitar Datos:** El usuario DEBE proporcionar el **nombre de los Issue Type** para el Nivel 1 (Raíz) y Nivel 2 (Agrupador), así como los nombres de los issues padres e hijos.
31
+
32
+ 2. **Verificar/Almacenar Configuración:** Verifica si estos datos existen en el archivo `{outputFile}`. Si no existen, **pregunta al usuario y guárdalos en `{outputFile}` en formato YAML**. **IMPORTANTE: NO crees archivos separados como hierarchy_config.yaml. Todo debe ir en `{outputFile}`.**
33
+
34
+ Formato esperado en `{outputFile}`:
35
+ ```yaml
36
+ hierarchy_level_1_type: "NombreTipoNivel1"
37
+ hierarchy_level_1_name: "NombreIssueNivel1"
38
+ hierarchy_level_2_type: "NombreTipoNivel2"
39
+ hierarchy_level_2_name: "NombreIssueNivel2"
40
+ ```
41
+
42
+ **Contexto:** Mi Jira tiene una jerarquía personalizada. Las Épicas NO deben crearse en la raíz del proyecto, sino bajo un issue agrupador específico (Nivel 2), que a su vez cuelga de una Raíz (Nivel 1).
43
+
44
+ **Estructura requerida(Ejemplo):**
45
+ A continuacion se presenta un ejemplo de la estructura jerárquica personalizada. En este ejemplo, el issue de Nivel 1 es un `Subproyecto`, el issue de Nivel 2 es un `Feature`, y las Épicas son hijas del `Feature`.
46
+
47
+ | Nivel | Issue Type | Nombre | Relación |
48
+ |-------|------------|--------|----------|
49
+ | 1 (Raíz) | `Subproyecto` | `(revisar) MIGRACION BACK DE SINCRONIZACION A .NET - Q1` | Padre de todo |
50
+ | 2 (Agrupador) | `Feature` | `Migración del backend a .NET - V 1.0 - Q1` | Hijo del Nivel 1 |
51
+ | 3 (Sincronización) | `Epic` | *Del workflow* | Hijas del Nivel 2 |
52
+
53
+ **Acciones requeridas:**
54
+
55
+ 1. **Verificar Issue Nivel 1:** Verificar existencia en Jira. Si no existe, informar al usuario.
56
+ 2. **Verificar Issue Nivel 2:** Verificar existencia en Jira y que sea hijo del Nivel 1.
57
+ 3. **Sincronizar:** Las Épicas se crearán como hijas del issue de Nivel 2.
58
+
59
+ **Visualización(Ejmplo):**
60
+ ```
61
+ (revisar) MIGRACION BACK DE SINCRONIZACION A .NET - Q1 (Subproyecto)
62
+ └── Migración del backend a .NET - V 1.0 - Q1 (Feature)
63
+ ├── Epic 1
64
+ ├── Epic 2
65
+ └── Epic N...
66
+ ```
67
+
68
+ Una vez ejecutado, invoca el workflow (/bmad:bmm:workflows:sync-epics-stories) en consola y continúa con el proceso de sincronización con ese contexto.
69
+
70
+ ### Opción B: Usuario responde "No" (Jerarquía Estándar)
71
+
72
+ Si el usuario selecciona "No":
73
+ - Omitir toda la configuración de "Jerarquía Personalizada".
74
+ - Usar la jerarquía estándar de Jira (Proyecto -> Epic -> Story).
75
+ - Continuar inmediatamente al **Paso 2**.
76
+
77
+ ---
78
+
79
+ ## Paso 2: Extensión del Menú de Alcance (step-03-scope)
80
+
81
+ **Independientemente de la elección en el Paso 1, ESTA SECCIÓN SE DEBE EJECUTAR SIEMPRE.**
82
+
83
+ Una vez completada la configuración de jerarquía (o si fue omitida), cuando el workflow (/bmad:bmm:workflows:sync-epics-stories) llegue al paso de selección de alcance, extiende su menú.
84
+
85
+ **Contexto:** El workflow base presenta un menú con 3 opciones que operan sobre el lote completo. Esta skill extiende ese menú agregando opciones de sincronización granular (individual).
86
+
87
+ **Menú extendido:** Cuando el workflow llegue al paso 3 (Scope Selection), el menú que se presenta al usuario DEBE incluir las opciones originales MÁS las siguientes opciones adicionales:
88
+
89
+ **Select Synchronization Scope:**
90
+
91
+ 1. **Epics Only** (Syncs todas las épicas -> Jira Epics)
92
+ 2. **Stories & Tasks** (Syncs todas las stories -> Jira Stories & Sub-tasks)
93
+ 3. **Both** (Syncs Epics primero, luego Stories & Tasks)
94
+ 4. **Una o varias Épicas específicas** (Sync de una o varias épicas por nombre)
95
+ 5. **Una Historia o varias Historias específicas** (Sync de una o varias historias por nombre)
96
+
97
+
98
+ ### Lógica para las nuevas opciones:
99
+
100
+ **Opción 4 - Épica específica:**
101
+ 1. Preguntar al usuario: "¿Cuál o cuáles épicas deseas sincronizar? Indica los nombres separados por comas."
102
+ 2. El usuario debe proporcionar un listado de nombres de épicas.
103
+ Ejemplo de input: "Épica 1, Épica 3, Épica N"
104
+ 3. Validar que las épicas indicadas existen en el archivo `epics.md` del proyecto. Si alguna no existe, informar al usuario cuáles no se encontraron y volver a preguntar(Debe proporcionar la que no se encontro).
105
+ 4. Ejecutar la sincronización SOLO de las épicas indicadas (y sus historias/tareas hijas si las tienen).
106
+ 5. **Guardar Configuración:** Agregar al archivo `{outputFile}` la siguiente configuración en formato YAML (sin borrar el contenido existente):
107
+ ```yaml
108
+ target_scope: epics_specific
109
+ target_names:
110
+ - "Nombre Epica 1"
111
+ - "Nombre Epica 2"
112
+ ```
113
+
114
+ **Opción 5 - Historia específica:**
115
+ 1. Preguntar al usuario: "¿Cuál o cuáles historias deseas sincronizar? Indica los nombres separados por comas."
116
+ 2. El usuario debe proporcionar un listado de nombres de historias.
117
+ Ejemplo de input: "Historia A, Historia C, Historia M"
118
+ 3. Validar que las historias indicadas existen en `{storiesFolder}` del proyecto. Si alguna no existe, informar al usuario cuáles no se encontraron y volver a preguntar.
119
+ 4. Ejecutar la sincronización SOLO de las historias indicadas (y sus tareas/subtareas hijas si las tiene).
120
+ 5. **Guardar Configuración:** Agregar al archivo `{outputFile}` la siguiente configuración en formato YAML (sin borrar el contenido existente):
121
+ ```yaml
122
+ target_scope: stories_specific
123
+ target_names:
124
+ - "Nombre Historia A"
125
+ - "Nombre Historia B"
126
+ ```
127
+
128
+ ### Reglas de las nuevas opciones:
129
+ - Las opciones 4 y 5 siguen las mismas reglas de jerarquía (personalizada o estándar) definidas en el Paso 1.
130
+ - Si el usuario selecciona la opción 4 o 5, NO se debe sincronizar ningún otro issue fuera del seleccionado.
131
+ - Si la épica o historia indicada no se encuentra en los archivos fuente, informar al usuario y volver a mostrar el menú.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siesa-agents",
3
- "version": "2.1.57",
3
+ "version": "2.1.58",
4
4
  "description": "Paquete para instalar y configurar agentes SIESA en tu proyecto",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,51 +0,0 @@
1
- import sys
2
- import json
3
- import os
4
-
5
- try:
6
- # Leer JSON desde stdin
7
- data = json.load(sys.stdin)
8
-
9
- # Obtener información del archivo y sesión
10
- file_path = data.get('tool_input', {}).get('file_path', '')
11
- extension = os.path.splitext(file_path)[1].lower() if file_path else ''
12
- session_id = data.get('session_id', '')
13
- cwd = data.get('cwd', '')
14
-
15
- # Construir ruta relativa al log desde el cwd
16
- log_file = os.path.join(cwd, '.claude', 'logs', 'active_agents.json')
17
-
18
- # Agentes que solo pueden escribir markdown
19
- MARKDOWN_ONLY_AGENTS = ['PO', 'SM', 'PM', 'ANALYST', 'ARCHITECT', 'UX-EXPERT']
20
-
21
- # Verificar si la sesión actual tiene un agente activo
22
- if session_id and os.path.exists(log_file):
23
- try:
24
- with open(log_file, 'r', encoding='utf-8') as f:
25
- active_agents = json.load(f)
26
-
27
- # Si la sesión actual tiene un agente activo
28
- if session_id in active_agents:
29
- agent_type = active_agents[session_id]['agent']
30
-
31
- # Si el agente está en la lista de solo markdown
32
- if agent_type in MARKDOWN_ONLY_AGENTS:
33
- # Solo permitir archivos markdown
34
- if extension != '.md':
35
- result = {
36
- "hookSpecificOutput": {
37
- "hookEventName": "PreToolUse",
38
- "permissionDecision": "deny",
39
- "permissionDecisionReason": f"⛔ El agente de tipo {agent_type} solo puede redactar archivos markdown"
40
- }
41
- }
42
- print(json.dumps(result))
43
- sys.exit(0)
44
- except:
45
- # Si hay error leyendo el log, permitir la operación
46
- pass
47
-
48
- # Si no está bloqueado, permitir la operación (no imprimir nada)
49
- except Exception as e:
50
- # En caso de error, permitir la operación
51
- pass
@@ -1,67 +0,0 @@
1
- import sys
2
- import json
3
- import os
4
- from datetime import datetime
5
-
6
- try:
7
- # Leer JSON desde stdin
8
- data = json.load(sys.stdin)
9
-
10
- session_id = data.get('session_id', '')
11
- prompt = data.get('prompt', '').lower()
12
- cwd = data.get('cwd', '')
13
-
14
- # Construir ruta relativa al log desde el cwd
15
- log_file = os.path.join(cwd, '.claude', 'logs', 'active_agents.json')
16
-
17
- # Crear directorio si no existe
18
- log_dir = os.path.dirname(log_file)
19
- os.makedirs(log_dir, exist_ok=True)
20
-
21
- # Lista completa de agentes disponibles
22
- agent_identifiers = {
23
- 'agents:po': 'PO',
24
- 'agents:sm': 'SM',
25
- 'agents:pm': 'PM',
26
- 'agents:analyst': 'ANALYST',
27
- 'agents:architect': 'ARCHITECT',
28
- 'agents:dev': 'DEV',
29
- 'agents:backend': 'BACKEND',
30
- 'agents:frontend': 'FRONTEND',
31
- 'agents:qa': 'QA',
32
- 'agents:ux-expert': 'UX-EXPERT',
33
- 'agents:bmad-master': 'BMAD-MASTER',
34
- 'agents:bmad-orchestrator': 'BMAD-ORCHESTRATOR'
35
- }
36
-
37
- # Detectar si se está invocando un agente
38
- agent_type = None
39
- for identifier, agent_name in agent_identifiers.items():
40
- if identifier in prompt or f'/bmad:{identifier}' in prompt:
41
- agent_type = agent_name
42
- break
43
-
44
- if agent_type and session_id:
45
- # Leer log existente
46
- active_agents = {}
47
- if os.path.exists(log_file):
48
- try:
49
- with open(log_file, 'r', encoding='utf-8') as f:
50
- active_agents = json.load(f)
51
- except:
52
- active_agents = {}
53
-
54
- # Actualizar o agregar la sesión con el agente actual
55
- active_agents[session_id] = {
56
- 'agent': agent_type,
57
- 'timestamp': datetime.now().isoformat(),
58
- 'last_prompt': prompt[:100] # Guardar inicio del prompt para debug
59
- }
60
-
61
- # Guardar log actualizado
62
- with open(log_file, 'w', encoding='utf-8') as f:
63
- json.dump(active_agents, f, indent=2, ensure_ascii=False)
64
-
65
- except Exception as e:
66
- # En caso de error, no bloquear la operación
67
- pass