---
name: humand-pm-jira
description: Operar Jira Cloud para PMs de Humand vía el MCP de Jira de Atlassian en Cursor. Cubre operaciones básicas (listar proyectos, buscar por JQL, ver y crear issues) y el workflow "doc → cards" desde Notion, Granola o texto libre. Al crear cards infiere el tipo (Story / Bug / Task) del contenido, completa Mini App, usa "Dev Task" para subtareas, y propone siempre la card antes de crearla. Usar cuando un PM mencione Jira, pida crear/consultar cards, o quiera pasar una spec, reunión o doc a cards de Jira.
---

# Jira para PMs de Humand

Skill para que cualquier PM de Humand opere Jira Cloud desde Cursor. Cubre dos modos:

- **Operaciones básicas**: listar proyectos, buscar por JQL, ver issues, crear issues sueltos.
- **Doc → cards**: recibir un link de Notion, una reunión de Granola o texto pegado, y proponer cards listas para crear.

## Setup (una sola vez por PM)

### 1. Conexión a Jira (MCP)

La skill **no** usa credenciales en variables de entorno ni `config.json` para llamar a la API: el acceso va por el **servidor MCP de Atlassian Jira** configurado en Cursor (OAuth / token según la config del IDE).

- El **nombre exacto** del servidor MCP depende del workspace (suele ser un identificador que termina en `-jira`). Si no está claro, revisar la configuración MCP del proyecto y usar siempre ese servidor para las tools listadas abajo.
- **`cloudId`** para el sitio Humand (Jira Cloud):
  - **Recomendado:** UUID del tenant, p. ej. `8e61bfba-152b-4da6-83e1-dbb5c8e7de26` (público; se obtiene de `https://humand.atlassian.net/_edge/tenant_info` en el campo `cloudId`, o del mismo endpoint que use el equipo).
  - **Alternativa:** URL del sitio `humand.atlassian.net` — el descriptor del MCP de Atlassian en Cursor documenta `cloudId` como *UUID o URL del sitio*; si alguna tool falla con la URL, usar el UUID.
  - Si la config del MCP ya fija el sitio, seguir lo que indiquen los descriptores de tools del workspace.

**Nunca** pegar tokens, client secrets ni contenido de archivos de credenciales en el chat.

### 2. Preferencias del PM (opcional)

Para que la skill use un proyecto y board por defecto sin que el PM lo repita en cada uso, se pueden exportar (el agente puede leerlos como contexto del PM; **no** sustituyen la config del MCP):

- `JIRA_DEFAULT_PROJECT` (ej. `SQPD`, `SQCY`, `SQKO`) — clave del proyecto Jira habitual.
- `JIRA_DEFAULT_BOARD_ID` (numérico) — referencia del board para sprints; **este MCP no expone** los endpoints Agile (`board`, `sprint`) que usaba el cliente Python. Para mover issues a sprint, usar la **UI de Jira** o automatización fuera de este flujo hasta contar con una tool equivalente.

Si no se exportan, la skill pregunta al PM cuál usar.

### 3. Dependencias

Ninguna para el camino principal: **no** hace falta `pip`, `python3` ni `jira_client.py` para crear/consultar issues desde el agente.

## Conexión a Jira (MCP)

Invocar las herramientas del servidor MCP de Jira configurado en Cursor. Referencia de mapeo (mismo comportamiento que antes, otro transporte):

| Acción | Tool MCP |
|--------|----------|
| Listar proyectos visibles | `getVisibleJiraProjects` |
| Buscar por JQL | `searchJiraIssuesUsingJql` (`jql`, `maxResults` hasta 100, `fields` opcional) |
| Búsqueda en lenguaje natural (sin JQL en el pedido) | `search` |
| Ver un issue | `getJiraIssue` |
| Crear issue | `createJiraIssue` |
| Actualizar issue (p. ej. descripción tras template de Bug) | `editJiraIssue` |
| Transiciones de workflow | `getTransitionsForJiraIssue`, `transitionJiraIssue` |
| Comentar | `addCommentToJiraIssue` |
| Enlazar issues | `getIssueLinkTypes`, `createIssueLink` |
| Resolver cuenta para asignado | `lookupJiraAccountId` |
| Tipos de issue y campos requeridos | `getJiraProjectIssueTypesMetadata`, `getJiraIssueTypeMetaWithFields` |

