orquestra-mcp 1.56.0 → 1.58.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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.mjs +8 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orquestra-mcp",
3
- "version": "1.56.0",
3
+ "version": "1.58.0",
4
4
  "description": "Servidor MCP de Orquestra -- 135 tools para leer y escribir tareas, ideas, changelog, infraestructura, contenido, QA y más desde un agente de IA",
5
5
  "type": "module",
6
6
  "bin": {
package/src/server.mjs CHANGED
@@ -284,7 +284,7 @@ export function createServer() {
284
284
  registerRead(
285
285
  'list_tasks',
286
286
  '/v1/tasks',
287
- 'Lista las tareas de un proyecto de Orquestra, opcionalmente filtradas por estatus/módulo/tipo/prioridad/responsable/tag. Los filtros se combinan con AND -- pásalos en vez de traer todo el proyecto y filtrar tú mismo del lado del cliente. Por default excluye tareas cerradas (isFinal/isCancel/isArchive) -- un proyecto con historial acumula cientos, traerlas todas revienta el contexto sin que nadie las haya pedido. Si mandas statusId puntual, eso ya es una elección explícita y no se le suma este filtro (podés pedir "solo Listo"). Para historial/auditoría real, usa includeClosed=true. No incluye actividades (reuniones/llamadas/seguimientos) -- esas van con list_activities.',
287
+ 'Lista las tareas de un proyecto de Orquestra, opcionalmente filtradas por estatus/módulo/tipo/prioridad/responsable/tag/groupKey (código de agrupación, ej. V2). Cada tarea trae su groupCode si lo tiene. Los filtros se combinan con AND -- pásalos en vez de traer todo el proyecto y filtrar tú mismo del lado del cliente. Por default excluye tareas cerradas (isFinal/isCancel/isArchive) -- un proyecto con historial acumula cientos, traerlas todas revienta el contexto sin que nadie las haya pedido. Si mandas statusId puntual, eso ya es una elección explícita y no se le suma este filtro (podés pedir "solo Listo"). Para historial/auditoría real, usa includeClosed=true. No incluye actividades (reuniones/llamadas/seguimientos) -- esas van con list_activities.',
288
288
  {
289
289
  statusId: z.string().optional().describe('ID de estatus para filtrar (opcional) -- pedir un estatus puntual (incluso uno cerrado) siempre se respeta tal cual, sin el filtro default de abiertas'),
290
290
  moduleId: z.string().optional().describe('ID de módulo para filtrar (opcional)'),
@@ -293,6 +293,7 @@ export function createServer() {
293
293
  assignedTo: z.string().optional().describe('uid del responsable para filtrar (opcional)'),
294
294
  tag: z.string().optional().describe('Un tag exacto para filtrar -- solo uno, no una lista (opcional)'),
295
295
  workCategory: z.enum(WORK_CATEGORIES).optional().describe('Categoría de trabajo para filtrar (opcional): plan | build | delivery | review'),
296
+ groupKey: z.string().max(10).optional().describe('Clave de agrupación exacta (ej. "V2") para traer solo las tareas de ese grupo (groupCode V2-1, V2-2...) -- úsalo antes de crear una tarea nueva de una iniciativa para reutilizar la clave y ver cuáles existen (opcional)'),
296
297
  includeClosed: z.boolean().optional().describe('Default false -- sin esto, tareas en un estatus isFinal/isCancel/isArchive quedan afuera. Ponelo en true solo si de verdad necesitás el historial cerrado (auditoría, "¿cuándo se hizo X?").'),
297
298
  },
298
299
  (args, projectId) => ({
@@ -304,6 +305,7 @@ export function createServer() {
304
305
  assignedTo: args.assignedTo,
305
306
  tag: args.tag,
306
307
  workCategory: args.workCategory,
308
+ groupKey: args.groupKey,
307
309
  includeClosed: args.includeClosed,
308
310
  })
309
311
  )
@@ -788,6 +790,7 @@ export function createServer() {
788
790
  skipParity: z.boolean().optional().describe('true = NO sumar las plataformas hermanas al scope aunque tengan el mismo productKey. Solo cuando el trabajo es genuinamente de UNA plataforma (ej. un ajuste de Gradle que no tiene contraparte en iOS) -- no lo mandes por default. Las tareas type="bug" nunca propagan, sin necesidad de esto.'),
789
791
  parityExempt: z.boolean().optional().describe('true = este trabajo es de UNA sola plataforma y no cuenta en get_parity_summary (se pone solo cuando skipParity va con scope de una sola dist). false para volver a contarla.'),
790
792
  parityOf: z.string().optional().describe('Folio: id de la tarea ORIGEN de la que esta es la hermana para otra plataforma (ej. la versión iOS de una tarea de Android). En paridad cuentan como UN item y al cerrar esta, su plataforma queda hecha en el origen. El origen no puede ser hermana de otra. "" lo quita.'),
793
+ groupKey: z.string().max(10).optional().describe('Código de agrupación (ORQ-464): clave corta de una iniciativa que cruza módulos (ej. "V2", "LANZ"; 2-10 letras/números, empieza con letra). El server asigna groupCode = clave + número ("V2-3"), separado del moduleCode y del folio ORQ-N. Úsalo cuando la tarea es parte de una iniciativa/entrega mayor que atraviesa varios módulos; propónlo tú al armar ese trabajo. Reutiliza la MISMA clave para todas las tareas del mismo grupo y revisa con list_tasks (groupKey) las que ya existen antes de inventar una nueva. No uses la clave de un módulo (400). Sin groupKey la tarea no lleva grupo.'),
791
794
  moduleCode: z.string().max(40).optional().describe('Clave de la tarea dentro de su módulo (ej. "AUTH-3"), ADEMÁS del folio ORQ-N. NO la mandes normalmente: si el módulo tiene clave (key), el server la asigna sola. Solo para conservar la clave que ya traía de otro sistema al importar (ej. "PROJ-128" de Jira/Linear).'),
792
795
  relatedTaskId: z.string().optional().describe('"Bloqueada por" -- id de otra tarea. LEGACY desde ORQ-248: si vas a bloquear por más de una tarea, usa blockedByIds en vez de esto (relatedTaskId se sigue llenando solo, como blockedByIds[0], para paridad con iOS/Android).'),
793
796
  blockedByIds: z.array(z.string()).optional().describe('"Bloqueada por" -- ids de otras tareas (puede ser más de una). Esta tarea se muestra como bloqueada mientras ALGUNA de esas no llegue a un estatus final (isFinal). Reemplaza a relatedTaskId para bloqueos múltiples -- preferí este campo, no relatedTaskId, salvo que de verdad sea un solo bloqueador.'),
@@ -836,6 +839,7 @@ export function createServer() {
836
839
  .describe('Alcance por distribución -- usa get_parity_summary para ver el scope actual antes de editarlo'),
837
840
  parityExempt: z.boolean().optional().describe('true = este trabajo es de UNA sola plataforma y no cuenta en get_parity_summary; false para volver a contarla.'),
838
841
  parityOf: z.string().optional().describe('Folio: id de la tarea ORIGEN de la que esta es la hermana para otra plataforma (ej. la versión iOS de una tarea de Android). En paridad cuentan como UN item y al cerrar esta, su plataforma queda hecha en el origen. El origen no puede ser hermana de otra. "" lo quita.'),
842
+ groupKey: z.string().max(10).optional().describe('Código de agrupación (ORQ-464): clave corta de una iniciativa que cruza módulos (ej. "V2"; 2-10 letras/números, empieza con letra). Estable: editar la tarea sin groupKey NO cambia su groupCode ni se gasta número si mandas la misma clave. Otra clave la reasigna (número nuevo de esa clave, ej. "LANZ-1"); "" quita el código. Reutiliza la misma clave para las tareas del mismo grupo y revisa antes con list_tasks (groupKey). No uses la clave de un módulo (400).'),
839
843
  moduleCode: z.string().max(40).optional().describe('Clave de la tarea dentro de su módulo (ej. "AUTH-3"), texto libre editable a mano. "" la quita. Mover la tarea a otro módulo (moduleId) NO la cambia: la clave es estable.'),
840
844
  relatedTaskId: z.string().optional().describe('"Bloqueada por" -- id de otra tarea, o "" para quitar el bloqueo. LEGACY, ver create_task -- preferí blockedByIds.'),
841
845
  blockedByIds: z.array(z.string()).optional().describe('"Bloqueada por" -- reemplaza el array COMPLETO (no hace merge), [] quita todos los bloqueos. Ver create_task.'),
@@ -872,8 +876,8 @@ export function createServer() {
872
876
  location: z.string().optional().describe('Plataforma o lugar ("Zoom", "Oficina del cliente") o contexto libre para un seguimiento.'),
873
877
  participants: z.array(z.string()).optional().describe('Nombres libres de quienes participan (cliente, equipo) -- no uids.'),
874
878
  description: z.string().optional().describe('Notas previas.'),
875
- agendaItems: z.array(z.union([z.string(), z.object({ id: z.string().optional(), text: z.string(), group: z.string().max(60).optional(), createdAt: z.number().optional(), createdBy: z.string().optional() })])).optional()
876
- .describe('Puntos a revisar en la reunión (ej. "Revisar [[ORQ-123]]"). Lista simple, NO checklist. Cada punto puede llevar group (agrupa puntos bajo un encabezado, máx. 60 caracteres). Reemplaza la lista COMPLETA: para agregar uno, lee la actual con list_activities y manda todos, con sus id para conservarlos Y con su group -- si reenvías un punto sin group, pierde su grupo.'),
879
+ agendaItems: z.array(z.union([z.string(), z.object({ id: z.string().optional(), text: z.string(), group: z.string().max(60).optional(), resolution: z.string().max(2000).optional(), resolutionStatus: z.enum(['pendiente', 'decidido', 'pospuesto', '']).optional(), createdAt: z.number().optional(), createdBy: z.string().optional() })])).optional()
880
+ .describe('Puntos a revisar en la reunión (ej. "Revisar [[ORQ-123]]"). Lista simple, NO checklist. Cada punto puede llevar group (agrupa puntos bajo un encabezado, máx. 60 caracteres). Reemplaza la lista COMPLETA: para agregar uno, lee la actual con list_activities y manda todos, con sus id para conservarlos Y con su group -- si reenvías un punto sin group, pierde su grupo. Cada punto puede llevar además resolution (qué se decidió, máx. 2000 caracteres) y resolutionStatus ("pendiente" | "decidido" | "pospuesto"): son informativos, NO bloquean el cierre de la actividad. Si reenvías un punto con su id sin esos campos, el server conserva los guardados; manda "" para borrarlos. list_activities los devuelve en cada punto.'),
877
881
  outcome: z.string().optional().describe('Resultado / minuta corta -- qué se acordó. Llénalo al marcarla hecha.'),
878
882
  nextStep: z.string().optional().describe('Siguiente paso acordado. Si es trabajo real, además crea la tarea con create_task y liga su id en nextStepTaskId.'),
879
883
  nextStepTaskId: z.string().optional().describe('id de la tarea creada desde nextStep.'),
@@ -1041,7 +1045,7 @@ export function createServer() {
1041
1045
  registerRead(
1042
1046
  'list_activities',
1043
1047
  '/v1/activities',
1044
- 'Lista las actividades (reuniones, llamadas, seguimientos) de un proyecto de Orquestra. status "scheduled" = agenda (próximas primero), "done" = bitácora (más recientes primero); sin status trae todas. from/to acotan por día.',
1048
+ 'Lista las actividades (reuniones, llamadas, seguimientos) de un proyecto de Orquestra. status "scheduled" = agenda (próximas primero), "done" = bitácora (más recientes primero); sin status trae todas. from/to acotan por día. Cada punto de agendaItems puede traer resolution y resolutionStatus (pendiente/decidido/pospuesto).',
1045
1049
  {
1046
1050
  status: z.enum(ACTIVITY_STATUSES).optional(),
1047
1051
  type: z.enum(ACTIVITY_TYPES).optional(),