feat(gestao): adicionar 9 skills /clip-* + migrar 5 para diag tools MCP
Skills clip-* nunca tinham sido committed. Adicionadas todas (9): clip, clip-agent, clip-health, clip-instructions, clip-issue, clip-org, clip-routine, clip-skill, clip-vision. Migração para mcp__paperclip__diag_* (17 substituições em 5 skills): - clip: 5 substituições (agents_by_status, false_blockers, token burn, stuck routines, company_skills_summary) - clip-agent: 2 (agent_full_context consolida 4 passos, false_blockers) - clip-health: 8 (budget_orphans, missing_permissions, missing_heartbeat, routine_triggers_broken, false_blockers, heartbeat_token_usage, prompt_too_long_errors, stuck_routines, zombie_parents) - clip-org: 1 (agent_hierarchy) - clip-routine: 1 (routine_triggers_broken) Sem substituições (CRUD-específico sem diag_* equivalente): clip-instructions, clip-issue, clip-skill — mantêm psql. Refs: Desk #2041, mcp-paperclip feature/diagnostics-db Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,349 @@
|
||||
---
|
||||
name: clip-routine
|
||||
description: Gerir routines Paperclip — listar crons activos, ver execuções, criar/editar routines. Usar quando "clip routine", "routines clip", "crons paperclip", "automações clip".
|
||||
context: fork
|
||||
---
|
||||
|
||||
# /clip-routine — Gerir Routines Paperclip
|
||||
|
||||
## Modelo de governance (desde 29-03-2026)
|
||||
|
||||
**Todas as routines são atribuídas ao CEO.** O CEO delega pela cadeia hierárquica:
|
||||
|
||||
```
|
||||
Routine (cron trigger) → CEO avalia e delega
|
||||
→ C-Level adiciona contexto departamental
|
||||
→ Director coordena e atribui
|
||||
→ Especialista executa
|
||||
→ Resultado sobe a cadeia com síntese progressiva
|
||||
```
|
||||
|
||||
Cada routine tem no campo `description` a cadeia de delegação (ex: `CADEIA: CEO → CTO → Dir. Infraestrutura → Backup Specialist`).
|
||||
|
||||
**Regras:**
|
||||
- Novas routines devem ser SEMPRE atribuídas ao CEO
|
||||
- A cadeia de delegação deve estar explícita na descrição
|
||||
- Nunca atribuir routines directamente a especialistas — quebra a visibilidade hierárquica
|
||||
|
||||
## Dois tipos de periodicidade
|
||||
|
||||
1. **Heartbeats** — intervalos configurados via `runtime_config` dos agentes (quando acordam)
|
||||
2. **Routines** — tarefas periódicas via tabela `routines` + `routine_triggers` com cron (o que fazem ao acordar)
|
||||
|
||||
## Constantes
|
||||
|
||||
```
|
||||
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
|
||||
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
|
||||
```
|
||||
|
||||
## Tiers de heartbeat
|
||||
|
||||
| Tier | Intervalo | Uso |
|
||||
|------|-----------|-----|
|
||||
| 1 | 1h (3600s) | CEO, agentes criticos |
|
||||
| 2 | 2h (7200s) | C-Level activos |
|
||||
| 3 | 4h (14400s) | Directores |
|
||||
| 4 | 6h (21600s) | Especialistas com rotina |
|
||||
| 5 | on-demand | Especialistas reactivos (sem timer) |
|
||||
|
||||
## Modo lista (sem argumentos)
|
||||
|
||||
Listar agentes com heartbeat configurado:
|
||||
|
||||
```sql
|
||||
SELECT name, role, status,
|
||||
runtime_config->'heartbeat'->>'enabled' as hb_enabled,
|
||||
runtime_config->'heartbeat'->>'intervalSec' as hb_interval,
|
||||
last_heartbeat_at
|
||||
FROM agents
|
||||
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
AND runtime_config::text != '{}'
|
||||
AND runtime_config->'heartbeat' IS NOT NULL
|
||||
ORDER BY (runtime_config->'heartbeat'->>'intervalSec')::int ASC NULLS LAST;
|
||||
```
|
||||
|
||||
Complementar com contagem de execucoes recentes:
|
||||
|
||||
```sql
|
||||
SELECT a.name,
|
||||
COUNT(CASE WHEN hr.status = 'succeeded' THEN 1 END) as ok_24h,
|
||||
COUNT(CASE WHEN hr.status = 'failed' THEN 1 END) as fail_24h
|
||||
FROM agents a
|
||||
LEFT JOIN heartbeat_runs hr ON hr.agent_id = a.id
|
||||
AND hr.started_at > NOW() - INTERVAL '24 hours'
|
||||
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
AND a.runtime_config->'heartbeat' IS NOT NULL
|
||||
GROUP BY a.name
|
||||
ORDER BY a.name;
|
||||
```
|
||||
|
||||
## Modo ver (com nome de agente)
|
||||
|
||||
Ultimas 10 execucoes de um agente:
|
||||
|
||||
```sql
|
||||
SELECT hr.status, hr.started_at, hr.finished_at, LEFT(hr.error, 80) as erro
|
||||
FROM heartbeat_runs hr
|
||||
JOIN agents a ON hr.agent_id = a.id
|
||||
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
AND LOWER(a.name) LIKE LOWER('%{{NOME}}%')
|
||||
ORDER BY hr.started_at DESC LIMIT 10;
|
||||
```
|
||||
|
||||
## Modo criar/editar (configurar heartbeat)
|
||||
|
||||
### Activar heartbeat
|
||||
|
||||
```sql
|
||||
UPDATE agents SET runtime_config = jsonb_set(
|
||||
COALESCE(runtime_config, '{}'::jsonb),
|
||||
'{heartbeat}',
|
||||
'{"enabled": true, "intervalSec": {{INTERVALO}}, "cooldownSec": 10, "wakeOnDemand": true, "maxConcurrentRuns": 1}'::jsonb
|
||||
)
|
||||
WHERE name = '{{NOME}}'
|
||||
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
RETURNING name, runtime_config;
|
||||
```
|
||||
|
||||
Confirmar sempre com o utilizador:
|
||||
- Nome do agente
|
||||
- Intervalo (sugerir tier adequado ao role)
|
||||
- wakeOnDemand (true para a maioria)
|
||||
|
||||
### Desactivar heartbeat
|
||||
|
||||
```sql
|
||||
UPDATE agents SET runtime_config = jsonb_set(
|
||||
runtime_config,
|
||||
'{heartbeat,enabled}',
|
||||
'false'::jsonb
|
||||
)
|
||||
WHERE name = '{{NOME}}'
|
||||
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
RETURNING name, runtime_config;
|
||||
```
|
||||
|
||||
### Alterar intervalo
|
||||
|
||||
```sql
|
||||
UPDATE agents SET runtime_config = jsonb_set(
|
||||
runtime_config,
|
||||
'{heartbeat,intervalSec}',
|
||||
'{{INTERVALO}}'::jsonb
|
||||
)
|
||||
WHERE name = '{{NOME}}'
|
||||
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
RETURNING name, runtime_config;
|
||||
```
|
||||
|
||||
## Routines do projecto (tabela routines)
|
||||
|
||||
Alem dos heartbeats por agente, existem routines organizadas por projecto com cron triggers.
|
||||
|
||||
**Estado actual:** 5 routines activas no Paperclip. 9 routines anteriores foram migradas para workflows n8n em https://automator.descomplicar.pt.
|
||||
|
||||
**5 routines Paperclip:**
|
||||
- Auditoria processos e compliance (0 10 * * *)
|
||||
- Execução tarefas AikTop (*/30 * * * *)
|
||||
- Reconciliação financeira diária (0 8 * * *)
|
||||
- Varredura inteligência competitiva (0 11 * * *)
|
||||
- Monitorização workflows n8n (0 10,18 * * *) — atribuída ao COO
|
||||
|
||||
### Listar routines activas
|
||||
|
||||
```sql
|
||||
SELECT r.title, r.status, r.priority, a.name as assignee,
|
||||
rt.cron_expression, rt.enabled, rt.next_run_at
|
||||
FROM routines r
|
||||
LEFT JOIN agents a ON r.assignee_agent_id = a.id
|
||||
LEFT JOIN routine_triggers rt ON rt.routine_id = r.id
|
||||
WHERE r.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
ORDER BY r.title;
|
||||
```
|
||||
|
||||
### Ver execucoes de uma routine
|
||||
|
||||
```sql
|
||||
SELECT rr.status, rr.triggered_at, rr.completed_at, LEFT(rr.error, 80) as erro
|
||||
FROM routine_runs rr
|
||||
JOIN routines r ON rr.routine_id = r.id
|
||||
WHERE r.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
|
||||
AND LOWER(r.title) LIKE LOWER('%{{TITULO}}%')
|
||||
ORDER BY rr.triggered_at DESC LIMIT 10;
|
||||
```
|
||||
|
||||
## Modo criar routine (nova)
|
||||
|
||||
### Passo 1: Obter CEO ID
|
||||
|
||||
```sql
|
||||
SELECT id FROM agents
|
||||
WHERE name = 'CEO' AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
|
||||
```
|
||||
|
||||
### Passo 2: Obter projecto
|
||||
|
||||
```sql
|
||||
SELECT id, name FROM projects
|
||||
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
|
||||
```
|
||||
|
||||
### Passo 3: Criar routine (SEMPRE atribuída ao CEO)
|
||||
|
||||
```sql
|
||||
INSERT INTO routines (id, company_id, project_id, title, description, assignee_agent_id, priority, status, created_at, updated_at)
|
||||
VALUES (
|
||||
gen_random_uuid(),
|
||||
'ebe10308-efd7-453f-86ab-13e6fe84004f',
|
||||
'{{PROJECT_ID}}',
|
||||
'{{TITULO}}',
|
||||
'CADEIA: CEO → {{C_LEVEL}} → {{DIRECTOR}} → {{ESPECIALISTA}}. {{DESCRICAO_TAREFA}}',
|
||||
'{{CEO_ID}}',
|
||||
'{{PRIORIDADE}}',
|
||||
'active',
|
||||
NOW(), NOW()
|
||||
)
|
||||
RETURNING id, title;
|
||||
```
|
||||
|
||||
### Passo 4: Criar cron trigger
|
||||
|
||||
**CRITICO:** O kind DEVE ser `'schedule'` (nao `'cron'`). O scheduler do Paperclip so processa triggers com `kind = 'schedule'`. Tambem e OBRIGATORIO popular `next_run_at` — sem ele o scheduler ignora o trigger.
|
||||
|
||||
```sql
|
||||
-- Calcular next_run_at antes de inserir
|
||||
-- Para crons diarios (ex: 0 8 * * *), usar:
|
||||
-- (CURRENT_DATE + 1) AT TIME ZONE 'Europe/Lisbon' + INTERVAL '{{HORA}} hours'
|
||||
-- Para crons recorrentes (ex: 0 */4 * * *), calcular proximo slot
|
||||
|
||||
INSERT INTO routine_triggers (id, company_id, routine_id, kind, label, enabled, cron_expression, timezone, next_run_at, created_at, updated_at)
|
||||
VALUES (
|
||||
gen_random_uuid(),
|
||||
'ebe10308-efd7-453f-86ab-13e6fe84004f',
|
||||
'{{ROUTINE_ID}}',
|
||||
'schedule',
|
||||
'{{LABEL}}',
|
||||
true,
|
||||
'{{CRON_EXPRESSION}}',
|
||||
'Europe/Lisbon',
|
||||
{{NEXT_RUN_AT}},
|
||||
NOW(), NOW()
|
||||
)
|
||||
RETURNING id, cron_expression, next_run_at;
|
||||
```
|
||||
|
||||
**Exemplos de next_run_at:**
|
||||
- `0 8 * * *` → `(CURRENT_DATE + 1) AT TIME ZONE 'Europe/Lisbon' + INTERVAL '8 hours'`
|
||||
- `0 */6 * * *` → `date_trunc('hour', NOW()) + INTERVAL '6 hours'`
|
||||
- `0 9 * * 1` → proxima segunda-feira as 09h
|
||||
|
||||
Confirmar sempre com o utilizador: título, cadeia, cron, projecto.
|
||||
|
||||
### Diagnostico: routines que nao disparam
|
||||
|
||||
Se routines nao disparam, verificar:
|
||||
|
||||
Invocar tool MCP: `mcp__paperclip__diag_routine_triggers_broken`
|
||||
|
||||
Corrigir com:
|
||||
```sql
|
||||
UPDATE routine_triggers SET kind = 'schedule', next_run_at = {{NEXT_RUN}}, updated_at = NOW()
|
||||
WHERE id = '{{TRIGGER_ID}}';
|
||||
```
|
||||
|
||||
### Diagnostico: pipeline noticias
|
||||
|
||||
Se noticias nao estao a ser publicadas, verificar esta cadeia:
|
||||
|
||||
```
|
||||
1. Routine triggers → kind='schedule'? next_run_at populado? last_fired_at recente?
|
||||
2. CEO heartbeat → apanha a issue da routine? delega ao CGO?
|
||||
3. CGO → delega ao Intelligence Researcher?
|
||||
4. Intelligence Researcher → cria issues PUBLICAR NOTICIA? (assignee fica NULL — normal)
|
||||
5. Cron assign-copywriter.sh → atribui ao Copywriter a cada 5 min?
|
||||
6. Copywriter → acorda com wakeOnDemand? publica no WordPress?
|
||||
7. Artigo publicado → acentuacao OK? links com aspas? titulo normalizado?
|
||||
```
|
||||
|
||||
Verificar ponto a ponto com:
|
||||
```sql
|
||||
-- Ponto 1: triggers
|
||||
SELECT r.title, rt.kind, rt.next_run_at, rt.last_fired_at
|
||||
FROM routine_triggers rt JOIN routines r ON rt.routine_id = r.id
|
||||
WHERE r.title LIKE 'Pesquisa diaria%noticias%' ORDER BY rt.cron_expression;
|
||||
|
||||
-- Ponto 4-5: issues PUBLICAR NOTICIA
|
||||
SELECT i.title, i.status, a.name as assignee, i.created_at
|
||||
FROM issues i LEFT JOIN agents a ON i.assignee_agent_id = a.id
|
||||
WHERE i.title LIKE 'PUBLICAR NOTICIA%' AND i.created_at > NOW() - INTERVAL '24 hours'
|
||||
ORDER BY i.created_at DESC;
|
||||
|
||||
-- Ponto 6: Copywriter runs
|
||||
SELECT hr.status, hr.started_at FROM heartbeat_runs hr
|
||||
JOIN agents a ON hr.agent_id = a.id WHERE a.name = 'Copywriter'
|
||||
AND hr.started_at > NOW() - INTERVAL '24 hours' ORDER BY hr.started_at DESC;
|
||||
|
||||
-- Ponto 7: artigos publicados (via SSH server)
|
||||
-- wp --allow-root post list --category=noticias --date_query='{"after":"1 day ago"}' --fields=ID,post_title
|
||||
```
|
||||
|
||||
## Cadeias de delegação por área
|
||||
|
||||
| Área | Cadeia |
|
||||
|------|--------|
|
||||
| Infraestrutura/WP/Backups/SSL | CEO → CTO → Dir. Infraestrutura → Especialista |
|
||||
| Desenvolvimento/MCPs/N8N | CEO → CTO → Dir. Desenvolvimento/Automação → Especialista |
|
||||
| Email/Tickets/Processos | CEO → COO → Dir. Suporte/Operações → Especialista |
|
||||
| Financeiro/Facturação | CEO → CFO → Dir. Financeiro → Finance Manager |
|
||||
| Marketing/SEO/Conteúdo/Ads | CEO → CMO → Dir. relevante → Especialista |
|
||||
| Vendas/Leads/Propostas | CEO → CRO → Dir. Comercial → Especialista |
|
||||
| Inteligência/Pesquisa | CEO → CGO → Dir. IA/Estratégia → Especialista |
|
||||
| Analytics/Dados | CEO → CDO → Analytics Agent |
|
||||
|
||||
## Formato de output
|
||||
|
||||
Para modo lista (heartbeats):
|
||||
```
|
||||
## Heartbeats Clip — [data]
|
||||
|
||||
| Agente | Tier | Intervalo | Enabled | Último HB | OK 24h | Fail 24h |
|
||||
...
|
||||
```
|
||||
|
||||
Para modo lista (routines):
|
||||
```
|
||||
## Routines Clip — [data]
|
||||
|
||||
| Título | Cron | Assignee | Cadeia | Próximo run | Enabled |
|
||||
...
|
||||
|
||||
Total: 5 routines activas no Paperclip (4 atribuídas ao CEO, 1 ao COO) + 9 migradas para n8n
|
||||
```
|
||||
|
||||
Para modo ver:
|
||||
```
|
||||
## Routine: {{NOME}}
|
||||
|
||||
**Cadeia:** {{cadeia_delegação}}
|
||||
**Cron:** {{cron}} | **Enabled:** {{enabled}}
|
||||
**Último trigger:** {{last_triggered_at}}
|
||||
|
||||
### Últimas 10 execuções
|
||||
| Status | Triggered | Completed | Erro |
|
||||
...
|
||||
|
||||
Taxa sucesso 24h: N/N (N%)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Healing Log
|
||||
|
||||
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
|
||||
|
||||
```jsonl
|
||||
{"date":"","issue":"","fix":"","source":"user|auto"}
|
||||
```
|
||||
|
||||
*Adicionar nova linha após cada erro corrigido.*
|
||||
Reference in New Issue
Block a user