**Uso de `cloudId` por tool (evitar confusiones):**

- **Incluir `cloudId`** en todas las tools Jira que lo marquen como requerido en el descriptor: p. ej. `getVisibleJiraProjects`, `searchJiraIssuesUsingJql`, `getJiraIssue`, `createJiraIssue`, `editJiraIssue`, transiciones, comentarios, links, lookups, metadata. Usar el UUID del tenant Humand (ver arriba) salvo que el MCP del workspace documente otro valor.
- **Tool `search` (Rovo):** en el descriptor típico del MCP, `cloudId` **no** es necesario — se deriva del token de acceso. Invocar `search` solo con `query` (y argumentos opcionales que liste el descriptor), **sin** forzar `cloudId` salvo que la versión concreta del MCP lo exija.

Antes de mergear cambios masivos, conviene validar una llamada de prueba (`getVisibleJiraProjects` o `getJiraIssue`) con el `cloudId` elegido.

## Modo 1: Operaciones básicas

### Listar proyectos

Llamar `getVisibleJiraProjects` con `cloudId`, opcionalmente `searchString`, `action`, `maxResults`.

### Buscar issues (JQL)

Llamar `searchJiraIssuesUsingJql` con `cloudId`, `jql`, y opcionalmente `maxResults` (hasta 100) y `fields`.

### Ver un issue

Llamar `getJiraIssue` con `cloudId`, `issueIdOrKey`, y opcionalmente `fields` / `responseContentFormat` (`markdown` o `adf`).

### Crear issue suelto

Llamar `createJiraIssue` con:

- `cloudId`, `projectKey`, `issueTypeName`, `summary`
- `description` si aplica
- `contentFormat`: `"markdown"` para texto enriquecido simple, o `"adf"` si hace falta ADF nativo (en ese caso `description` debe ser el **documento ADF serializado como string JSON**, según el contrato del MCP)
- `parent` si es subtarea (ver [Subtareas](#subtareas))
- **`additional_fields`** (nombre exacto **snake_case**, tal como figura en el JSON Schema del MCP de Atlassian en Cursor) para **prioridad**, **labels**, **componentes**, **Mini App** y demás custom fields (nombres según metadata del tipo de issue en ese proyecto). No usar `additionalFields` (camelCase) salvo que el descriptor del workspace muestre explícitamente ese nombre — siempre alinear con el schema de la tool instalada.

Ejemplo de prioridad y componente en `additional_fields`:

```json
{
  "priority": { "name": "Medium" },
  "components": [{ "name": "Admin" }]
}
```

Para Mini App u otros custom fields, obtener la clave (`customfield_…`) con `getJiraIssueTypeMetaWithFields` y rellenar en `additional_fields`.

## Modo 2: Doc → cards

Workflow cuando el PM pide "armame cards de este doc / reunión / spec".

### Paso 1: Obtener contenido

Preguntar al PM: "¿De dónde saco la info? Pasame un link de Notion, una reunión de Granola, o pegá el texto."

Según la fuente:

| Fuente | Tool / Acción |
|---|---|
| URL de Notion | `notion-fetch` con el ID/URL. Si es de Humand Features, extraer también propiedades (Mini App, Components, Status). |
| Reunión de Granola | `get_meeting_details` (buscar por nombre o listar recientes con `list_meetings`). Extraer action items, decisiones, next steps. |
| Texto libre | Parsear el texto pegado tal cual. |

### Paso 2: Analizar y proponer cards

Con el contenido obtenido, analizar y proponer las cards. **No asumir 1 card por documento**: si el doc tiene múltiples funcionalidades o frontend + backend separados, proponer múltiples cards.

Para cada card, decidir:

| Campo | Cómo resolverlo |
|---|---|
| **Proyecto** | Usar `JIRA_DEFAULT_PROJECT` salvo que el PM indique otro. |
| **Tipo** | Inferir del contenido: **Story** = funcionalidad nueva o cambio funcional. **Bug** = problema en algo existente. **Task** = tarea técnica sin impacto directo al usuario (refactor, migración, deuda). |
| **Summary** | Conciso, claro. Si el PM ya usó un formato previo en su proyecto (ej. `[Plataforma] Mini app \| Descripción`), respetarlo. |
| **Descripción** | Autocontenida. Ver [Reglas de descripción](#reglas-de-descripcion). |
| **Mini App** | Extraer de propiedades de Notion, del contenido, o preguntar al PM. Es un campo común a los proyectos de Humand. |
| **Componente** | Inferir de palabras del contenido ("Admin", "Backend", "Web", "Mobile"). Si no se infiere, preguntar o dejar vacío. |
| **Prioridad** | Inferir del tono/urgencia. Si no queda claro, dejar default (Medium). |

### Paso 3: Mostrar propuesta antes de crear

**Nunca crear cards sin confirmación explícita del PM.** Mostrar primero la propuesta:

```
Cards a crear en Jira (proyecto: {JIRA_DEFAULT_PROJECT}):

# | Tipo  | Summary                                       | Mini App     | Comp.
1 | Story | [Admin] Roles | Crear permiso "Definir roles" | Roles & Perm | Admin
2 | Story | [Backend] Roles | API de asignación            | Roles & Perm | Backend
3 | Task  | Migrar permisos legacy                        | Roles & Perm | Backend

Descripción de cada card incluida abajo.
```

Y junto debajo, mostrar la **descripción completa** que se va a usar para cada card (contexto + requerimientos + criterios de aceptación).

Preguntar: "¿Algo para ajustar? Confirmá, o decime qué cambiar."

El PM puede:
- Confirmar todo → ir al Paso 4.
- Pedir cambios ("la 2 que sea Task", "sacá la 3", "agregá una de Mobile") → ajustar y mostrar de nuevo.
- Cambiar campos puntuales ("la 1 con prioridad alta", "todas al sprint actual").

### Paso 4: Crear cards

Para cada card confirmada, llamar `createJiraIssue` con:

- `cloudId`: mismo valor documentado arriba en **Setup → Conexión a Jira (MCP)** (UUID del tenant recomendado)
- `projectKey`, `issueTypeName`, `summary`
- `description` con el texto acordado y `contentFormat` acorde (`markdown` o `adf` — ver [Reglas de descripción](#reglas-de-descripcion))
- `parent` si corresponde subtarea
- `additional_fields` para prioridad, componentes, Mini App (`customfield_…` según metadata), etc.

Después de crear, devolver los links:

```
Cards creadas:
1. SQXX-123 — [Admin] Roles | Crear permiso → https://humand.atlassian.net/browse/SQXX-123
2. SQXX-124 — [Backend] Roles | API de asignación → https://humand.atlassian.net/browse/SQXX-124
```

## Reglas al crear cards

### Subtareas

Al crear una subtarea (con `parent` en `createJiraIssue`), el tipo de issue se fija siempre en **Dev Task** (estándar en los proyectos de Humand). No usar "Subtask" para trabajo de desarrollo — misma regla que con el cliente Python.

### Reglas de descripción

- **Autocontenida**: la descripción debe incluir todo el contexto necesario dentro del texto (resumen, origen, acuerdos, criterios). No depender de links a Granola, Notion o Figma — no todos los lectores tienen acceso. Quien lea solo la card debe poder entender y ejecutar.
- **Formato en Jira**: con MCP, enviar cuerpo con `contentFormat: "markdown"` (flujo simple) o `contentFormat: "adf"` si se necesita control fino. Si se usa ADF, construir el documento Atlassian y pasar `description` como **string JSON** del doc, según el descriptor del MCP. Redactar en markdown con la misma estructura que antes:
  - `##` → heading 2
  - `**texto**` → negrita
  - `- ítem` → lista con viñetas
  - `- [ ] ítem` → ítem de checklist
- **Estructura típica de descripción**:
  ```
  ## Contexto
  Por qué se hace esta card. De dónde viene (resumen breve, sin link).

  ## Requerimientos
  - Punto 1
  - Punto 2

  ## Criterios de aceptación
  - [ ] Criterio 1
  - [ ] Criterio 2
  ```
- **Sin jerga si la card va a Sales/CX**: si la card es para que la lea alguien no técnico, evitar endpoints, payloads, schemas. Si es una card de ingeniería, sí se puede usar lenguaje técnico.

### Proponer antes de crear (no negociable)

No invocar `createJiraIssue` hasta tener el OK explícito del PM. Para cada card a crear, mostrar:

- **Proyecto**
- **Tipo** (Story / Bug / Task inferido)
- **Summary**
- **Mini App**
- **Componente** (si aplica)
- **Descripción** completa que se va a usar

Cuando el PM da OK (o pide ajustes), recién entonces crear.

## Reglas de comportamiento

- **Siempre escribir con tildes** en español.
- **No inventar contenido**: la info de las cards sale del documento fuente o de lo que diga el PM. Si falta algo crítico (proyecto, Mini App, prioridad, criterios), preguntar antes.
- **Links útiles**: al terminar, devolver siempre las URLs de los issues creados.
- **Bugs con template override**: si un proyecto tiene un template de Bug que pisa la descripción al crear (ej. SQCY), tras `createJiraIssue` llamar `editJiraIssue` con `fields.description` (y `contentFormat` adecuado) para restaurar la descripción correcta.

## Scripts auxiliares (opcionales)

Siguen en `skills/humand-pm-jira/scripts/` para tareas puntuales **sin** pasar por el flujo principal del agente:

- **`build_adf_from_pages.py`** — construye un ADF JSON con bullets clickables a partir de un array de `{title, url}`. Para aplicarlo en Jira vía MCP, usar la salida en `editJiraIssue` dentro de `fields.description` con `contentFormat: "adf"` (serializar el ADF como string JSON si el MCP lo exige para `description`).
  ```bash
  echo '[{"title": "Spec", "url": "https://notion.so/..."}]' \
    | python3 skills/humand-pm-jira/scripts/build_adf_from_pages.py
  ```
  Luego el agente copia el resultado al cuerpo del issue con `editJiraIssue` (no hace falta pipe a `jira_client.py`).

- **`convert_subtasks_type.py`** — convierte en masa subtareas de tipo `Subtask`/`Sub-task` a `Dev Task` para un parent dado. Soporta `--dry-run`. Sigue siendo útil como **mantenimiento por terminal** contra la API; el día a día del PM en Cursor usa MCP para lectura/escritura de issues.
  ```bash
  python3 skills/humand-pm-jira/scripts/convert_subtasks_type.py --parent SQPD-3356 --dry-run
  python3 skills/humand-pm-jira/scripts/convert_subtasks_type.py --parent SQPD-3356
  ```
  Requiere entorno Python y credenciales propias del script si se ejecuta fuera del MCP.

## Seguridad (crítico)

- **Nunca exponer credenciales** del MCP ni tokens en el chat.
- **Todo acceso a Jira desde el agente** pasa por las **tools del MCP de Jira** anteriores. No hacer requests HTTP sueltos a la API desde el chat.
- Los scripts auxiliares que aún llaman a la API no deben incrustar secretos en el repo; quien los ejecute en local usa su propia config según la documentación del script.

## Notas

- Jira Cloud sigue siendo `/rest/api/3/` por debajo; el MCP abstrae el transporte.
- **Sprints / Agile**: este conjunto de tools MCP no reemplaza `raw-get` / `raw-post` / `list-sprints` del cliente Python. Para asignar a sprint, usar la UI de Jira (o automatización dedicada) hasta disponer de una tool equivalente.
- El template `config.template.json` permanece como referencia para quien use los **scripts** auxiliares en local; **no** es el mecanismo de auth del agente con MCP.
