Compare commits

...

8 Commits

Author SHA1 Message Date
ealmeida 6285be6c2e 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>
2026-04-07 03:59:54 +01:00
ealmeida 2252e1c29c feat(crm-ops): adicionar skill /ticket-manage e agent support-specialist D2
Cobertura D2 Suporte elevada de 50% para 75% com novos componentes
baseados nos PROCs D2-SUP-001/002/003.

Skill /ticket-manage (crm-ops/skills/ticket-manage/SKILL.md):
- Dashboard SLA com alertas automáticos (violado/em risco/OK)
- Criação de tickets com campos correctos e confirmação de recepção
- Atribuição por prioridade e responsável (P1→imediato, P2→2h, etc.)
- Escalação com protocolo completo e notificação ao cliente
- Fecho com checklist obrigatória 7 pontos (SUP-001)
- Relatório semanal SLA com métricas por prioridade (SUP-003)

Agent support-specialist (crm-ops/agents/support-specialist.md):
- Executor D2 focado em triagem, atribuição e follow-up
- 4 workflows: triagem diária, resolver ticket, follow-up semanal, P1 crítico
- Métricas: SLA resposta >95%, resolução >90%, NPS >8, 0 violações P1
- Escala para Emanuel (P1) e D7 Tecnologia (tech complexo)

Plugin v1.2.0: adicionadas keywords suporte e sla

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 01:38:15 +01:00
ealmeida 19f89e0d69 feat(gestao): adicionar skill /monday-briefing v1.0
Briefing semanal automatizado com 4 componentes:
1. Trend Researcher — tendências de mercado via WebSearch
2. Analytics Reporter — métricas Desk CRM + Moloni + Calendar
3. Growth Hacker — 1 acção concreta com 3 passos
4. Reality Checker — contra-argumentos e pressupostos

Suporta argumentos: terminal (default), inbox, email.
Agendável via /schedule segunda 9h.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 01:30:00 +01:00
ealmeida 19da1bed48 feat(gestao): adicionar skill /hub-compile v1.0
Skill de compilação do 00-Inbox do Hub Obsidian. Classifica ficheiros
.md, gera resumos e backlinks, sugere destino e move com aprovação
explícita do utilizador. Implementa padrão Karpathy Raw→Compiler→Wiki.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 01:16:13 +01:00
ealmeida 8bf46bcaf0 heal(plugin-curator): corrigir coerência capabilities vs workflow e clarificar scoring algorithm
- Reordenar Capabilities para seguir ordem do Workflow:
  ANALYSE GAPS → SEARCH → EVALUATE → RECOMMEND → INSTALL
  (Gap Analysis passa de 4º para 1º lugar)
- Scoring: adicionar comentários inline com tipo (bool/tiered)
  e escala de cada variável; confirmar explicitamente soma 3+2+2+1+2=10
- Healing log preenchido com os 2 problemas encontrados e corrigidos

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:59:38 +01:00
ealmeida b1d31ef152 heal(gestao:reflect): corrigir inconsistências vs worklog v4.2.0
Problemas encontrados e corrigidos:
- Comandos /reflect deep e /reflect week marcados como '(exclusivo)'
  mas existem na tabela de comandos do worklog SKILL.md (linhas 24-25)
- Versão desactualizada: reflect v4.0.0 vs worklog v4.2.0
- /worklog view não referenciado no reflect (utilizador sem acesso a ver logs)

Correcções aplicadas:
- Tabela de comandos: remover '(exclusivo)', mapear equivalentes worklog
- Adicionar /reflect view → /worklog view
- Nota explicativa sobre comandos partilhados (deep/week)
- Referência ao worklog v4.2.0 no corpo da skill
- Healing log preenchido com 3 entradas dos problemas detectados
- Bump versão: v4.0.0 → v4.0.1

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:58:41 +01:00
ealmeida e2b086acbf heal(gestao): skill dual-review validada e healing log preenchido
- Frontmatter validado: name, description, context (fork) OK
- Paths judgment-frameworks verificados: global, wordpress, crm existem
- Workflow 4 passos coerente e completo
- Healing log preenchido com registo de validacao 2026-04-06
- Skill adicionada ao tracking git (era untracked)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 17:58:09 +01:00
ealmeida 24b0b68ed0 feat: adicionar plugin acidaos e skill prompt-refine
Plugin acidaos (novo):
- rust-dev: desenvolvimento Core em Rust (Axum, crates, debug compiler)
- spoke-dev: desenvolvimento Spokes em Next.js/TypeScript + Storybook
- devops: pipelines Gitea Actions CI/CD (adaptado de GitHub para Gitea)
- docs: rustdoc, TypeDoc, Outline e ADRs

dev-tools:
- prompt-refine: skill genérica de engenharia de prompts para agentes IA

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 22:11:22 +00:00
23 changed files with 4541 additions and 24 deletions
+28
View File
@@ -0,0 +1,28 @@
# Plugin: acidaos
Skills especializadas para desenvolvimento do **AcidaOS** — o sistema operativo de negócio para PMEs da Descomplicar®.
## Arquitectura
O AcidaOS usa uma arquitectura Hub-and-Spoke:
- **Core (Hub):** Rust + Axum — motor de orquestração de agentes, API gRPC/REST interna
- **Spokes:** Next.js/TypeScript — dashboards, UI, aplicações de negócio
## Skills disponíveis
| Skill | Trigger | Descrição |
|-------|---------|-----------|
| `acidaos:rust-dev` | `/rust-dev`, desenvolvimento Core | Desenvolvimento do Core em Rust (Axum, Tokio) |
| `acidaos:spoke-dev` | `/spoke-dev`, desenvolvimento Spokes | Aplicações Next.js e componentes React |
| `acidaos:devops` | `/acidaos-pipeline`, CI/CD | Pipelines Gitea Actions para o AcidaOS |
| `acidaos:docs` | `/acidaos-docs`, documentação técnica | Gerar documentação a partir do código |
## Referências
- Arquitectura: `Hub/01-Planeamento/AcidaOS/Relatorio_Arquitetura_Core.md`
- SPECs: `Hub/01-Planeamento/AcidaOS/acidaos-core/SPECs.md`
- Visão estratégica: `Hub/01-Planeamento/AcidaOS/AcidaOS_Visao-Estrategica.md`
- Repositório: Gitea `acidaos-core`, `acidaos-dashboard`
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Data**: 2026-03-12
+316
View File
@@ -0,0 +1,316 @@
---
name: devops
description: CI/CD pipelines para o AcidaOS via Gitea Actions — build, test, deploy para acidaos-core (Rust) e acidaos-dashboard (Next.js). Usar quando "pipeline acidaos", "gitea actions acidaos", "ci cd acidaos", "deploy acidaos", "workflow acidaos".
allowed-tools: Read, Write, Edit, Bash, mcp__gitea__list_repo_action_workflows, mcp__gitea__get_repo_action_workflow, mcp__gitea__create_file, mcp__gitea__update_file, mcp__memory-supabase__search_memories
---
# AcidaOS DevOps — Gitea Actions
Skill para criar e gerir pipelines CI/CD do AcidaOS via **Gitea Actions**.
> **Atenção:** O AcidaOS usa **Gitea Actions**, não GitHub Actions. A sintaxe é compatível mas o runner é self-hosted em `mcp-hub.descomplicar.pt`.
## Contexto
```
Repositórios Gitea:
acidaos-core → Rust Core
acidaos-dashboard → Next.js Dashboard
Runners:
self-hosted @ mcp-hub.descomplicar.pt
Labels: [self-hosted, linux, rust, node]
Deploy target:
EasyPanel (projectName: "descomplicar")
acidaos-core → serviceName: "acidaos-core"
acidaos-dashboard → serviceName: "acidaos-dashboard"
```
## Protocolo Inicial
```
mcp__memory-supabase__search_memories "acidaos devops pipeline"
mcp__gitea__list_repo_action_workflows <repo> # ver workflows existentes
```
---
## Pipelines Disponíveis
### 1. Core Rust — CI Pipeline
**Ficheiro:** `.gitea/workflows/ci.yml`
```yaml
name: AcidaOS Core CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
check:
name: Verificar código
runs-on: [self-hosted, linux, rust]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache Cargo
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Cargo check
run: cargo check --all-features
- name: Clippy
run: cargo clippy --all-features -- -D warnings
- name: Formatação
run: cargo fmt --all -- --check
test:
name: Testes
needs: check
runs-on: [self-hosted, linux, rust]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Cache Cargo
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Testes unitários
run: cargo test --all-features
- name: Testes de integração
run: cargo test --test '*' --all-features
env:
ACIDAOS_ENV: test
DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}
security:
name: Auditoria de segurança
runs-on: [self-hosted, linux, rust]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: cargo-audit
run: |
cargo install cargo-audit --quiet
cargo audit
```
---
### 2. Core Rust — Deploy Pipeline
**Ficheiro:** `.gitea/workflows/deploy.yml`
```yaml
name: AcidaOS Core Deploy
on:
push:
branches: [main]
tags: ['v*']
jobs:
deploy:
name: Deploy para EasyPanel
runs-on: [self-hosted, linux, rust]
environment: production
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build release
run: cargo build --release
- name: Build Docker image
run: |
docker build \
-t acidaos-core:${{ gitea.sha }} \
-t acidaos-core:latest \
.
- name: Push para registry
run: |
docker tag acidaos-core:latest \
registry.descomplicar.pt/acidaos/core:latest
docker push registry.descomplicar.pt/acidaos/core:latest
env:
DOCKER_REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
- name: Deploy via EasyPanel API
run: |
curl -X POST \
"https://easypanel.descomplicar.pt/api/deploy" \
-H "Authorization: Bearer ${{ secrets.EASYPANEL_TOKEN }}" \
-H "Content-Type: application/json" \
-d '{
"projectName": "descomplicar",
"serviceName": "acidaos-core",
"image": "registry.descomplicar.pt/acidaos/core:latest"
}'
- name: Verificar health
run: |
sleep 10
curl -f http://acidaos-core.descomplicar.pt/health || exit 1
```
---
### 3. Dashboard Next.js — CI Pipeline
**Ficheiro:** `.gitea/workflows/ci.yml` (no repo acidaos-dashboard)
```yaml
name: AcidaOS Dashboard CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint-typecheck:
name: Lint e TypeCheck
runs-on: [self-hosted, linux, node]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Instalar dependências
run: pnpm install --frozen-lockfile
- name: TypeScript check
run: pnpm tsc --noEmit
- name: ESLint
run: pnpm lint
test:
name: Testes
needs: lint-typecheck
runs-on: [self-hosted, linux, node]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Instalar dependências
run: pnpm install --frozen-lockfile
- name: Testes unitários
run: pnpm test
- name: Build de verificação
run: pnpm build
env:
ACIDAOS_CORE_URL: http://localhost:3001
e2e:
name: Testes E2E
needs: test
runs-on: [self-hosted, linux, node]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- name: Instalar dependências
run: pnpm install --frozen-lockfile
- name: Instalar Playwright
run: pnpm exec playwright install --with-deps chromium
- name: Testes E2E
run: pnpm test:e2e
env:
BASE_URL: http://localhost:3000
ACIDAOS_CORE_URL: http://localhost:3001
- name: Upload relatório E2E
if: failure()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: playwright-report/
```
---
## Gestão via MCP Gitea
```javascript
// Listar workflows de um repo
mcp__gitea__list_repo_action_workflows({ owner: "descomplicar", repo: "acidaos-core" })
// Ver runs recentes
mcp__gitea__list_repo_action_runs({ owner: "descomplicar", repo: "acidaos-core" })
// Desencadear workflow manualmente
mcp__gitea__dispatch_repo_action_workflow({
owner: "descomplicar",
repo: "acidaos-core",
workflow_id: "deploy.yml",
ref: "main"
})
// Ver logs de uma job
mcp__gitea__get_repo_action_job_log_preview({ owner: "descomplicar", repo: "acidaos-core", job_id: <id> })
```
## Segredos necessários (Gitea Secrets)
| Segredo | Usado em | Descrição |
|---------|----------|-----------|
| `TEST_DATABASE_URL` | Core CI | PostgreSQL de teste |
| `REGISTRY_TOKEN` | Core Deploy | Token registry Docker |
| `EASYPANEL_TOKEN` | Core/Dashboard Deploy | Token API EasyPanel |
## Checklist Pipeline Nova
- [ ] Workflow criado em `.gitea/workflows/`
- [ ] Runner labels correctas (`self-hosted, linux, rust` ou `node`)
- [ ] Cache Cargo/pnpm configurado
- [ ] Segredos referenciados (não hardcoded)
- [ ] Health check no deploy
- [ ] Tested com `mcp__gitea__dispatch_repo_action_workflow`
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos
+191
View File
@@ -0,0 +1,191 @@
---
name: docs
description: Gerar documentação técnica do AcidaOS a partir do código — Rust (rustdoc), TypeScript (TypeDoc), e publicar no Outline. Usar quando "documentação acidaos", "gerar docs", "rustdoc", "typedoc", "acidaos-docs", documentar código do projecto.
allowed-tools: Read, Write, Bash, mcp__gitea__get_file_content, mcp__gitea__get_dir_content, mcp__outline-api__create_document, mcp__outline-api__update_document, mcp__outline-api__search_documents, mcp__memory-supabase__search_memories
---
# AcidaOS Docs
Skill para gerar e publicar documentação técnica do AcidaOS.
## Estratégia de Documentação
| Camada | Ferramenta | Destino |
|--------|-----------|---------|
| API interna Rust | `rustdoc` + comentários `///` | `/docs` no repo |
| Componentes React | TypeDoc + Storybook | Storybook deployed |
| Arquitectura | Mermaid.js diagramas | Outline (Wiki) |
| Endpoints API | OpenAPI/Swagger | Outline (Wiki) |
| Decisões técnicas | ADRs em Markdown | Outline (Wiki) |
## Protocolo
```
mcp__memory-supabase__search_memories "acidaos documentação"
mcp__outline-api__search_documents "acidaos" # ver docs existentes
```
---
## Operações
### 1. Gerar documentação Rust (`rustdoc`)
**Verificar comentários existentes:**
```
mcp__gitea__get_dir_content acidaos-core/src/
```
**Gerar localmente (no container dev):**
```bash
cd /root/Dev/acidaos-core
cargo doc --all-features --no-deps --open
```
**Verificar cobertura de documentação:**
```bash
cargo doc --all-features 2>&1 | grep "warning: missing documentation"
```
**Template comentários Rust:**
```rust
/// # ComponenteX
///
/// Breve descrição em uma linha.
///
/// ## Descrição detalhada
///
/// Explicação mais longa do comportamento e propósito.
///
/// ## Exemplos
///
/// ```rust
/// use acidaos_core::ComponenteX;
///
/// let c = ComponenteX::new("id");
/// assert!(c.is_valid());
/// ```
///
/// ## Erros
///
/// Retorna [`Error::Init`] se a inicialização falhar.
pub struct ComponenteX { ... }
```
---
### 2. Gerar documentação TypeScript (TypeDoc)
**Verificar configuração:**
```
mcp__gitea__get_file_content acidaos-dashboard/typedoc.json
```
**Gerar (no container dev):**
```bash
cd /root/Dev/acidaos-dashboard
pnpm typedoc --out docs/api src/
```
**Template JSDoc para componentes:**
```typescript
/**
* AgentStatusCard — Mostra o estado de um agente AcidaOS
*
* @example
* ```tsx
* <AgentStatusCard
* agentId="agent-123"
* onRefresh={() => refetch()}
* />
* ```
*/
export interface AgentStatusCardProps {
/** ID único do agente no Core */
agentId: string;
/** Callback chamado ao clicar em refrescar */
onRefresh?: () => void;
}
```
---
### 3. Publicar arquitectura no Outline
**Criar/actualizar diagrama de arquitectura:**
```javascript
mcp__outline-api__create_document({
title: "AcidaOS — Arquitectura Core",
text: `
# Arquitectura AcidaOS Core
## Hub-and-Spoke
\`\`\`mermaid
graph TD
A[acidaos-dashboard] -->|API REST| B[AcidaOS Core]
B --> C[Agent Kernel]
B --> D[Security & Sandboxing]
B --> E[Memory Engine]
B --> F[Observability]
\`\`\`
## Componentes
| Componente | Linguagem | Responsabilidade |
|-----------|-----------|-----------------|
| Core | Rust | Orquestração de agentes |
| Dashboard | Next.js | Interface de utilizador |
`,
collectionId: "<acidaos-collection-id>"
})
```
---
### 4. Criar ADR (Architecture Decision Record)
**Template ADR:**
```markdown
# ADR-<NNN>: <Título da Decisão>
**Data:** YYYY-MM-DD
**Estado:** [Proposto | Aceite | Depreciado | Substituído por ADR-NNN]
## Contexto
[Situação que levou à necessidade de tomar esta decisão]
## Opções Consideradas
1. **Opção A** — descrição breve
2. **Opção B** — descrição breve
## Decisão
[Opção escolhida e porquê]
## Consequências
**Positivas:**
- [Consequência positiva]
**Negativas / Trade-offs:**
- [Limitação ou custo]
```
---
## Quality Gate de Documentação
Antes de marcar tarefa como concluída:
- [ ] Rust: zero `missing documentation` warnings em `cargo doc`
- [ ] TypeScript: TypeDoc gera sem erros
- [ ] Novos módulos têm exemplos de uso nos comentários
- [ ] Diagramas Mermaid actualizado se arquitectura mudou
- [ ] ADR criado para decisões técnicas significativas
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos
+232
View File
@@ -0,0 +1,232 @@
---
name: rust-dev
description: Desenvolvimento do AcidaOS Core em Rust — criar crates, definir endpoints Axum, debugar erros do compilador. Usar quando "rust", "axum", "cargo", "crate", "core", "acidaos core", "rust error", "borrow checker", desenvolvimento do motor central do AcidaOS.
allowed-tools: Read, Write, Edit, Bash, mcp__memory-supabase__search_memories, mcp__gitea__get_file_content, mcp__gitea__create_file, mcp__gitea__update_file
---
# AcidaOS Rust Dev
Skill para desenvolvimento do **Core do AcidaOS** em Rust.
## Contexto do Projecto
```
acidaos-core (Rust)
├── src/
│ ├── api/ ← endpoints Axum (REST/gRPC)
│ ├── kernel/ ← Agent Kernel & Scheduler
│ ├── security/ ← Sandboxing, isolamento WASM
│ ├── memory/ ← Context & Memory Engine
│ ├── registry/ ← Parsers de skills/plugins
│ ├── observability/← Logging, tracing
│ └── ethics/ ← Constitution Engine
├── crates/ ← bibliotecas internas
└── Cargo.toml
```
**Stack:** Rust stable | Axum | Tokio | Serde | Tracing | SQLx | wasmtime
## Protocolo Inicial
```
mcp__memory-supabase__search_memories "acidaos core [componente]"
mcp__gitea__get_file_content acidaos-core/Cargo.toml # verificar dependências actuais
```
---
## Operações
### 1. Criar novo crate (`/rust-create-crate`)
**Input:** Nome do crate e propósito
**Passos:**
1. Criar directório `crates/<nome>/`
2. Gerar `Cargo.toml` com dependências mínimas
3. Criar `src/lib.rs` com estrutura base
4. Adicionar ao workspace `Cargo.toml`
5. Criar `src/error.rs` com tipo de erro custom usando `thiserror`
**Template `Cargo.toml`:**
```toml
[package]
name = "acidaos-<nome>"
version = "0.1.0"
edition = "2021"
description = "<descrição>"
[dependencies]
tracing = "0.1"
serde = { version = "1", features = ["derive"] }
thiserror = "1"
tokio = { version = "1", features = ["full"] }
```
**Template `src/lib.rs`:**
```rust
//! # acidaos-<nome>
//!
//! <Descrição do módulo>
//!
//! ## Exemplo
//! ```rust
//! use acidaos_<nome>::<TipoPrincipal>;
//! ```
mod error;
pub use error::Error;
pub type Result<T> = std::result::Result<T, Error>;
```
**Template `src/error.rs`:**
```rust
use thiserror::Error;
#[derive(Debug, Error)]
pub enum Error {
#[error("Erro de inicialização: {0}")]
Init(String),
#[error("Operação não suportada: {0}")]
Unsupported(String),
}
```
---
### 2. Definir endpoint Axum (`/rust-define-api-endpoint`)
**Input:** Definição do endpoint (método, path, request/response types) de uma SPEC.md
**Template de endpoint:**
```rust
use axum::{
extract::{Path, State},
http::StatusCode,
response::Json,
routing::{get, post},
Router,
};
use serde::{Deserialize, Serialize};
use tracing::instrument;
// --- Tipos ---
#[derive(Debug, Deserialize)]
pub struct <NomeRequest> {
// campos do request
}
#[derive(Debug, Serialize)]
pub struct <NomeResponse> {
// campos do response
}
// --- Handler ---
#[instrument(skip(state))]
pub async fn <nome_handler>(
State(state): State<AppState>,
Json(req): Json<<NomeRequest>>,
) -> Result<Json<<NomeResponse>>, StatusCode> {
tracing::info!("Processando <nome>");
// lógica do handler
Ok(Json(<NomeResponse> {
// preencher response
}))
}
// --- Router ---
pub fn <nome>_router() -> Router<AppState> {
Router::new()
.route("/<path>", post(<nome_handler>))
}
```
**Princípios obrigatórios:**
- `#[instrument]` em todos os handlers (observabilidade)
- Erros retornam `StatusCode` ou tipo de erro custom (nunca `.unwrap()`)
- Estado partilhado via `State<AppState>` (não globals)
- Validação de input antes de processamento
---
### 3. Debugar erro do compilador (`/rust-debug-compiler-error`)
**Input:** Output completo de `cargo build` ou `cargo check`
**Protocolo de análise:**
1. **Identificar categoria do erro:**
| Código | Categoria | Solução típica |
|--------|-----------|----------------|
| E0382 | Move após uso | Usar `clone()` ou referências `&` |
| E0502 | Borrow conflict | Reordenar operações, usar `Arc<Mutex<>>` |
| E0308 | Type mismatch | Verificar tipos, usar `.into()` ou cast explícito |
| E0277 | Trait not impl | Implementar trait ou usar tipo diferente |
| E0499 | Multiple mut borrows | Usar `RefCell` ou reestruturar lógica |
2. **Analisar mensagem de erro completa** (incluindo `help:` e `note:`)
3. **Gerar código corrigido** com explicação da causa raiz
4. **Verificar:** `cargo check` passa antes de `cargo build`
**Padrões comuns no AcidaOS Core:**
```rust
// ❌ Move não intencional
let data = fetch_data();
process(data);
log(data); // ERRO: data foi moved
// ✅ Correcto
let data = fetch_data();
process(&data); // ou process(data.clone())
log(&data);
// ❌ Async + lifetime
async fn handler(req: &Request) -> Response { ... } // lifetime issue
// ✅ Correcto — owned ou Arc
async fn handler(req: Arc<Request>) -> Response { ... }
```
---
## Quality Gate
Antes de fazer commit:
```bash
cargo check # zero erros
cargo clippy # zero warnings
cargo test # todos os testes passam
cargo fmt --check # formatação correcta
```
**Standards:**
- Zero `unwrap()` em código de produção — usar `?` ou `expect("mensagem descritiva")`
- Funções async < 50 linhas
- `tracing::instrument` em todas as funções públicas async
- Documentação `///` em todos os tipos e funções públicas
---
## Checklist Entrega
- [ ] `cargo check` sem erros
- [ ] `cargo clippy -- -D warnings` limpo
- [ ] `cargo test` 100% pass
- [ ] Documentação `///` completa
- [ ] Observabilidade: `#[instrument]` nos handlers
- [ ] Sem `.unwrap()` em paths críticos
- [ ] CHANGELOG.md actualizado
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos
+239
View File
@@ -0,0 +1,239 @@
---
name: spoke-dev
description: Desenvolvimento de Spokes do AcidaOS em Next.js/TypeScript — criar aplicações Spoke, componentes React com testes e Storybook. Usar quando "spoke", "dashboard acidaos", "next.js acidaos", "componente react acidaos", "ts-create-spoke", "acidaos ui", "acidaos frontend".
allowed-tools: Read, Write, Edit, Bash, mcp__memory-supabase__search_memories, mcp__gitea__get_file_content, mcp__gitea__create_file, mcp__gitea__update_file
---
# AcidaOS Spoke Dev
Skill para desenvolvimento dos **Spokes do AcidaOS** em Next.js/TypeScript.
## Contexto do Projecto
Os Spokes são as aplicações de interface que comunicam com o Core via API interna:
```
acidaos-dashboard (Next.js 15 + App Router)
├── src/
│ ├── app/ ← App Router pages
│ ├── components/ ← Componentes React
│ │ ├── ui/ ← Componentes base (shadcn/ui)
│ │ └── features/ ← Componentes de funcionalidade
│ ├── lib/
│ │ ├── api/ ← Client para AcidaOS Core API
│ │ └── hooks/ ← React hooks custom
│ └── types/ ← TypeScript types partilhados
├── __tests__/ ← Jest + Testing Library
└── .storybook/ ← Storybook
```
**Stack:** Next.js 15 | TypeScript 5 | React 19 | Tailwind CSS | shadcn/ui | Vercel AI SDK | Vitest | Playwright
## Protocolo Inicial
```
mcp__memory-supabase__search_memories "acidaos spoke dashboard [componente]"
mcp__gitea__get_file_content acidaos-dashboard/package.json
```
---
## Operações
### 1. Criar nova aplicação Spoke (`/ts-create-spoke-app`)
**Input:** Nome do Spoke e propósito
**Estrutura a criar:**
```bash
# No container dev (Regra #48)
cd /root/Dev
npx create-next-app@latest acidaos-<nome> \
--typescript \
--tailwind \
--app \
--src-dir \
--import-alias "@/*" \
--no-git
```
**Ficheiros obrigatórios após scaffold:**
`src/lib/api/core-client.ts` — cliente para o Core:
```typescript
/**
* AcidaOS Core API Client
*
* @author Descomplicar® Crescimento Digital
* @link https://descomplicar.pt
*/
const CORE_API_URL = process.env.ACIDAOS_CORE_URL ?? 'http://localhost:3001';
export async function coreRequest<T>(
endpoint: string,
options?: RequestInit
): Promise<T> {
const res = await fetch(`${CORE_API_URL}${endpoint}`, {
...options,
headers: {
'Content-Type': 'application/json',
'X-AcidaOS-Version': '1',
...options?.headers,
},
});
if (!res.ok) {
throw new Error(`Core API error: ${res.status} ${res.statusText}`);
}
return res.json() as Promise<T>;
}
```
`src/types/index.ts` — tipos base:
```typescript
export interface AgentTask {
id: string;
status: 'pending' | 'running' | 'completed' | 'failed';
createdAt: string;
completedAt?: string;
}
export interface CoreHealth {
status: 'healthy' | 'degraded' | 'down';
version: string;
uptime: number;
}
```
---
### 2. Criar componente React (`/ts-create-react-component`)
**Input:** Descrição do componente (nome, props, comportamento)
**Template base — componente:**
`src/components/features/<Nome>/<Nome>.tsx`:
```typescript
/**
* <Nome> — <Descrição curta>
*
* @author Descomplicar® Crescimento Digital
*/
import { type FC } from 'react';
import { cn } from '@/lib/utils';
interface <Nome>Props {
// props do componente
className?: string;
}
export const <Nome>: FC<<Nome>Props> = ({ className }) => {
return (
<div className={cn('', className)}>
{/* conteúdo */}
</div>
);
};
<Nome>.displayName = '<Nome>';
```
**Template — teste (Vitest + Testing Library):**
`src/components/features/<Nome>/<Nome>.test.tsx`:
```typescript
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { <Nome> } from './<Nome>';
describe('<Nome>', () => {
it('renderiza sem erros', () => {
render(<<Nome> />);
// asserção específica ao componente
});
it('aceita className personalizada', () => {
const { container } = render(<<Nome> className="test-class" />);
expect(container.firstChild).toHaveClass('test-class');
});
});
```
**Template — Storybook:**
`src/components/features/<Nome>/<Nome>.stories.tsx`:
```typescript
import type { Meta, StoryObj } from '@storybook/react';
import { <Nome> } from './<Nome>';
const meta: Meta<typeof <Nome>> = {
title: 'Features/<Nome>',
component: <Nome>,
parameters: {
layout: 'centered',
},
};
export default meta;
type Story = StoryObj<typeof <Nome>>;
export const Default: Story = {
args: {},
};
```
**Criar index de exportação:**
`src/components/features/<Nome>/index.ts`:
```typescript
export { <Nome> } from './<Nome>';
export type { <Nome>Props } from './<Nome>';
```
---
## Padrões Obrigatórios
### TypeScript
- `strict: true` em `tsconfig.json` — sem `any` implícito
- Props sempre tipadas com interface exportada
- Hooks custom em `src/lib/hooks/use<Nome>.ts`
- Server Components por defeito; `'use client'` apenas quando necessário
### Performance
- `next/image` para todas as imagens
- `loading="lazy"` em componentes pesados
- `Suspense` boundaries em torno de data-fetching
- Cache de API calls com `unstable_cache` ou React cache
### Segurança
- Nunca expor `ACIDAOS_CORE_URL` no cliente (apenas server-side)
- Sanitizar input do utilizador antes de enviar ao Core
- Usar Next.js Server Actions para mutações
---
## Quality Gate
```bash
pnpm build # zero erros TypeScript
pnpm test # todos os testes passam
pnpm lint # zero erros ESLint
```
## Checklist Entrega
- [ ] Tipos TypeScript sem `any`
- [ ] Testes criados (>80% cobertura)
- [ ] Story Storybook criada
- [ ] `displayName` definido no componente
- [ ] `pnpm build` sem erros
- [ ] Client/Server components correctamente marcados
- [ ] CHANGELOG.md actualizado
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: acidaos
+28 -15
View File
@@ -18,30 +18,30 @@ Esta skill deve ser activada quando:
## Capabilities ## Capabilities
### 1. Discovery ### 1. Gap Analysis
- Mapear funcionalidades existentes
- Identificar áreas sem cobertura
- Sugerir plugins ou skills a desenvolver
- Priorizar baseado em uso real
### 2. Discovery
- Pesquisar marketplaces oficiais e comunitários - Pesquisar marketplaces oficiais e comunitários
- Avaliar relevância baseada no contexto actual - Avaliar relevância baseada no contexto actual
- Identificar plugins com funcionalidades sobrepostas - Identificar plugins com funcionalidades sobrepostas
- Detectar plugins desactualizados ou abandonados - Detectar plugins desactualizados ou abandonados
### 2. Evaluation ### 3. Evaluation
- Analisar qualidade do código (se open source) - Analisar qualidade do código (se open source)
- Verificar compatibilidade com sistema actual - Verificar compatibilidade com sistema actual
- Avaliar segurança (hooks, permissões) - Avaliar segurança (hooks, permissões)
- Medir popularidade e manutenção activa - Medir popularidade e manutenção activa
### 3. Installation Management ### 4. Installation Management
- Instalar plugins recomendados - Instalar plugins recomendados
- Configurar hooks e MCPs do plugin - Configurar hooks e MCPs do plugin
- Resolver conflitos com plugins existentes - Resolver conflitos com plugins existentes
- Gerir actualizações e rollbacks - Gerir actualizações e rollbacks
### 4. Gap Analysis
- Mapear funcionalidades existentes
- Identificar áreas sem cobertura
- Sugerir plugins ou skills a desenvolver
- Priorizar baseado em uso real
## Marketplaces Conhecidos ## Marketplaces Conhecidos
| Marketplace | URL | Tipo | | Marketplace | URL | Tipo |
@@ -56,12 +56,12 @@ Esta skill deve ser activada quando:
``` ```
score = 0 score = 0
score += keyword_match * 3 # Max 3 score += keyword_match * 3 # Max 3 (bool: 0|1)
score += category_align * 2 # Max 2 score += category_align * 2 # Max 2 (bool: 0|1)
score += popularity # Max 2 (>1k stars) score += popularity # Max 2 (tiered: 0=<100 stars, 1=100-1k, 2=>1k)
score += recent_update # Max 1 (<30 days) score += recent_update # Max 1 (bool: 1 se último commit <30 dias)
score += no_conflicts * 2 # Max 2 score += no_conflicts * 2 # Max 2 (bool: 0|1)
# Total max: 10 # Total max: 3 + 2 + 2 + 1 + 2 = 10
``` ```
## Workflow ## Workflow
@@ -97,3 +97,16 @@ Assistant: [Activa plugin-curator]
- NUNCA instalar plugins de fontes não verificadas - NUNCA instalar plugins de fontes não verificadas
- Verificar SEMPRE conflitos antes de instalar - Verificar SEMPRE conflitos antes de instalar
- Manter registo de todos os plugins avaliados - Manter registo de todos os plugins avaliados
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-06","issue":"Capabilities ordenadas por ordem diferente do Workflow (Discovery 1º, Gap Analysis 4º) — incoerência com fluxo ANALYSE GAPS → SEARCH → EVALUATE → RECOMMEND → INSTALL","fix":"Reordenadas Capabilities para seguir ordem do Workflow: 1.Gap Analysis 2.Discovery 3.Evaluation 4.Installation Management","source":"auto"}
{"date":"2026-04-06","issue":"Scoring algorithm: score += popularity sem multiplicador e sem documentar escala — ambíguo se max é 1 (bool) ou 2 (tiered)","fix":"Adicionados comentários inline a todos os campos: tipo (bool/tiered), escala e critério. Confirmada soma: 3+2+2+1+2=10.","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+4 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "crm-ops", "name": "crm-ops",
"description": "CRM operations, sales management, leads, customers, estimates, invoices, tickets and expense tracking with Desk CRM. Backed by NotebookLM notebooks.", "description": "CRM operations, sales management, leads, customers, estimates, invoices, tickets and expense tracking with Desk CRM. Backed by NotebookLM notebooks.",
"version": "1.1.0", "version": "1.2.0",
"author": { "author": {
"name": "Descomplicar - Crescimento Digital", "name": "Descomplicar - Crescimento Digital",
"url": "https://descomplicar.pt" "url": "https://descomplicar.pt"
@@ -14,6 +14,8 @@
"leads", "leads",
"facturacao", "facturacao",
"tickets", "tickets",
"orcamento" "orcamento",
"suporte",
"sla"
] ]
} }
+184
View File
@@ -0,0 +1,184 @@
---
name: support-specialist
description: >
Especialista de suporte D2 para triagem, atribuição e follow-up de tickets. Executor
autónomo baseado nos PROCs D2-SUP-001/002/003. Usar para: triagem tickets, atribuição
por prioridade SLA, follow-up clientes, verificação SLA, escalação automática, relatório
suporte, gestão tickets Desk CRM.
role: Especialista de Suporte D2
domain: Support, CRM
model: sonnet
tools: Read, Glob, Grep, ToolSearch
primary_mcps:
- desk-crm-v3
recommended_mcps:
- memory-supabase
- mcp-time
primary_skills:
- ticket-manage
- ticket
- ticket-triage
- crm
recommended_skills:
- today
- worklog
desk_project: 65
tags:
- agent
- suporte
- d2
- tickets
- sla
- desk-crm
version: "1.0"
status: active
quality_score: 75
compliance:
sacred_rules: true
data_sources: true
reports_to: Emanuel Almeida
collaborates_with:
- sales-manager
- lead-qualifier
escalates_to:
- Emanuel Almeida (P1 crítico, SLA violado)
- D7 Tecnologia (problemas técnicos complexos)
created: "2026-04-07"
updated: "2026-04-07"
author: "Descomplicar®"
---
# Support Specialist Descomplicar
Especialista de suporte D2 responsável pela triagem, atribuição e follow-up de tickets no Desk CRM. Opera de forma autónoma seguindo os PROCs D2 Suporte (SUP-001, SUP-002, SUP-003).
## System Prompt
Você é o especialista de suporte D2 da Descomplicar®. A sua missão é garantir que todos os tickets de suporte são tratados com profissionalismo, dentro dos SLAs definidos, e que os clientes recebem respostas claras e soluções eficazes.
### Regras Obrigatórias (checklist antes de agir)
- [ ] **SLA Primeiro**: Verificar sempre o estado SLA antes de responder (`/ticket-manage sla`)
- [ ] **Contexto Cliente**: Consultar histórico do cliente via `/crm` antes de responder
- [ ] **Checklist Fecho**: NUNCA fechar ticket sem checklist 100% completa (`/ticket-manage close`)
- [ ] **Causa Raiz**: Identificar causa real, não só sintoma
- [ ] **Confirmar Resolução**: Aguardar confirmação do cliente antes de fechar
- [ ] **Registar Lições**: Documentar novos problemas na KB
### Prioridades de Actuação
1. **P1 Crítico** — Acção imediata (<30min). Notificar Emanuel se não resolvido em 1h
2. **P2 Funcional** — Resposta em 2h. Escalar para D7 se não resolvido em 12h
3. **P3 Dúvida** — Resposta em 4h. Consultar KB/WikiJS antes de responder
4. **P4 Melhoria** — Registar para sprint. Confirmar ao cliente o registo
### Output Format Padrão
```markdown
## Ticket #X — [Assunto]
### Estado
- **Prioridade:** P[N] [Nome]
- **Cliente:** [Nome] ([email])
- **Aberto há:** Xh
- **SLA:** [OK/EM RISCO/VIOLADO]
### Acção Tomada
[Descrição do que foi feito]
### Próximo Passo
[Acção seguinte + responsável + prazo]
```
## Responsabilidades
- Triagem diária de tickets novos (classificar P1-P4 por impacto)
- Atribuição correcta por área: técnica → D7, billing → D3, comercial → D1
- Primeira resposta dentro do SLA em todos os tickets
- Follow-up proactivo em tickets P1/P2 sem resposta do cliente >24h
- Verificação semanal de cumprimento SLA e relatório (`/ticket-manage report`)
- Fecho com checklist obrigatória e registo de lições aprendidas
## Workflows
### Workflow 1: Triagem Diária
```
1. /ticket-manage → Ver dashboard SLA + tickets em risco
2. Para cada ticket NOVO:
a. Classificar prioridade (P1-P4) por impacto
b. /ticket-manage assign <id> → Atribuir a responsável
c. Enviar confirmação de recepção ao cliente
3. Para cada ticket EM RISCO:
a. Avaliar estado de resolução
b. Escalar se necessário: /ticket-manage escalate <id>
4. Para cada ticket VIOLADO:
a. Notificar Emanuel imediatamente (P1) ou criar alerta (P2/P3)
```
### Workflow 2: Resolver Ticket
```
1. /ticket view <id> → Ler histórico completo
2. /crm → Verificar contexto do cliente (projectos, histórico)
3. Diagnosticar: reproduzir problema, consultar KB
4. Se técnico WP/servidor: delegar para D7 (/ticket-manage escalate)
5. Se billing: verificar /billing-check
6. Aplicar solução e testar
7. Responder ao cliente com solução + passos prevenção
8. Aguardar confirmação → /ticket-manage close <id>
```
### Workflow 3: Follow-up Semanal
```
1. Tickets no estado "Resolvido" há >3 dias → Contactar cliente
2. Verificar NPS respostas dos últimos 7 dias
3. /ticket-manage report → Gerar relatório SLA semanal
4. Se cumprimento <90% em qualquer prioridade → Criar tarefa melhoria no Desk
5. Registar acções correctivas como comentário no ticket #65
```
### Workflow 4: Escalação P1
```
1. Ticket P1 identificado → Acção imediata
2. Tentar resolução directa (máx 30min)
3. Se não resolvido: /ticket-manage escalate para D7
4. Notificar Emanuel: comentário interno + urgência
5. Acompanhar até resolução — actualizações cada 30min
```
## Knowledge Sources
### Referências PROCs (Consultar SEMPRE)
```
Read: /media/ealmeida/Dados/Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-001-Atendimento-Cliente.md
Read: /media/ealmeida/Dados/Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-002-Ticketing-Workflow.md
Read: /media/ealmeida/Dados/Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-003-SLA-Management.md
```
### Desk CRM (Dados Reais)
```
mcp__desk-crm-v3__get_tickets({ status: [1,2,3] })
mcp__desk-crm-v3__get_ticket({ ticket_id: id })
mcp__desk-crm-v3__reply_ticket({ ticket_id: id, message: html, internal: false })
mcp__desk-crm-v3__close_ticket({ ticket_id: id })
```
## Métricas de Sucesso
| Métrica | Meta |
|---------|------|
| SLA resposta cumprido | >95% |
| SLA resolução cumprido | >90% |
| Resolução 1º contacto | >60% |
| NPS médio | >8/10 |
| Tickets P1 violados | 0/semana |
## Colaboração
- **Reporta a**: Emanuel Almeida
- **Colabora com**: sales-manager (tickets pós-venda), lead-qualifier (clientes novos)
- **Escalar para**: Emanuel (P1 crítico, SLA violado), D7 Tecnologia (tech complexo)
+319
View File
@@ -0,0 +1,319 @@
---
name: ticket-manage
description: >
Gestão completa do ciclo de vida de tickets D2 Suporte: criar com campos correctos, atribuir
por prioridade e SLA, escalar quando SLA em risco, fechar com checklist obrigatória. Baseado
em PROC-D2-SUP-001 (Atendimento), SUP-002 (Ticketing Workflow) e SUP-003 (SLA Management).
Usar para: gestão ticket, SLA check, escalar suporte, fechar ticket, atribuir prioridade.
disable-model-invocation: true
---
# /ticket-manage v1.0 — Gestão Integrada de Suporte D2
Workflow completo de gestão de tickets segundo os PROCs D2 Suporte (SUP-001/002/003).
Complementa `/ticket` (operações básicas) com gestão de SLA, checklist e escalação automática.
---
## Comandos
| Comando | Função |
|---------|--------|
| `/ticket-manage` | Dashboard SLA + tickets em risco |
| `/ticket-manage new` | Criar ticket com campos correctos |
| `/ticket-manage assign <id>` | Atribuir por prioridade e SLA |
| `/ticket-manage sla` | Ver estado SLA todos os tickets abertos |
| `/ticket-manage escalate <id>` | Escalar com protocolo SUP-001 |
| `/ticket-manage close <id>` | Fechar com checklist obrigatória |
| `/ticket-manage report` | Relatório semanal SLA (SUP-003) |
---
## Prioridades e SLAs (SUP-003)
| Prioridade | Código | Primeira Resposta | Resolução | Escalação |
|------------|--------|-------------------|-----------|-----------|
| Crítico | P1 | <1h | <4h | Imediata D7 |
| Funcional | P2 | <2h | <24h | Após 12h sem resolução |
| Dúvida | P3 | <4h | <48h | Após 24h sem resolução |
| Melhoria | P4 | <24h | Próximo sprint | N/A |
**Mapping Desk CRM:**
| Desk Priority ID | Correspondência |
|-----------------|----------------|
| 4 — Urgente | P1 Crítico |
| 3 — Alta | P2 Funcional |
| 2 — Normal | P3 Dúvida |
| 1 — Baixa | P4 Melhoria |
---
## `/ticket-manage` — Dashboard SLA
```
1. mcp__desk-crm-v3__get_tickets({ status: [1,2,3] })
2. Para cada ticket:
a. Calcular tempo decorrido desde criação/última resposta
b. Comparar com SLA da prioridade
c. Classificar: OK / EM RISCO (<25% SLA restante) / VIOLADO (SLA excedido)
3. Mostrar dashboard agrupado por estado SLA
```
**Output:**
```markdown
## 🎫 Dashboard Suporte — [DATA]
### 🔴 SLA Violado (N)
| # | Prioridade | Cliente | Assunto | Há | SLA |
|---|-----------|---------|---------|-----|-----|
| #234 | P1 Crítico | ClienteA | Downtime servidor | 6h | <4h ❌ |
### 🟠 Em Risco (<25% restante)
| # | Prioridade | Cliente | Assunto | Há | Restante |
|---|-----------|---------|---------|-----|---------|
| #236 | P2 Funcional | ClienteB | Erro login | 20h | 4h ⚠️ |
### 🟢 Dentro do SLA
| # | Prioridade | Cliente | Assunto | Há |
|---|-----------|---------|---------|-----|
| #238 | P3 Dúvida | ClienteC | Como configurar X | 2h |
---
**Resumo:** X violados | Y em risco | Z OK | Total: W tickets abertos
```
---
## `/ticket-manage new` — Criar Ticket Correcto
```
1. Recolher campos obrigatórios:
- Cliente: pesquisar mcp__desk-crm-v3__get_customers({ search: nome }) OU perguntar ID
- Assunto: descrever o problema
- Descrição completa
- Prioridade: perguntar (P1/P2/P3/P4) ou sugerir baseado no assunto
- Departamento: 1=Suporte Técnico, 2=Vendas, 3=Facturação, 4=Geral
- Origem: Desk CRM, email, WhatsApp
2. Confirmar antes de criar:
"Criar ticket P[X] para [Cliente] — [Assunto]? [Sim/Cancelar]"
3. mcp__desk-crm-v3__create_ticket({
client_id: id,
department_id: dept_id,
priority: priority_id, // 4=Urgente, 3=Alta, 2=Normal, 1=Baixa
subject: assunto,
message: "<p>[descrição detalhada]</p><p><strong>Origem:</strong> [origem]</p>"
})
4. Enviar confirmação de recepção ao cliente (se externo):
- P1/P2: "Prioridade máxima. Analisando agora. Actualização em 30min/2h."
- P3: "Recebemos. Resposta em 4h."
- P4: "Registado para próximo sprint."
5. Output: "Ticket #X criado [P1-Crítico] | SLA: 1h resposta / 4h resolução"
```
---
## `/ticket-manage assign <id>` — Atribuir por Prioridade
```
1. mcp__desk-crm-v3__get_ticket({ ticket_id: id })
2. Determinar responsável baseado em categoria:
- Técnico (WP, servidor, código) → D7 Tecnologia
- Billing, factura → D3 / Emanuel
- Comercial, proposta → D1
- Geral → Support Specialist (staff_id: 25)
3. Se P1: notificar imediatamente (comentário interno + /task urgente)
4. Registar atribuição como comentário interno:
mcp__desk-crm-v3__reply_ticket({
ticket_id: id,
message: "<p>Atribuído: [Responsável] | SLA: [prazo] | Prioridade: [P1-P4]</p>",
internal: true
})
5. Output: "Ticket #X atribuído a [Responsável] | SLA expira: [data/hora]"
```
---
## `/ticket-manage sla` — Estado SLA Completo
```
1. Recolher todos tickets abertos (status 1, 2, 3)
2. Para cada ticket calcular:
- tempo_decorrido = agora - created_at
- sla_limite = por prioridade (1h/2h/4h/24h para primeira resposta)
- percentagem_usada = tempo_decorrido / sla_limite × 100
3. Agrupar: VIOLADO (>100%), EM RISCO (75-100%), OK (<75%)
4. Highlight P1 e P2 com aviso especial
```
**Alertas automáticos a gerar:**
```
P1 sem resposta >30min → "⚠️ CRÍTICO: Ticket #X P1 excede 30min. Acção imediata."
P2 sem resposta >2h → "⚠️ ALERTA: Ticket #X P2 em risco. Re-atribuir?"
Qualquer ticket >48h → "⏰ Ticket #X aberto há +48h. Revisar."
```
---
## `/ticket-manage escalate <id>` — Escalação com Protocolo
```
1. mcp__desk-crm-v3__get_ticket({ ticket_id: id })
2. Determinar destino de escalação:
- Tech complexo (WP, servidor) → D7 Tecnologia
- Billing → D3 Facturação
- Dev customizado → Project Manager
3. Criar tarefa Desk CRM com contexto completo:
mcp__desk-crm-v3__create_task({
name: "[ESCALADO] Ticket #X: [Assunto]",
description: "<h4>Escalado de Ticket #X</h4>
<p><strong>Cliente:</strong> [nome]</p>
<p><strong>Problema:</strong> [descrição]</p>
<p><strong>Tentativas anteriores:</strong> [o que foi tentado]</p>
<p><strong>SLA original:</strong> [prazo]</p>
<p><strong>Motivo escalação:</strong> [razão]</p>",
priority: 3,
assignees: [1]
})
4. Informar cliente:
mcp__desk-crm-v3__reply_ticket({
ticket_id: id,
message: "<p>Olá [Nome],</p>
<p>A situação é mais complexa e foi escalada para a equipa especialista.
Prazo estimado: 24-48h.</p>
<p>Pedimos desculpa pela demora.</p>"
})
5. Nota interna com motivo detalhado
6. Output: "Ticket #X escalado → Tarefa #Y | Dept: [destino] | ETA: [prazo]"
```
---
## `/ticket-manage close <id>` — Fecho com Checklist Obrigatória
```
1. mcp__desk-crm-v3__get_ticket({ ticket_id: id })
2. Executar checklist SUP-001 (OBRIGATÓRIO — 100% antes de fechar):
```
### Checklist de Fecho (SUP-001)
- [ ] Solução aplicada e testada
- [ ] Explicação clara da solução enviada ao cliente
- [ ] Causa raiz identificada (não só sintoma)
- [ ] Passos de prevenção comunicados
- [ ] Cliente confirmou resolução ("Resolvido? Feedback?")
- [ ] Lições aprendidas registadas (se novo problema)
- [ ] Follow-up 3 dias agendado (se P1/P2)
```
3. Se checklist incompleta → NÃO fechar, listar pendentes
4. Se 100% → fechar:
mcp__desk-crm-v3__reply_ticket({
ticket_id: id,
message: "<p>Olá [Nome],</p>
<p>Confirmamos que a situação foi resolvida.</p>
<p><strong>Solução:</strong> [explicação]</p>
<p><strong>Prevenção:</strong> [dica]</p>
<p>Obrigado pelo contacto. Se precisar de algo, estamos disponíveis.</p>
<p>Nota 1-10 sobre o suporte?</p>"
})
mcp__desk-crm-v3__close_ticket({ ticket_id: id })
5. Output: "Ticket #X fechado ✓ | Checklist: 7/7 | [Data fecho]"
```
---
## `/ticket-manage report` — Relatório SLA Semanal (SUP-003)
```
1. Recolher tickets dos últimos 7 dias
2. Calcular por prioridade:
- % tickets que cumpriram SLA de resposta
- % tickets que cumpriram SLA de resolução
- Tempo médio de resposta e resolução
3. Identificar violações e categorizar causas
4. Comparar com semana anterior
```
**Output:**
```markdown
## Relatório SLA Semanal — [DD-MM-YYYY a DD-MM-YYYY]
### Cumprimento SLA (Meta: >90%)
| Prioridade | Tickets | SLA Resposta | SLA Resolução | Violações |
|-----------|---------|-------------|--------------|-----------|
| P1 Crítico | 2 | 100% ✅ | 50% ⚠️ | 1 |
| P2 Funcional | 8 | 87.5% ⚠️ | 100% ✅ | 1 |
| P3 Dúvida | 15 | 93.3% ✅ | 86.7% ⚠️ | 2 |
| P4 Melhoria | 3 | 100% ✅ | N/A | 0 |
### Top 3 Tickets Mais Lentos
1. #X — [Assunto] — P2 — 36h — causa: dependência externa D7
2. #Y — [Assunto] — P3 — 52h — causa: complexidade técnica
3. #Z — [Assunto] — P1 — 5h30 — causa: falta de informação cliente
### Acções Correctivas
- [ ] P2 cumprimento <90% → Revisão processo atribuição automática
```
---
## Referências PROCs
| PROC | Ficheiro Hub |
|------|-------------|
| SUP-001 Atendimento | `Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-001-Atendimento-Cliente.md` |
| SUP-002 Ticketing | `Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-002-Ticketing-Workflow.md` |
| SUP-003 SLA | `Hub/06-Operacoes/Procedimentos/D2-Suporte/PROC-D2-SUP-003-SLA-Management.md` |
---
## Anti-Patterns
- **NUNCA** fechar sem checklist 100% completa
- **NUNCA** escalar sem informar o cliente
- **NUNCA** ignorar tickets P1 >30min
- **NUNCA** resolver sintoma sem identificar causa raiz
---
## Integração com Outras Skills
| Skill | Quando usar |
|-------|-------------|
| `/ticket` | Operações básicas (view, reply) |
| `/ticket-triage` | Triagem automática SPAM/facturas |
| `/crm` | Contexto cliente 360° |
| `/today` | Dashboard diário com SLA alerts |
---
## Changelog
### v1.0.0 (07-04-2026)
- Versão inicial baseada em SUP-001, SUP-002, SUP-003
- Dashboard SLA com alertas automáticos
- Criação com campos obrigatórios e confirmação recepção
- Checklist fecho obrigatória 7 pontos
- Protocolo escalação com contexto completo
- Relatório semanal SLA
---
*Skill v1.0.0 | 07-04-2026 | Descomplicar® | Baseado em PROCs D2-SUP-001/002/003*
---
## 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.*
+132
View File
@@ -0,0 +1,132 @@
---
name: prompt-refine
description: Transforma um pedido vago em prompt de excelência — especificação detalhada, inequívoca e estruturada para agentes de IA. Usar quando "refinar prompt", "melhorar prompt", "engenharia de prompts", "prompt para agente", "estruturar instrução IA", "prompt engineering".
allowed-tools: Read, Write, mcp__memory-supabase__search_memories
---
# /prompt-refine — Engenharia de Prompts
Transforma um pedido em linguagem natural num **prompt de excelência** pronto para ser executado por outro agente de IA.
## Quando Usar
- Pedido do utilizador é vago ou incompleto
- Preparar instrução para um agente especializado
- Criar template reutilizável para uma tarefa recorrente
- Garantir qualidade máxima de input antes de executar
## Protocolo
### 1. Pesquisar contexto relevante
```
mcp__memory-supabase__search_memories "<palavras-chave do pedido>"
```
Verificar se há padrões ou decisões anteriores relacionadas.
### 2. Analisar o pedido original
Identificar:
- **O quê** — resultado final esperado
- **Para quê** — objectivo ou problema a resolver
- **Quem** — agente ou utilizador que vai executar
- **Restrições** — limitações técnicas, de formato ou de negócio
- **Lacunas** — o que está implícito mas não dito
Se faltar informação crítica → perguntar antes de estruturar.
### 3. Estruturar o prompt de excelência
Usar este template como base:
```markdown
## Função
[Quem é / que papel assume o agente executante]
## Objectivo
[O que deve ser produzido — resultado concreto e mensurável]
## Contexto
[Informação de fundo necessária para compreender o pedido]
## Requisitos
- [Requisito 1 — obrigatório]
- [Requisito 2 — obrigatório]
- [Restrição ou critério de qualidade]
## Input
[Descrição do que o agente recebe como entrada]
## Output esperado
[Formato, estrutura e conteúdo exacto do resultado]
## Exemplos
### Exemplo positivo (fazer)
[Exemplo concreto do resultado desejado]
### Exemplo negativo (não fazer)
[Exemplo do que deve ser evitado]
## Critérios de sucesso
- [ ] Critério 1
- [ ] Critério 2
```
### 4. Rever antes de entregar
Verificar checklist:
- [ ] Sem ambiguidades — cada instrução tem um único significado possível
- [ ] Completo — nenhuma informação crítica em falta
- [ ] Accionável — o agente pode executar sem fazer suposições
- [ ] Testável — é possível verificar se o output é correcto
- [ ] Conciso — sem redundâncias ou instruções contraditórias
### 5. Entregar com explicação
Apresentar:
1. **Prompt refinado** (em bloco de código copiável)
2. **Decisões tomadas** — o que foi inferido vs. o que estava explícito
3. **Questões em aberto** — se houver ambiguidades que o utilizador deve resolver
## Exemplos de Transformação
### Input vago
> "Cria um agente que analisa clientes"
### Output refinado
```markdown
## Função
Analista de CRM especializado em classificação de clientes
## Objectivo
Gerar um relatório de segmentação de clientes com base em histórico de compras
e interacções, identificando os segmentos de alto, médio e baixo valor.
## Contexto
Base de dados Desk CRM com clientes activos nos últimos 12 meses.
Acesso via mcp__desk-crm-v3__get_customers e mcp__desk-crm-v3__get_payments.
## Requisitos
- Segmentar em 3 níveis: Alto Valor (>5000EUR/ano), Médio (1000-5000EUR), Baixo (<1000EUR)
- Incluir número de projectos activos por cliente
- Formato: tabela Markdown ordenada por valor decrescente
## Input
Lista de IDs de clientes ou "todos" para analisar base completa
## Output esperado
Tabela com: ID, Nome, Segmento, Volume Anual (EUR), Projectos Activos, Última Interacção
```
## Padrões de Qualidade
| Característica | Mau prompt | Bom prompt |
|---|---|---|
| Especificidade | "Analisa dados" | "Calcula receita mensal por cliente em EUR para Q1 2026" |
| Formato output | "Devolve resultados" | "Tabela Markdown com colunas: ID, Nome, Valor, Delta%" |
| Critério sucesso | "Deve ser bom" | "Score de satisfação >85% em teste com 3 utilizadores reais" |
| Contexto | Nenhum | "Sistema usa Desk CRM v3, moeda EUR, fuso Europe/Lisbon" |
---
**Versão**: 1.0.0 | **Autor**: Descomplicar® | **Plugin**: dev-tools
+340
View File
@@ -0,0 +1,340 @@
---
name: clip-agent
description: Gerir agente Paperclip individual — estado, config, AGENTS.md, histórico runs, issues. Aceita nome como argumento. Usar quando "clip agent", "agente clip", "ver agente", "estado do CTO".
context: fork
---
# /clip-agent — Gerir Agente Paperclip
Aceita argumento: nome do agente (ex: `/clip-agent CTO`).
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
AGENTS_PATH: /media/ealmeida/Dados/Hub/04-Stack/02.06-Clip/agents/
```
## Procedimento
### Passo 1: Contexto completo do agente
Invocar tool MCP: `mcp__paperclip__diag_agent_full_context(agent_name="{{NOME}}")`
Esta tool retorna config, últimas runs, membership, permissões e tokens — cobre os Passos 1, 3, 6, 7 e 7b de uma só vez. Se multiplos resultados, mostrar lista e pedir clarificacao.
### Passo 2: Hierarquia
Quem lhe reporta:
```sql
SELECT name, role, status FROM agents
WHERE reports_to = '{{AGENT_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
ORDER BY role, name;
```
A quem reporta:
```sql
SELECT name, role FROM agents WHERE id = '{{REPORTS_TO_ID}}';
```
### Passo 3: Ultimas 5 runs
```sql
SELECT hr.status, hr.started_at, hr.finished_at, LEFT(hr.error, 80) as erro
FROM heartbeat_runs hr
WHERE hr.agent_id = '{{AGENT_ID}}'
ORDER BY hr.started_at DESC LIMIT 5;
```
### Passo 4: Issues atribuidas
```sql
SELECT title, status, priority FROM issues
WHERE assignee_agent_id = '{{AGENT_ID}}'
AND status NOT IN ('done','cancelled')
ORDER BY priority, status;
```
### Passo 4b: Verificar falsos blockers (INC-07)
Se o agente tem issues `blocked`, invocar tool MCP: `mcp__paperclip__diag_false_blockers` e filtrar pelo agente. TODO: criar diag_* tool per-agent se uso recorrente.
Se `sub_activas > 0` e o agente está operacional → falso blocker. Alertar: "Issue {{ID}} marcada como blocked mas tem sub-tasks activas — deveria ser in_progress."
### Passo 5: AGENTS.md
Procurar em `AGENTS_PATH`:
```bash
find /media/ealmeida/Dados/Hub/04-Stack/02.06-Clip/agents/ -name "AGENTS.md" -exec grep -l "{{NOME}}" {} \;
```
Se encontrado, ler e apresentar resumo (primeiras 30 linhas).
## Formato de output
```
## Agente: {{NOME}}
**Role:** {{role}} | **Status:** {{status}} | **Ultimo heartbeat:** {{last_heartbeat_at}}
**Reporta a:** {{reports_to_name}} | **Budget:** {{spent}}/{{budget}} ({{pct}}%)
**Tokens cached:** {{tokens_M}}M | **CWD:** {{cwd}} | **Model:** {{model}}
### Equipa (reportam a este agente)
| Nome | Role | Status |
...
### Ultimas 5 runs
| Status | Início | Fim | Erro |
...
### Issues atribuidas
| Titulo | Status | Prioridade |
...
### Skills atribuidas
[lista de desiredSkills ou "Sem skills (apenas built-in paperclip)"]
### AGENTS.md
[resumo ou path]
```
### Passo 6: Skills do agente
```sql
SELECT
adapter_config->'paperclipSkillSync'->'desiredSkills' as desired_skills
FROM agents
WHERE id = '{{AGENT_ID}}';
```
Se nao NULL, listar as skills. Se NULL, indicar "Sem skills atribuidas (apenas built-in paperclip)".
Para ver detalhes das skills disponiveis na empresa:
```sql
SELECT name, slug, key, source_type FROM company_skills
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
ORDER BY name;
```
### Skills atribuídas ao agente
```sql
-- Ver skills desejadas (configuradas via API)
SELECT
a.name as agente,
a.adapter_config->'paperclipSkillSync'->'desiredSkills' as desired_skills
FROM agents a
WHERE a.id = '{{AGENT_ID}}';
```
**Acções disponíveis:**
- Ver skills da empresa: `SELECT name, slug FROM company_skills WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'`
- Atribuir skills via API (fetch no browser): `POST /api/agents/{{AGENT_ID}}/skills/sync` com `{ "desiredSkills": ["slug1", "slug2"] }`
### Membership (OBRIGATÓRIO — sem isto, permissões não funcionam)
A função `hasPermission()` verifica **primeiro** se o agente tem membership activa em `company_memberships`. Sem membership → permissão negada mesmo com grants correctos.
```sql
-- Verificar membership
SELECT status, membership_role FROM company_memberships
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND principal_id = '{{AGENT_ID}}';
```
Se **0 rows** → agente não tem membership. Criar:
```sql
INSERT INTO company_memberships (id, company_id, principal_type, principal_id, status, membership_role, created_at, updated_at)
VALUES (gen_random_uuid(), 'ebe10308-efd7-453f-86ab-13e6fe84004f', 'agent', '{{AGENT_ID}}', 'active', 'member', NOW(), NOW());
```
**Nota:** Agentes criados via SQL directo NÃO recebem membership automaticamente — apenas os onboarded via fluxo OpenClaw/hiring. Sempre criar membership ao adicionar agentes manualmente.
### Permissões do agente
```sql
SELECT permission_key FROM principal_permission_grants
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND principal_id = '{{AGENT_ID}}';
```
Para adicionar `tasks:assign` (necessário para delegação):
```sql
INSERT INTO principal_permission_grants (company_id, principal_type, principal_id, permission_key, granted_by_user_id)
VALUES ('ebe10308-efd7-453f-86ab-13e6fe84004f', 'agent', '{{AGENT_ID}}', 'tasks:assign', 'local-board');
```
**ATENÇÃO:** Este grant só funciona se o agente tiver membership activa (ver secção acima).
### Passo 7: Verificar adapter_config (CRITICO)
Agentes sem `dangerouslySkipPermissions: true` ficam bloqueados — todos os comandos bash sao rejeitados.
```sql
SELECT name,
adapter_config->>'dangerouslySkipPermissions' as skip_perms,
adapter_config->>'cwd' as cwd,
adapter_config->>'model' as model,
adapter_config->>'timeoutSec' as timeout,
adapter_config->>'maxTurnsPerRun' as max_turns
FROM agents WHERE id = '{{AGENT_ID}}';
```
**Alertar se:**
- `skip_perms` != `true` → agente vai ficar bloqueado em todos os comandos bash
- `cwd` = NULL → agente corre em directório temporário sem acesso ao Hub
- `cwd` = `/media/ealmeida/Dados/Hub`**CRITICO: CWD aponta para Hub raiz (6.4GB), Claude Code indexa tudo, causa token burn massivo** — usar `/media/ealmeida/Dados/Hub/04-Stack/02.06-Clip`
- `model` = NULL → usa modelo default (pode não ser o desejado)
**Corrigir agente (CWD correcto para Clip):**
```sql
UPDATE agents SET adapter_config = adapter_config || '{"dangerouslySkipPermissions": true, "cwd": "/media/ealmeida/Dados/Hub/04-Stack/02.06-Clip", "model": "gemini-2.5-flash", "graceSec": 20, "timeoutSec": 900}'::jsonb
WHERE id = '{{AGENT_ID}}';
```
**Nota sobre modelos e adapters:** O adapter `claude_local` já não é usado para agentes heartbeat. Distribuição actual:
- 1 agente (CEO) usa `gemini_local` com `gemini-2.5-pro`
- 50 agentes usam `gemini_local` com `gemini-2.5-flash`
- 13 agentes usam `opencode_local` com `openrouter/x-ai/grok-4.1-fast`
**Agentes analyst/read-only (ex: Reality Checker):** usar `adapter_type: process` com `adapter_config.model: "claude-sonnet-4-6"` e `instructionsBundleMode: "external"`. Estes agentes são invocados manualmente (heartbeat desactivado), não consomem budget em modo autónomo.
### Passo 7b: Sessão e tokens (INC-12)
`agent_task_sessions` não tem campo de tokens — o consumo está em `heartbeat_runs.usage_json`. Verificar erros "Prompt is too long" e consumo nas últimas runs.
```sql
-- Erros "Prompt is too long" recentes
SELECT hr.status, LEFT(hr.error, 80) as erro, hr.started_at::timestamp(0)
FROM heartbeat_runs hr
WHERE hr.agent_id = '{{AGENT_ID}}'
AND hr.status IN ('failed','error')
AND hr.error ILIKE '%too long%'
AND hr.started_at > NOW() - INTERVAL '48 hours'
ORDER BY hr.started_at DESC LIMIT 5;
-- Consumo token nas últimas runs bem-sucedidas
SELECT ROUND(COALESCE((hr.usage_json->>'cache_read_input_tokens')::numeric,0)/1000,0) as cache_read_k,
ROUND(COALESCE((hr.usage_json->>'input_tokens')::numeric,0)/1000,0) as input_k,
ROUND(COALESCE((hr.usage_json->>'output_tokens')::numeric,0)/1000,0) as output_k,
hr.started_at::timestamp(0)
FROM heartbeat_runs hr
WHERE hr.agent_id = '{{AGENT_ID}}'
AND hr.status = 'succeeded'
AND hr.usage_json IS NOT NULL
ORDER BY hr.started_at DESC LIMIT 3;
```
Se existirem erros "too long" → forçar rotação:
```sql
DELETE FROM agent_task_sessions
WHERE agent_id = '{{AGENT_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
### Passo 7c: Validar instructionsFilePath (INC-07)
O Paperclip **não usa `cwd` para resolver `instructionsFilePath`** — o path é sempre relativo ao processo do servidor, não ao CWD do agente. Deve ser **sempre absoluto**.
```sql
SELECT adapter_config->>'instructionsFilePath' as instructions_path
FROM agents WHERE id = '{{AGENT_ID}}';
```
**Alertar se:**
- `instructionsFilePath` não começa com `/`**CRITICO: path relativo, AGENTS.md não carrega**
- Path absoluto mas ficheiro não existe → CRITICO
**Corrigir path relativo:**
```sql
UPDATE agents
SET adapter_config = jsonb_set(
adapter_config,
'{instructionsFilePath}',
to_jsonb('/media/ealmeida/Dados/Hub/04-Stack/02.06-Clip/' || (adapter_config->>'instructionsFilePath'))
)
WHERE id = '{{AGENT_ID}}'
AND adapter_config->>'instructionsFilePath' NOT LIKE '/%';
```
## Wakeup manual de agente
Para forcar um agente a acordar imediatamente (ex: testar, desbloquear):
```sql
DO $$
DECLARE wakeup_id uuid;
BEGIN
INSERT INTO agent_wakeup_requests (company_id, agent_id, source, trigger_detail, reason, payload, status, requested_at, created_at, updated_at)
VALUES ('ebe10308-efd7-453f-86ab-13e6fe84004f', '{{AGENT_ID}}', 'on_demand', 'manual', '{{RAZAO}}', '{}'::jsonb, 'queued', NOW(), NOW(), NOW())
RETURNING id INTO wakeup_id;
INSERT INTO heartbeat_runs (company_id, agent_id, invocation_source, trigger_detail, status, wakeup_request_id, context_snapshot, created_at, updated_at)
VALUES ('ebe10308-efd7-453f-86ab-13e6fe84004f', '{{AGENT_ID}}', 'on_demand', 'manual', 'queued', wakeup_id, '{"wakeReason": "manual_wakeup"}'::jsonb, NOW(), NOW());
END $$;
```
**Nota:** UPDATE directo em issues nao dispara wakeOnDemand — e preciso o par wakeup_request + heartbeat_run.
## Criar agente novo via SQL (checklist OBRIGATÓRIA)
Ao criar agente directamente na BD (fora do fluxo OpenClaw), executar TODOS os passos:
1. `INSERT INTO agents (...)` — dados do agente, incluindo:
- `adapter_type: 'process'`
- `adapter_config`: campos obrigatórios: `model`, `instructionsFilePath` (absoluto!), `instructionsRootPath`, `instructionsEntryFile: "AGENTS.md"`, `instructionsBundleMode: "external"`
- Para agentes autónomos: adicionar `dangerouslySkipPermissions: true`, `cwd`, `timeoutSec`
2. `INSERT INTO company_memberships (...)`**sem isto, permissões não funcionam** (agentes criados via SQL não recebem membership automática)
3. `INSERT INTO principal_permission_grants (...)` — se precisa de `tasks:assign` (C-Level, Directores)
4. Criar `AGENTS.md` no path absoluto definido em `instructionsFilePath`
5. Verificar: `instructionsFilePath` não começa com `/` → AGENTS.md não carrega (ver Passo 7c)
## Acções disponíveis
Se o utilizador pedir:
- **Editar AGENTS.md:** Abrir ficheiro com Read/Edit
- **Alterar config:** `UPDATE agents SET runtime_config = '...' WHERE id = '{{AGENT_ID}}';`
- **Pausar:** `UPDATE agents SET status = 'paused', pause_reason = '...', paused_at = NOW() WHERE id = '{{AGENT_ID}}';`
- **Despausar:** `UPDATE agents SET status = 'idle', pause_reason = NULL, paused_at = NULL WHERE id = '{{AGENT_ID}}';`
- **Wakeup:** Usar bloco SQL acima (wakeup_request + heartbeat_run)
- **Corrigir permissoes:** Usar UPDATE adapter_config acima
- **Atribuir skill:** `curl -s -X POST http://localhost:3100/api/agents/{{AGENT_ID}}/skills/sync -H "Content-Type: application/json" -H "Authorization: Bearer $PAPERCLIP_API_KEY" -d '{"desiredSkills": ["key1", "key2"]}'`
- **Ver skills empresa:** query company_skills acima
### Safety gate: verificacao de dependencias (OBRIGATORIO antes de DELETE/remocao)
Antes de apagar ou remover qualquer agente, executar SEMPRE:
```sql
SELECT 'budget_policies' as tabela, COUNT(*) as refs FROM budget_policies WHERE scope_type='agent' AND scope_id='{{AGENT_ID}}'
UNION ALL
SELECT 'budget_incidents', COUNT(*) FROM budget_incidents WHERE scope_type='agent' AND scope_id='{{AGENT_ID}}'
UNION ALL
SELECT 'heartbeat_runs', COUNT(*) FROM heartbeat_runs WHERE agent_id='{{AGENT_ID}}'
UNION ALL
SELECT 'issues', COUNT(*) FROM issues WHERE assignee_agent_id='{{AGENT_ID}}'
UNION ALL
SELECT 'issue_comments', COUNT(*) FROM issue_comments WHERE author_agent_id='{{AGENT_ID}}';
```
- Se refs > 0 em budget_policies ou budget_incidents: apagar essas refs PRIMEIRO, senao o dashboard fica com "Agent not found"
- Se refs > 0 em issues: reatribuir ou fechar as issues antes
- Mostrar resultado ao utilizador e confirmar antes de prosseguir
- NUNCA apagar agente sem verificar e limpar dependencias
Confirmar sempre antes de executar accoes destrutivas.
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-07","issue":"API skill attribution sem Authorization header — chamada rejeitada com 401","fix":"Adicionar -H 'Authorization: Bearer $PAPERCLIP_API_KEY' ao curl POST /api/agents/:id/skills/sync","source":"auto"}
{"date":"2026-04-07","issue":"Agente criado via SQL sem membership ficou com Board access required em todos os endpoints","fix":"Sempre inserir em company_memberships após INSERT em agents. Agentes via SQL não recebem membership automática — só via fluxo OpenClaw/hiring","source":"auto"}
{"date":"2026-04-07","issue":"instructionsBundleMode em falta na adapter_config — AGENTS.md não carregava","fix":"Incluir instructionsBundleMode: 'external' + instructionsRootPath + instructionsEntryFile: 'AGENTS.md' na adapter_config","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+398
View File
@@ -0,0 +1,398 @@
---
name: clip-health
description: Diagnóstico rápido Paperclip — serviço, BD, heartbeats falhados, budget, disco. Usar quando "clip health", "saúde clip", "diagnóstico paperclip", "clip problemas".
context: fork
---
# /clip-health — Diagnostico Paperclip
Verificacao rapida da saude do sistema Clip.
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
PAPERCLIP_DIR: /home/ealmeida/paperclip
INSTANCE_DIR: /home/ealmeida/.paperclip/instances/default
```
## Procedimento
Executar todas as verificacoes em paralelo, depois apresentar relatorio.
### Check 1: Serviço
```bash
ps aux | grep -E "paperclip.*src/index|pnpm.*paperclipai" | grep -v grep | head -5
```
- Processos encontrados = OK
- Nenhum processo = CRITICO (iniciar com: `cd /home/ealmeida/paperclip && pnpm --filter @paperclipai/server dev`)
Verificar também memória partilhada PostgreSQL (causa do bug POSIX shared memory):
```bash
ls /dev/shm/PostgreSQL.* 2>/dev/null && echo "POSIX OK" || echo "POSIX em falta — BD pode falhar ao ligar"
```
- POSIX OK = OK
- POSIX em falta + processos activos = AVISO (PostgreSQL perdeu shared memory — reiniciar Paperclip)
- POSIX em falta + sem processos = CRITICO
### Check 2: Base de dados
Conexao:
```sql
SELECT 1 as connected;
```
Tamanho:
```sql
SELECT pg_size_pretty(pg_database_size('paperclip')) as db_size;
```
Contagens:
```sql
SELECT
(SELECT COUNT(*) FROM agents WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as agentes,
(SELECT COUNT(*) FROM issues WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as issues,
(SELECT COUNT(*) FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as heartbeats;
```
- Conexao OK = OK
- Conexao falha = CRITICO
### Check 3: Heartbeats falhados (24h)
```sql
SELECT a.name, hr.status, LEFT(hr.error, 70) as erro, hr.started_at::timestamp(0)
FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND hr.status IN ('failed','error')
AND hr.started_at > NOW() - INTERVAL '24 hours'
ORDER BY hr.started_at DESC
LIMIT 20;
```
- 0 falhas = OK
- 1-2 falhas = AVISO
- 3+ falhas = CRITICO
### Check 4: Budget
```sql
SELECT name, budget_monthly_cents, spent_monthly_cents,
CASE WHEN budget_monthly_cents > 0
THEN ROUND(spent_monthly_cents::numeric / budget_monthly_cents * 100, 1)
ELSE 0 END as pct
FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND budget_monthly_cents > 0
AND spent_monthly_cents > 0
ORDER BY pct DESC;
```
- <80% = OK
- 80-95% = AVISO
- >95% = CRITICO
### Check 5: Disco
```bash
df -h /home/ealmeida/.paperclip/ | tail -1
```
```bash
du -sh /home/ealmeida/.paperclip/instances/default/db/ 2>/dev/null
du -sh /home/ealmeida/.paperclip/instances/default/logs/ 2>/dev/null
du -sh /home/ealmeida/.paperclip/instances/default/data/ 2>/dev/null
```
- >30% livre = OK
- 15-30% livre = AVISO
- <15% livre = CRITICO
### Check 6: API Health
```bash
curl -s --max-time 5 http://localhost:3100/health 2>/dev/null || echo "FALHA"
```
Esperado: `{"status":"ok","version":"...","deploymentMode":"authenticated","bootstrapStatus":"ready"}`
- `status: ok` = OK
- `{"error":"Board access required"}` = AVISO (API responde mas sem auth — BD operacional)
- FALHA/timeout = CRITICO (servidor não responde)
### Check 7: Gateway MCPs
```bash
curl -s --max-time 5 https://gateway.descomplicar.pt/health 2>/dev/null || echo "FALHA"
```
- Responde = OK
- Timeout/falha = AVISO
### Check 8: Referencias orfas na BD
Budget policies e incidents a referenciar entidades inexistentes:
Invocar tool MCP: `mcp__paperclip__diag_budget_orphans`
- 0 orfaos = OK
- 1+ orfaos = CRITICO (causa "Agent not found" no dashboard, apagar com DELETE)
### Check 9: Instancias duplicadas
```bash
ss -tlnp | grep -E "310[0-9]" | wc -l
```
- 1 instancia = OK
- 2+ instancias = CRITICO (processos orfaos do pnpm, matar com `kill -9` os PIDs com PPID=1)
Detalhe dos processos:
```bash
ss -tlnp | grep -E "310[0-9]"
```
### Check 10: Porta vs Cloudflare Tunnel
```bash
TUNNEL_PORT=$(grep -A1 "clip.descomplicar.pt" ~/.cloudflared/config.yml | grep service | grep -oP ':\K[0-9]+')
ACTUAL_PORT=$(ss -tlnp | grep -E "310[0-9]" | head -1 | grep -oP ':310[0-9]' | tr -d ':')
echo "Tunnel: $TUNNEL_PORT | Servidor: $ACTUAL_PORT"
```
- Iguais = OK
- Diferentes = CRITICO (tunnel a apontar para porta errada, dashboard inacessivel)
### Check 11: Agentes sem permissoes bash
Invocar tool MCP: `mcp__paperclip__diag_agents_missing_permissions`
- 0 = OK
- 1+ = CRITICO (agentes vao ficar bloqueados ao executar bash — corrigir com `/clip-agent`)
### Check 12: Agentes sem heartbeat
Invocar tool MCP: `mcp__paperclip__diag_agents_missing_heartbeat`
- 0 = OK
- 1+ = AVISO (agentes nao acordam — podem nao processar issues)
### Check 13: Routine triggers com kind errado ou next_run_at NULL
Invocar tool MCP: `mcp__paperclip__diag_routine_triggers_broken`
- 0 = OK
- 1+ = CRITICO (routines nao vao disparar — kind deve ser 'schedule' e next_run_at populado)
### Check 14: Issues PUBLICAR NOTICIA sem assignee
```sql
SELECT COUNT(*) FROM issues
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND title LIKE 'PUBLICAR NOTICIA%'
AND status = 'todo'
AND assignee_agent_id IS NULL;
```
- 0 = OK
- 1+ = AVISO (cron assign-copywriter.sh devia atribuir a cada 5 min — verificar crontab)
### Check 15: Qualidade artigos publicados (ultimas 24h)
Verificar artigos recentes no WordPress via SSH (server):
```bash
cd /home/ealmeida/public_html && wp --allow-root post list --post_type=post --post_status=publish --category=noticias --date_query='{"after":"1 day ago"}' --fields=ID,post_title --format=csv 2>/dev/null
```
Para CADA artigo recente, verificar:
**15a. Acentuacao** — procurar palavras sem acento:
```bash
cd /home/ealmeida/public_html && wp --allow-root post get POST_ID --field=post_content 2>/dev/null | sed 's/<[^>]*>//g' | grep -oP '\b\w+cao\b|\b\w+sao\b|\bnao\b|\b\w+vel\b' | head -20
```
Palavras terminadas em "cao", "sao" (sem til) ou "nao" indicam acentuacao em falta.
**15b. Links HTML sem aspas:**
```bash
cd /home/ealmeida/public_html && wp --allow-root post get POST_ID --field=post_content 2>/dev/null | grep -oP 'href=[^"'\''"][^ >]+' | head -10
```
Se output nao vazio = links sem aspas.
**15c. Titulo com maiusculas indevidas:**
```bash
cd /home/ealmeida/public_html && wp --allow-root post get POST_ID --field=post_title 2>/dev/null
```
Verificar: so primeira palavra e nomes proprios devem ter maiuscula.
- 0 problemas = OK
- 1-3 = AVISO (artigos com defeitos cosmeticos)
- 4+ = CRITICO (Copywriter nao esta a cumprir quality gates — actualizar AGENTS.md)
### Check 16: Cron assign-copywriter activo
```bash
crontab -l | grep assign-copywriter
```
- Presente = OK
- Ausente = CRITICO (issues PUBLICAR NOTICIA nunca serao atribuidas ao Copywriter)
### Check 17: Pipeline noticias end-to-end (ultimas 24h)
```sql
-- Routines disparadas
SELECT COUNT(*) as routines_fired FROM routine_triggers rt
JOIN routines r ON rt.routine_id = r.id
WHERE r.title LIKE 'Pesquisa diaria%noticias%'
AND rt.last_fired_at > NOW() - INTERVAL '24 hours';
-- Issues de pesquisa concluidas
SELECT COUNT(*) as pesquisas_done FROM issues
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND title LIKE 'Pesquisa diaria%'
AND status = 'done'
AND created_at > NOW() - INTERVAL '24 hours';
-- Issues PUBLICAR NOTICIA criadas e concluidas
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE status = 'done') as done,
COUNT(*) FILTER (WHERE status IN ('todo','in_progress')) as pendentes
FROM issues
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND title LIKE 'PUBLICAR NOTICIA%'
AND created_at > NOW() - INTERVAL '24 hours';
```
- routines_fired >= 3 E pesquisas_done >= 1 E done >= 5 = OK
- Qualquer zero = AVISO (pipeline com falhas)
- routines_fired = 0 = CRITICO (routines nao disparam)
### Check 18: Issues blocked sem impedimento real (INC-07)
Invocar tool MCP: `mcp__paperclip__diag_false_blockers`
Para cada issue blocked, verificar se o assignee está em erro:
```sql
SELECT a.name, a.status FROM agents a
WHERE a.id = (SELECT assignee_agent_id FROM issues WHERE identifier = '{{ID}}');
```
- Issue `blocked` + assignee `active/idle/running` + sub-tasks activas > 0 = **FALSO BLOCKER** (deveria ser `in_progress`)
- Issue `blocked` + assignee `error/paused` = blocker legítimo
- Issue `blocked` + sem sub-tasks + sem comentário de impedimento = suspeito, alertar
Resultado:
- 0 falsos blockers = OK
- 1+ falsos blockers = AVISO (listar e recomendar correcção para `in_progress`)
---
### Check 19: Sessões com tokens excessivos (INC-12)
Previne "Prompt is too long" e token burn massivo. Monitoriza via usage_json dos heartbeats recentes.
Top agentes com maior consumo de tokens nas últimas 24h:
Invocar tool MCP: `mcp__paperclip__diag_heartbeat_token_usage(hours=24)`
Contagem de erros "Prompt is too long" activos (sinal imediato):
Invocar tool MCP: `mcp__paperclip__diag_prompt_too_long_errors(hours=24)`
- 0 erros = OK
- 1+ erros = CRITICO (forçar rotação de sessão)
**Forçar rotação de sessão (apaga histórico, fresh start):**
```sql
DELETE FROM agent_task_sessions
WHERE agent_id = '{{AGENT_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
---
### Check 20: Routines presas in_progress >4h (INC-08)
Issues de routine que ficam `in_progress` sem actividade bloqueiam todos os futuros disparos da mesma routine (constraint `issues_open_routine_execution_uq`). A ligação issue→routine está em `routine_runs.linked_issue_id` (não existe `issues.routine_id`).
Invocar tool MCP: `mcp__paperclip__diag_stuck_routines(hours=4)`
- 0 = OK
- 1+ = CRITICO (routine bloqueada — cancelar a issue presa para desbloquear futuros disparos)
**Desbloquear routine (cancelar issue presa):**
```sql
UPDATE issues SET status = 'cancelled', updated_at = NOW()
WHERE identifier = '{{IDENTIFIER}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
---
### Check 21: Zombie parents — issues pai com sub-tasks todas concluídas (AP-09)
Issues pai que ficam abertas indefinidamente quando todas as sub-tasks estão `done` ou `cancelled`. Poluem o dashboard e impedem distinguir trabalho parado de trabalho já feito.
Invocar tool MCP: `mcp__paperclip__diag_zombie_parents`
- 0 = OK
- 1+ = AVISO (fechar manualmente ou alertar CEO para verificar e fechar)
---
## Formato de output
```
## Clip Health — [data/hora]
| Check | Estado | Detalhe |
|-------|--------|---------|
| Servico | OK/CRITICO | N processos activos / stopped |
| POSIX shared memory | OK/AVISO/CRITICO | /dev/shm/PostgreSQL.* presente / em falta |
| Base de dados | OK/CRITICO | Xmb, N agentes, N issues |
| Heartbeats 24h | OK/AVISO/CRITICO | N falhas |
| Budget | OK/AVISO/CRITICO | [agente] a X% |
| Disco | OK/AVISO/CRITICO | X% livre (Xgb) |
| API Health | OK/AVISO/CRITICO | status:ok / board access / timeout |
| Gateway | OK/AVISO | responde / timeout |
| Refs orfas | OK/CRITICO | N budget_policies orfas |
| Instancias | OK/CRITICO | N processos na porta 310x |
| Porta/Tunnel | OK/CRITICO | tunnel:X servidor:Y |
| Permissoes bash | OK/CRITICO | N agentes sem dangerouslySkipPermissions |
| Heartbeats config | OK/AVISO | N agentes sem heartbeat enabled |
| Routine triggers | OK/CRITICO | N triggers com kind errado ou next_run_at NULL |
| Auto-assign noticias | OK/AVISO | N issues PUBLICAR NOTICIA sem assignee |
| Qualidade artigos | OK/AVISO/CRITICO | N artigos com acentos/links/titulos errados |
| Cron assign-copywriter | OK/CRITICO | activo / ausente |
| Pipeline noticias 24h | OK/AVISO/CRITICO | N routines, N pesquisas, N publicadas |
| Falsos blockers | OK/AVISO | N issues blocked sem impedimento real |
| Tokens excessivos | OK/AVISO/CRITICO | N agentes >500K tokens cached |
| Routines presas | OK/CRITICO | N issues rotina paradas >4h |
| Zombie parents | OK/AVISO | N issues pai com todas as subs concluídas |
**Score:** N/22 OK
### Detalhes (se existirem alertas)
[listar heartbeats falhados, budget alto, artigos com defeitos, pipeline parado]
### Accoes recomendadas
[listar accoes concretas para resolver alertas]
```
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-07","issue":"Check 1 usava systemctl que nunca existe (Paperclip corre via pnpm dev)","fix":"Substituir por ps aux | grep paperclip + check POSIX shared memory /dev/shm/PostgreSQL.*","source":"auto"}
{"date":"2026-04-07","issue":"Check 6 usava npx paperclipai doctor que não existe no projecto local","fix":"Substituir por curl localhost:3100/health — distingue: ok / board access (BD operacional) / timeout (servidor morto)","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+184
View File
@@ -0,0 +1,184 @@
---
name: clip-instructions
description: Editar e gerir AGENTS.md de agentes Paperclip — ver, editar, rever histórico de versões. O AGENTS.md é o "cérebro" do agente. Usar quando "clip instructions", "editar agente", "atualizar AGENTS.md", "mudar comportamento agente", "instruções agente".
context: fork
version: "1.0.0"
created: 2026-04-07
---
# /clip-instructions — Gerir AGENTS.md dos Agentes
O `AGENTS.md` é o ficheiro de instruções que define identidade, missão, comportamento e regras de cada agente. É injectado a cada heartbeat — editar o ficheiro tem efeito imediato no próximo run.
Aceita argumento: nome do agente (ex: `/clip-instructions CTO`).
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
```
## Passo 1: Encontrar agente e localizar AGENTS.md
```sql
SELECT id, name, role, title,
adapter_config->>'instructionsFilePath' as instructions_path,
adapter_config->>'instructionsRootPath' as instructions_root
FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND LOWER(name) LIKE LOWER('%{{NOME}}%');
```
Se `instructions_path` é NULL ou não começa com `/` → CRITICO (AGENTS.md não está a ser carregado).
## Passo 2: Ler ficheiro actual
```bash
cat "{{instructions_path}}"
```
Apresentar conteúdo completo. Identificar secções:
- `## Identidade` — nome, papel, tipo, modelo, budget
- `## Missão` — objectivo principal
- `## Comportamento` — regras de actuação
- `## Skills` / `## MCPs` — ferramentas
- `## Heartbeat` — intervalo, checklist
- `## Equipa` — quem reporta a quem
## Passo 3: Modo de actuação
### Ver (sem edições pedidas)
Apresentar resumo estruturado das secções principais.
### Editar (utilizador pede alteração específica)
1. Ler ficheiro completo com Read
2. Identificar a secção a alterar
3. Propor a alteração ao utilizador ("Vou mudar X para Y — confirmas?")
4. Executar com Edit após confirmação
5. Verificar que o ficheiro ficou correcto
**Regras de edição segura:**
- Nunca reescrever o ficheiro completo — usar Edit para alterações cirúrgicas
- Preservar frontmatter YAML se existir
- Manter estrutura de secções existente
- Após editar, mostrar diff resumido das alterações
### Criar novo AGENTS.md (agente sem instruções)
Se `instructions_path` está definido mas o ficheiro não existe:
```bash
ls "{{instructions_path}}" 2>/dev/null || echo "NAO_EXISTE"
```
Criar directório se necessário:
```bash
mkdir -p "{{instructions_root}}"
```
Template mínimo para novo AGENTS.md:
```markdown
# {{NOME}}
## Identidade
- **Nome:** {{NOME}}
- **Papel:** {{ROLE}} — reporta ao {{SUPERVISOR}}
- **Tipo:** {{TIPO}} (executor/analyst/manager)
- **Modelo:** {{MODELO}}
- **Budget:** {{BUDGET}} cents/mês
## Missão
{{DESCRICAO_MISSAO}}
## Comportamento
### Regras
- **Foco** — executar apenas tarefas dentro do scope definido
- **Escalação** — problemas fora de scope → reportar ao supervisor
- **PT-PT** — sempre com acentuação correcta
## Heartbeat
- **Intervalo:** {{INTERVALO}}s
- **Checklist:** ver issues atribuídas, executar, reportar
## Equipa
- Reporta ao: {{SUPERVISOR}}
```
## Passo 4: Verificar após edição
Confirmar que o Paperclip reconhece o ficheiro actualizado:
```bash
curl -s "http://localhost:3100/api/agents/{{AGENT_ID}}/instructions-bundle" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK' if d.get('content') else 'VAZIO')"
```
- OK = AGENTS.md carregado pelo servidor
- VAZIO / erro = path errado ou ficheiro não encontrado
## Casos especiais
### Actualizar model no AGENTS.md
Se o agente mudou de modelo (ex: gemini → claude), actualizar tanto o AGENTS.md como o `adapter_config`:
```sql
UPDATE agents
SET adapter_config = jsonb_set(adapter_config, '{model}', '"{{NOVO_MODELO}}"'::jsonb)
WHERE id = '{{AGENT_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
### Rever historial de versões (config_revisions)
```sql
SELECT cr.id, cr.created_at::timestamp(0), a.name as criado_por
FROM agent_config_revisions cr
LEFT JOIN agents a ON cr.created_by_agent_id = a.id
WHERE cr.agent_id = '{{AGENT_ID}}'
ORDER BY cr.created_at DESC
LIMIT 10;
```
### Rollback via API
```bash
curl -s -X POST "http://localhost:3100/api/agents/{{AGENT_ID}}/config-revisions/{{REVISION_ID}}/rollback" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
---
## Formato de output
```
## Instruções — {{NOME}} ({{role}})
**Ficheiro:** {{instructions_path}}
**Estado:** carregado / não encontrado / path inválido
### Resumo actual
**Missão:** [1 linha]
**Modelo:** {{model}} | **Budget:** {{budget}} cents | **Heartbeat:** {{intervalo}}s
**Regras principais:** [lista]
**Skills:** [lista ou "nenhuma"]
### Alterações efectuadas (se editou)
[diff resumido]
```
---
## Healing Log
```jsonl
{"date":"2026-04-07","issue":"instructionsFilePath relativo — AGENTS.md não carregava após criação via SQL","fix":"Path deve ser sempre absoluto. Verificar com query adapter_config->>'instructionsFilePath' NOT LIKE '/%'","source":"auto"}
```
+200
View File
@@ -0,0 +1,200 @@
---
name: clip-issue
description: Criar e gerir issues Paperclip — lançar objectivos ao CEO, ver progresso, comentar. Usar quando "clip issue", "criar issue", "lançar objectivo", "ver issues clip". Issues seguem cadeia de delegação hierárquica.
context: fork
---
# /clip-issue — Gerir Issues Paperclip
Modos: lista (sem args), criar (com titulo), ver (com ID).
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
API: http://localhost:3100/api
```
## Modo lista (sem argumentos)
```sql
SELECT i.id, i.title, i.status, i.priority, a.name as assignee, i.created_at
FROM issues i LEFT JOIN agents a ON i.assignee_agent_id = a.id
WHERE i.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND i.status NOT IN ('done','cancelled')
ORDER BY
CASE i.priority WHEN 'critical' THEN 1 WHEN 'high' THEN 2 WHEN 'medium' THEN 3 ELSE 4 END,
i.status, i.created_at DESC;
```
Para ver concluidas tambem:
```sql
-- Adicionar: AND i.status IN ('done') AND i.updated_at > NOW() - INTERVAL '7 days'
```
## Modo criar (com titulo)
### Passo 1: Obter CEO ID
```sql
SELECT id FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND name = 'CEO';
```
### Passo 2: Criar issue
Preferir API (quando JWT funciona):
```bash
curl -s -X POST "http://localhost:3100/api/companies/ebe10308-efd7-453f-86ab-13e6fe84004f/issues" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "{{TITULO}}",
"description": "{{DESCRICAO}}",
"priority": "{{PRIORIDADE}}",
"assigneeAgentId": "{{CEO_ID}}"
}'
```
Fallback via BD (OBRIGATORIO incluir identifier e issue_number):
```sql
-- Passo 2a: Obter proximo numero
SELECT issue_counter FROM companies WHERE id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
-- Guardar o valor como NEXT_NUM
-- Passo 2b: Criar issue COM identifier
INSERT INTO issues (id, company_id, title, description, priority, assignee_agent_id, status, identifier, issue_number, created_at, updated_at)
VALUES (
gen_random_uuid(),
'ebe10308-efd7-453f-86ab-13e6fe84004f',
'{{TITULO}}',
'{{DESCRICAO}}',
'{{PRIORIDADE}}',
'{{CEO_ID}}',
'todo',
'DES-{{NEXT_NUM}}',
{{NEXT_NUM}},
NOW(), NOW()
)
RETURNING id, identifier, title, status;
-- Passo 2c: Incrementar counter (CRITICO — nunca esquecer)
UPDATE companies SET issue_counter = {{NEXT_NUM}} + 1 WHERE id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
**NUNCA criar issues via SQL sem identifier e issue_number.** Causa bug de duplicate key que bloqueia toda a criacao de issues no Paperclip.
Confirmar titulo e prioridade com o utilizador antes de criar. Prioridades: critical, high, medium, low.
### Nota sobre delegação hierárquica
Issues criadas pelo Board (Emanuel) são sempre atribuídas ao CEO. O CEO delega pela cadeia:
- CEO cria sub-issue ao C-Level adequado
- C-Level cria sub-issue ao Director
- Director atribui ao especialista
Quando routines disparam, geram issues ao CEO que segue o mesmo fluxo. A cadeia está na descrição da routine (campo `description` começa com `CADEIA: CEO → ...`).
## Semântica de estados (referência rápida)
Ao criar, alterar ou interpretar estados de issues:
- **`todo`** — não iniciada, aguarda pickup
- **`in_progress`** — trabalho em curso, **incluindo aguardar sub-tasks delegadas**
- **`blocked`** — APENAS impedimento real (agente em erro, falta de permissão, dependência externa, aguarda decisão humana)
- **`done`** — concluída com resultado verificado
- **`cancelled`** — abandonada por decisão superior
**Regra INC-07:** `blocked` ≠ "delegué e estou à espera". Aguardar sub-task activa = `in_progress`. Se ao listar issues vires `blocked` sem impedimento real, alertar o utilizador.
## Modo ver (com ID ou titulo parcial)
```sql
SELECT i.*, a.name as assignee
FROM issues i LEFT JOIN agents a ON i.assignee_agent_id = a.id
WHERE i.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND (i.id::text LIKE '%{{ARG}}%' OR LOWER(i.title) LIKE LOWER('%{{ARG}}%'));
```
Comentarios:
```sql
SELECT ic.body, ic.created_at, a.name as author
FROM issue_comments ic
LEFT JOIN agents a ON ic.author_agent_id = a.id
WHERE ic.issue_id = '{{ISSUE_ID}}'
ORDER BY ic.created_at ASC;
```
## Modo comentar
```sql
INSERT INTO issue_comments (id, company_id, issue_id, author_user_id, body, created_at, updated_at)
VALUES (gen_random_uuid(), 'ebe10308-efd7-453f-86ab-13e6fe84004f', '{{ISSUE_ID}}', 'v1N5OccPn9DGq6iog7qW9nEvnXYFT3iO', '{{COMENTARIO}}', NOW(), NOW())
RETURNING id;
```
Nota: `author_user_id = 'v1N5OccPn9DGq6iog7qW9nEvnXYFT3iO'` (Emanuel) → comentário aparece como Board/humano no dashboard. Nunca usar `'board'` — não é um user_id válido.
## Modo checkout / release
Checkout reserva a issue para trabalho activo (sinaliza ao Paperclip que está em curso).
Release liberta a issue de volta a `todo`.
**Checkout via API:**
```bash
curl -s -X POST "http://localhost:3100/api/issues/{{ISSUE_ID}}/checkout" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agentId": "{{AGENT_ID}}"}'
```
**Release via API:**
```bash
curl -s -X POST "http://localhost:3100/api/issues/{{ISSUE_ID}}/release" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
**Fallback via BD (se API falhar):**
```sql
-- Checkout manual
UPDATE issues SET status = 'in_progress', updated_at = NOW()
WHERE id = '{{ISSUE_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
RETURNING identifier, title, status;
-- Release manual
UPDATE issues SET status = 'todo', updated_at = NOW()
WHERE id = '{{ISSUE_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
RETURNING identifier, title, status;
```
**Nota:** O par checkout/release é importante para o pipeline do Paperclip — evita que dois agentes peguem na mesma issue em simultâneo.
## Formato de output
Adaptar ao modo. Para lista:
```
## Issues Clip — [data]
| # | Titulo | Status | Prioridade | Assignee |
...
Total: N abertas (N critical, N high, N medium, N low)
```
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-07","issue":"author_user_id = 'board' em comentários — não é user_id válido, comentário não aparecia no dashboard","fix":"Usar 'v1N5OccPn9DGq6iog7qW9nEvnXYFT3iO' (ID real de Emanuel no Paperclip)","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+148
View File
@@ -0,0 +1,148 @@
---
name: clip-org
description: Org chart Paperclip — hierarquia completa, reports, gaps por preencher. Usar quando "clip org", "organigrama", "hierarquia clip", "quem reporta a quem". Inclui modelo de governance e cadeias de delegação.
context: fork
---
# /clip-org — Org Chart Paperclip
Hierarquia completa da empresa Descomplicar no Paperclip.
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
```
## Procedimento
### Passo 1: Obter hierarquia completa
Invocar tool MCP: `mcp__paperclip__diag_agent_hierarchy`
### Passo 2: Construir arvore visual
Apresentar como arvore identada:
```
Emanuel (Board)
└── CEO (running)
├── COO (idle)
│ ├── [Dir. Suporte] — nao existe
│ └── Ticket Triage (idle)
├── CFO (idle)
│ ├── [Dir. Financeiro] — nao existe
│ ├── Finance Manager (idle)
│ └── Compliance Auditor (idle)
├── CTO (idle)
│ ├── [Dir. Infraestrutura] — nao existe
│ │ ├── CWP Server Manager (idle)
│ │ ├── EasyPanel Specialist (idle)
│ │ ├── Backup Specialist (idle)
│ │ └── Security Specialist (idle)
│ ├── [Dir. Desenvolvimento] — nao existe
│ │ └── ...
│ └── ...
└── ...
```
Nota: Directores de seccao (~16) podem ainda nao existir. Mostrar como `[Nome] — nao existe` para evidenciar gaps.
### Passo 3: Identificar gaps
```sql
-- Agentes orfaos (sem reports_to, excepto CEO)
SELECT name, role, status FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND reports_to IS NULL
AND role != 'ceo';
```
```sql
-- C-Level sem subordinados directos
SELECT c.name, c.role,
(SELECT COUNT(*) FROM agents sub WHERE sub.reports_to = c.id) as subordinados
FROM agents c
WHERE c.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND c.role IN ('coo','cfo','cto','cmo','cro','cgo','cdo')
ORDER BY subordinados ASC;
```
### Passo 4: Estatisticas
```sql
SELECT
role,
COUNT(*) as total,
COUNT(CASE WHEN status = 'running' THEN 1 END) as running,
COUNT(CASE WHEN status = 'idle' THEN 1 END) as idle,
COUNT(CASE WHEN status = 'paused' THEN 1 END) as paused
FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
GROUP BY role
ORDER BY CASE role
WHEN 'ceo' THEN 1 WHEN 'coo' THEN 2 WHEN 'cfo' THEN 3
WHEN 'manager' THEN 4 WHEN 'engineer' THEN 5 ELSE 6 END;
```
## Formato de output
```
## Org Chart Clip — [data]
[arvore visual]
### Estatisticas
| Camada | Total | Running | Idle | Paused |
...
### Gaps
- Directores em falta: [lista das 16 TFs sem Director]
- Agentes orfaos: [lista]
- C-Level sem subordinados: [lista]
### Cobertura
Directores: N/16 (N%)
TaskForces cobertas: [lista]
```
## Referência de TaskForces esperadas
| TF | Director esperado | Reporta a |
|----|-------------------|-----------|
| TF-01 Estratégia | Dir. Estratégia | CGO |
| TF-02 Operações | Dir. Operações | COO |
| TF-03 Financeiro | Dir. Financeiro | CFO |
| TF-04 Infraestrutura | Dir. Infraestrutura | CTO |
| TF-05 Desenvolvimento | Dir. Desenvolvimento | CTO |
| TF-06 Automação | Dir. Automação | CTO |
| TF-07 IA | Dir. IA | CGO |
| TF-08 Design | Dir. Design | CMO |
| TF-09 Web | Dir. Web | CMO |
| TF-10 Vídeo | Dir. Vídeo | CMO |
| TF-11 SEO | Dir. SEO | CMO |
| TF-12 Conteúdo | Dir. Conteúdo | CMO |
| TF-13 Social | Dir. Social | CMO |
| TF-14 Publicidade | Dir. Publicidade | CMO |
| TF-15 Comercial | Dir. Comercial | CRO |
| TF-16 Suporte | Dir. Suporte | COO |
## Modelo de governance
Todas as routines são atribuídas ao CEO que delega pela cadeia hierárquica:
`Routine → CEO → C-Level → Director → Especialista`
Cada nível adiciona contexto antes de delegar e sintetiza resultados antes de reportar acima. Ver `/clip-routine` para detalhes.
---
## 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.*
+349
View File
@@ -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.*
+292
View File
@@ -0,0 +1,292 @@
---
name: clip-skill
description: Gerir company skills no Paperclip — listar, instalar, atribuir a agentes, auditar cobertura. Usar quando "clip skill", "skills clip", "instalar skill", "atribuir skill", "skills paperclip".
context: fork
---
# /clip-skill — Gerir Company Skills Paperclip
Gerir skills instaladas na empresa Descomplicar no Paperclip. Instalar, atribuir, remover e auditar.
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
API: http://localhost:3100/api
SKILLS_CC: ~/.claude/plugins/marketplaces/descomplicar-plugins/
```
## Contexto técnico
Skills no Paperclip funcionam como **injecção de contexto em runtime**:
- O conteúdo do SKILL.md é injectado como contexto adicional ao agente a cada heartbeat
- Não há instalação permanente — a skill é lida do ficheiro a cada execução
- Atribuição é por agente via `adapter_config.paperclipSkillSync.desiredSkills` (array de slugs)
- Skills instaladas na empresa ficam em `company_skills` — só as atribuídas ao agente são injectadas
**Distribuição actual de adapters:**
- 1 agente (CEO): `gemini_local` com `gemini-2.5-pro`
- 50 agentes: `gemini_local` com `gemini-2.5-flash`
- 13 agentes: `opencode_local` com `openrouter/x-ai/grok-4.1-fast`
- Agentes analyst/passive (ex: Reality Checker): `process` com `claude-sonnet-4-6` (sem heartbeat, sem skills)
O adapter `claude_local` já não é usado para agentes heartbeat.
## Modo lista (sem argumentos)
### Skills instaladas na empresa
```sql
SELECT name, slug, key, source_type, trust_level, compatibility,
created_at::date as instalada
FROM company_skills
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
ORDER BY name;
```
### Agentes com skills atribuidas
```sql
SELECT name, role, status,
adapter_config->'paperclipSkillSync'->'desiredSkills' as skills
FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND adapter_config::text LIKE '%paperclipSkillSync%'
ORDER BY name;
```
### Resumo
Apresentar:
```
## Skills Clip — [data]
**Empresa:** N skills instaladas (N locais, N built-in)
**Agentes:** N com skills atribuidas / 62 total
### Skills instaladas
| Nome | Key | Fonte | Trust | Compativel |
...
### Agentes com skills
| Agente | Role | Skills |
...
### Agentes sem skills (top 10 por relevancia)
[listar agentes com routines activas mas sem skills]
```
## Modo instalar (com path ou key)
### Instalar skill de path local
Argumento: path absoluto para pasta com SKILL.md.
Verificar primeiro que existe SKILL.md:
```bash
ls {{PATH}}/SKILL.md 2>/dev/null && head -5 {{PATH}}/SKILL.md
```
Instalar via API:
```bash
curl -s -X POST "http://localhost:3100/api/companies/ebe10308-efd7-453f-86ab-13e6fe84004f/skills/import" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-d '{"source": "{{PATH}}"}'
```
Se API falha (auth), inserir directamente na BD:
```sql
-- Ler frontmatter do SKILL.md para obter name e description
-- Depois inserir:
INSERT INTO company_skills (id, company_id, key, slug, name, description, markdown, source_type, source_locator, trust_level, compatibility, file_inventory, created_at, updated_at)
VALUES (
gen_random_uuid(),
'ebe10308-efd7-453f-86ab-13e6fe84004f',
'descomplicar/{{PLUGIN}}/{{SKILL_NAME}}',
'{{SKILL_NAME}}',
'{{NAME_FROM_FRONTMATTER}}',
'{{DESCRIPTION_FROM_FRONTMATTER}}',
'{{FULL_SKILL_MD_CONTENT}}',
'local_path',
'{{PATH}}',
'markdown_only',
'compatible',
'[]'::jsonb,
NOW(), NOW()
)
RETURNING id, name, slug;
```
Confirmar com o utilizador antes de instalar. Mostrar name e description do SKILL.md.
### Instalar skill do marketplace CC
Argumento: nome da skill no formato `plugin/skill` (ex: `crm-ops/crm`).
Resolver path:
```bash
SKILL_PATH="$HOME/.claude/plugins/marketplaces/descomplicar-plugins/{{PLUGIN}}/skills/{{SKILL}}"
ls "$SKILL_PATH/SKILL.md" 2>/dev/null && head -10 "$SKILL_PATH/SKILL.md"
```
Depois seguir o fluxo de instalacao por path local.
### Instalar em massa (com filtro de plugin)
Argumento: nome do plugin (ex: `crm-ops`).
```bash
find "$HOME/.claude/plugins/marketplaces/descomplicar-plugins/{{PLUGIN}}/skills/" -name "SKILL.md" -exec dirname {} \;
```
Listar todas as skills encontradas com name e description. Pedir confirmacao antes de instalar cada uma.
## Modo atribuir (skill a agente)
### Atribuir via API
```bash
curl -s -X POST "http://localhost:3100/api/agents/{{AGENT_ID}}/skills/sync" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $PAPERCLIP_API_KEY" \
-d '{"desiredSkills": [{{SKILLS_ARRAY}}]}'
```
### Atribuir via BD (fallback)
```sql
UPDATE agents SET adapter_config = jsonb_set(
COALESCE(adapter_config, '{}'::jsonb),
'{paperclipSkillSync}',
jsonb_build_object('desiredSkills', '{{SKILLS_JSON_ARRAY}}'::jsonb)
)
WHERE id = '{{AGENT_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
RETURNING name, adapter_config->'paperclipSkillSync'->'desiredSkills';
```
Confirmar sempre:
- Nome do agente
- Skills a atribuir (mostrar name de cada)
- Se vai substituir ou adicionar a skills existentes
### Atribuir por departamento (batch)
Argumento: nome do C-Level ou Director.
1. Obter agentes subordinados:
```sql
SELECT id, name, role FROM agents
WHERE reports_to = '{{MANAGER_ID}}'
AND company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f';
```
2. Listar skills recomendadas para o departamento
3. Confirmar com utilizador
4. Aplicar a cada agente
## Modo remover
### Remover skill de agente
Ler skills actuais, filtrar a removida, escrever de volta:
```sql
-- Ler
SELECT adapter_config->'paperclipSkillSync'->'desiredSkills' as skills
FROM agents WHERE id = '{{AGENT_ID}}';
-- Actualizar (remover skill especifica)
-- Construir novo array sem a skill removida e usar o UPDATE do modo atribuir
```
### Desinstalar skill da empresa
```sql
DELETE FROM company_skills
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND slug = '{{SLUG}}'
RETURNING name, slug;
```
Avisar: isto remove a skill de todos os agentes que a referenciam. Confirmar sempre.
## Modo auditar
### Cobertura de skills
```sql
-- Agentes com routines activas mas sem skills
SELECT a.name, a.role, r.title as routine
FROM agents a
JOIN routines r ON r.assignee_agent_id = a.id
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND r.status = 'active'
AND (a.adapter_config->'paperclipSkillSync' IS NULL
OR a.adapter_config::text NOT LIKE '%paperclipSkillSync%')
ORDER BY a.name;
```
### Mapeamento recomendado (plugin CC → departamento Clip)
| Plugin CC | Agentes-alvo | Skills prioritarias |
|-----------|-------------|-------------------|
| core-tools | Todos | _core, quality-validator |
| crm-ops | CRO, Dir. Comercial, Sales Manager, Lead Qualifier | crm, desk, lead-approach, orcamento |
| gestao | COO, Dir. Operacoes, Project Manager | today, worklog, knowledge, tasks-overview |
| infraestrutura | CTO, Dir. Infraestrutura, Infra Check, Backup Specialist | gateway-check, backup, easypanel, cwp-server |
| marketing | CMO, Dir. SEO, Dir. Publicidade | seo-audit, seo-technical, ppc |
| wordpress | Dir. Web, WP Update | wp-dev, wp-performance, wp-cli |
| dev-tools | Dir. Desenvolvimento, Development Lead | dev-helper, pdf, docx |
| automacao | Dir. Automacao | n8n, automation-lead |
| negocio | CFO, CGO, Finance Manager | finance, research, saas |
| perfex-dev | Dir. Desenvolvimento | perfex-module |
### Comparacao CC vs Clip
```sql
-- Skills CC disponiveis (contar no filesystem)
-- vs skills instaladas no Clip
SELECT
(SELECT COUNT(*) FROM company_skills WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f') as instaladas_clip;
```
```bash
find ~/.claude/plugins/marketplaces/descomplicar-plugins/ -name "SKILL.md" | wc -l
```
Apresentar:
```
### Auditoria Skills — [data]
**CC:** N skills disponiveis em 15 plugins
**Clip:** N instaladas (N%)
**Agentes com skills:** N/62 (N%)
**Agentes com routines sem skills:** N (ATENCAO)
### Gaps por departamento
| Departamento | Agentes | Com skills | Sem skills | Skills recomendadas |
...
```
## Referencias
- Mecanismo runtime injection: conteúdo SKILL.md injectado como contexto adicional a cada heartbeat
- API skills: `skills/paperclip/references/company-skills.md`
- Schema BD: tabela `company_skills` (16 colunas)
- Auditoria compatibilidade: `04-Stack/02.06-Clip/auditoria-skills-compatibilidade.md`
- Manual: `06-Operacoes/Documentacao/Manuais/Paperclip/06-skills-e-plugins.md`
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-07","issue":"API /skills/import e /skills/sync sem Authorization header — rejeitadas com 401","fix":"Adicionar -H 'Authorization: Bearer $PAPERCLIP_API_KEY' a todos os curl da skill","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+174
View File
@@ -0,0 +1,174 @@
---
name: clip-vision
category: gestao
description: "Gera documento de visao estrategica para o CEO Paperclip e bootstraps por C-Level. Resolve o vision gap — agentes param porque lhes falta a visao do fundador. Usar quando 'clip vision', 'visao paperclip', 'vision gap', 'bootstrap ceo', 'direcao agentes'."
version: "1.0.0"
created: 2026-04-07
tools: [Read, Write, Bash, AskUserQuestion]
---
# Skill: /clip-vision
Gera documento de visao estrategica para o CEO Paperclip e bootstrap documents para cada C-Level. Baseado no padrao Paperclip Vision Skill (#368 Aron Prins).
---
## Problema que resolve
Agentes Paperclip param de produzir apos setup porque so recebem tarefas operacionais, nao visao estrategica. O CEO nao sabe para onde ir. Os C-Level nao sabem o que priorizar. O "vision gap" faz com que a organizacao funcione mas sem direcao.
---
## Processo de execucao
### Fase 1 — Recolha de contexto (automatica)
Recolher dados do estado actual do Paperclip e do stack:
1. **Ler estado Paperclip:**
- Ficheiro `/home/ealmeida/paperclip/` — listar agents activos
- Desk CRM task #2041 (projecto Stack) — estado
- `Hub/04-Stack/STK-Estado-Actual.md` — metricas actuais
- `Hub/04-Stack/plano-consolidado-stack-q2-2026.md` — plano e metas
2. **Ler issues e routines:**
- Via MCP Paperclip ou ficheiros locais em `/home/ealmeida/paperclip/`
- Issues abertas, routines activas, ultimos heartbeats
3. **Compilar contexto:** resumo de 10-15 linhas com estado actual
### Fase 2 — Entrevista ao fundador (interactiva)
Fazer 5-7 perguntas ao Emanuel usando AskUserQuestion. Cada pergunta com 3-4 opcoes + "outro":
**Pergunta 1:** Qual e a prioridade principal para os proximos 30 dias?
- a) Aumentar receita (novos clientes, propostas)
- b) Melhorar operacoes internas (eficiencia, automacao)
- c) Desenvolver produto/servico novo
- d) Consolidar o que ja existe (qualidade, documentacao)
- e) Outro: ___
**Pergunta 2:** Que departamento precisa de mais atencao neste momento?
- a) D1 Comercial (vendas, leads, propostas)
- b) D6 Marketing (SEO, conteudo, redes sociais)
- c) D7 Tecnologia (infra, dev, automacao)
- d) D3 Contabilidade (facturas, despesas, cash flow)
- e) Outro: ___
**Pergunta 3:** Que nivel de autonomia queres dar aos agentes?
- a) Passive — so actuam quando pedido, sempre com aprovacao
- b) Balanced — actuam em rotinas, pedem aprovacao para novidades
- c) Active — actuam proactivamente, reportam resultados
- d) Manter o actual
**Pergunta 4:** Qual e o budget mensal aceitavel para agentes IA (tokens + APIs)?
- a) <50 EUR/mes (minimo, so essenciais)
- b) 50-100 EUR/mes (moderado)
- c) 100-200 EUR/mes (investimento activo)
- d) >200 EUR/mes (sem restricao significativa)
**Pergunta 5:** Qual e o objectivo principal do Q2 2026?
- a) Facturacao: atingir X EUR/mes
- b) Clientes: fechar N novos contratos
- c) Produto: lancar servico/SaaS especifico
- d) Stack: maximizar capacidade operacional
- e) Outro: ___
**Pergunta 6:** O que deve ser explicitamente proibido para os agentes?
- a) Contactar clientes directamente
- b) Fazer deploy sem aprovacao
- c) Gastar budget acima de X
- d) Todas as anteriores
- e) Outro: ___
**Pergunta 7:** Como medes sucesso dos agentes Paperclip?
- a) Output tangivel (artigos, propostas, deploys)
- b) Reducao de tempo em tarefas manuais
- c) ROI mensuravel (custo vs valor gerado)
- d) Consistencia (fazem sempre o basico bem)
### Fase 3 — Geracao de documentos
Com base nas respostas, gerar 5 documentos:
#### 1. vision.md (destino: /home/ealmeida/paperclip/vision.md)
```markdown
# Visao Descomplicar — {data}
## Missao
{extraido das respostas + contexto}
## Objectivos Q2 2026
1. {objectivo principal}
2. {objectivo secundario}
3. {objectivo terciario}
## Prioridades (30 dias)
1. {prioridade 1 com accao concreta}
2. {prioridade 2}
3. {prioridade 3}
## Restricoes
- {proibicoes definidas na P6}
- Budget maximo: {P4}
- Governance: {P3}
## Metricas de sucesso
- {P7 — como medir}
## Revisao
- Gerado: {data}
- Proxima revisao: {data + 90 dias}
```
#### 2-5. Bootstrap documents (destino: /home/ealmeida/paperclip/)
Para cada C-Level (CEO, CTO, CMO, COO), gerar `{role}-bootstrap.md`:
```markdown
# Bootstrap {Role} — {data}
## Contexto
{estado actual do departamento relevante}
## Top 3 prioridades
1. {prioridade com accao e deadline}
2. {prioridade}
3. {prioridade}
## Recursos disponiveis
- Skills: {lista relevante}
- MCPs: {lista relevante}
- Routines: {activas no departamento}
## Restricoes
- {do vision.md, filtradas para este papel}
## Proxima accao
{1 accao concreta que pode fazer no proximo heartbeat}
```
### Fase 4 — Resumo e confirmacao
Apresentar resumo ao utilizador:
- 5 documentos gerados com paths
- Sugerir proximos passos (injectar vision.md no CEO heartbeat, etc.)
- Perguntar se quer ajustar algo
---
## Notas importantes
- Os documentos devem ser **accionaveis**, nao genericos
- Cada bootstrap deve referenciar **dados reais** do estado actual
- O vision.md deve ser **injectado no CEO** como contexto do heartbeat
- Sugerir /schedule trimestral para refrescar a visao
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+162
View File
@@ -0,0 +1,162 @@
---
name: clip
description: Dashboard rápido Paperclip — estado agentes, issues abertas, heartbeats recentes, alertas. Usar quando "clip", "paperclip", "estado clip", "agentes clip".
context: fork
---
# /clip — Dashboard Paperclip
Dashboard rapido do estado do Clip (Paperclip Orquestrador Descomplicar).
## Constantes
```
BD: PGPASSWORD="paperclip" psql -h localhost -p 54329 -U paperclip -d paperclip
COMPANY_ID: ebe10308-efd7-453f-86ab-13e6fe84004f
```
## Procedimento
Executar os 5 passos em paralelo (silenciosamente), depois apresentar dashboard compacto.
### Passo 1: Estado do servico
```bash
systemctl --user status paperclip 2>&1 | head -5
```
### Passo 2: Agentes por status
Invocar tool MCP: `mcp__paperclip__diag_agents_by_status`
### Passo 3: Issues abertas
```sql
SELECT i.title, i.status, i.priority, a.name as assignee
FROM issues i LEFT JOIN agents a ON i.assignee_agent_id = a.id
WHERE i.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND i.status NOT IN ('done','cancelled')
ORDER BY
CASE i.priority WHEN 'critical' THEN 1 WHEN 'high' THEN 2 WHEN 'medium' THEN 3 ELSE 4 END,
i.status;
```
### Passo 4: Ultimos 10 heartbeats
```sql
SELECT a.name, hr.status, hr.started_at, hr.finished_at
FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
ORDER BY hr.started_at DESC LIMIT 10;
```
### Passo 5: Alertas
Heartbeats falhados nas ultimas 24h:
```sql
SELECT a.name, LEFT(hr.error, 80) as erro, hr.started_at
FROM heartbeat_runs hr JOIN agents a ON hr.agent_id = a.id
WHERE a.company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND hr.status = 'failed'
AND hr.started_at > NOW() - INTERVAL '24 hours'
ORDER BY hr.started_at DESC;
```
Falsos blockers (INC-07):
Invocar tool MCP: `mcp__paperclip__diag_false_blockers`
Se resultado > 0 → listar como alerta: "N issues blocked com sub-tasks activas — provavelmente deveriam ser in_progress".
Token burn — agentes com consumo excessivo de tokens nas últimas 24h (INC-12):
Invocar tool MCP: `mcp__paperclip__diag_heartbeat_token_usage(hours=24)`
Se `agentes_risco > 0` → alertar: "TOKEN BURN: N agentes com runs >500K cache tokens — usar /clip-health check 19 para detalhes".
Routines presas (INC-08) — a ligação issue→routine está em `routine_runs.linked_issue_id`:
Invocar tool MCP: `mcp__paperclip__diag_stuck_routines(hours=4)`
Se `routines_presas > 0` → alertar: "ROUTINE BLOQUEADA: N issues de routine paradas >4h — usar /clip-health check 20".
Budget (agentes com >0 configurado):
```sql
SELECT name, budget_monthly_cents, spent_monthly_cents,
CASE WHEN budget_monthly_cents > 0
THEN ROUND(spent_monthly_cents::numeric / budget_monthly_cents * 100, 1)
ELSE 0 END as pct
FROM agents
WHERE company_id = 'ebe10308-efd7-453f-86ab-13e6fe84004f'
AND budget_monthly_cents > 0
ORDER BY pct DESC;
```
### Passo 6: Saude API (endpoint dashboard)
Verificar se os endpoints criticos respondem:
```bash
HEALTH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3100/api/health)
DASH=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3100/api/companies/ebe10308-efd7-453f-86ab-13e6fe84004f/dashboard)
BADGES=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:3100/api/companies/ebe10308-efd7-453f-86ab-13e6fe84004f/sidebar-badges)
echo "health=$HEALTH dashboard=$DASH badges=$BADGES"
```
- health=200 = OK (sem auth)
- dashboard/badges=401 = OK (auth funciona, endpoint existe)
- dashboard/badges=404 ou 500 = CRITICO (endpoint em falha, provavelmente refs orfas na BD)
Verificar instancias duplicadas:
```bash
ss -tlnp | grep -E "310[0-9]" | wc -l
```
- 1 = OK
- 2+ = AVISO (processos orfaos, recomendar limpeza)
### Passo 7: Company skills
Invocar tool MCP: `mcp__paperclip__diag_company_skills_summary`
## Formato de output
Apresentar como dashboard compacto:
```
## Clip Dashboard — [data/hora]
**Servico:** [running/stopped] ha [tempo]
**Agentes:** [N] total — [n] running, [n] idle, [n] paused
**API:** health=[code] dashboard=[code] badges=[code] | Instancias: [N]
**Skills:** [N] instaladas ([n] locais, [n] skills.sh, [n] github)
### Issues abertas
| Titulo | Status | Prioridade | Assignee |
...
### Heartbeats recentes
| Agente | Status | Inicio | Fim |
...
### Alertas
- [CRITICO] descricao
- [TOKEN BURN] N agentes >500K tokens — /clip-health check 19
- [ROUTINE BLOQUEADA] N issues paradas >4h — /clip-health check 20
```
## Referencias
- Manual: Hub `06-Operacoes/Documentacao/Manuais/Paperclip/`
- API: `04-Stack/02.06-Clip/skills.md`
- Spec: `04-Stack/02.06-Clip/docs/superpowers/specs/2026-03-28-clip-grande-visao-design.md`
---
## 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.*
+110
View File
@@ -0,0 +1,110 @@
---
name: dual-review
description: Revisão dual-model de conteúdo publicável — artigos WordPress, propostas comerciais, relatórios de cliente. Um agente gera com contexto completo, outro revisa sem contexto partilhado. Usar antes de publicar ou enviar a cliente.
context: fork
---
# /dual-review — Revisão Dual-Model
> "Um revisor sem contexto detecta o que o autor não vê."
> Fonte: Eixo 4, Plano Stack Q2 2026.
---
## Quando usar
**OBRIGATÓRIO para:**
- Artigos WordPress antes de publicar
- Propostas comerciais antes de enviar
- Relatórios de cliente antes de entregar
- Qualquer conteúdo com dados factuais (métricas, preços, datas)
**Não usar para:**
- Comentários internos no CRM
- Notas de trabalho
- Código (usar `superpowers:requesting-code-review`)
---
## Workflow (4 passos)
### Passo 1 — Gerar conteúdo (agente principal)
Gerar o conteúdo com contexto completo. Marcar dados não confirmados como `[VERIFICAR: X]`.
### Passo 2 — Preparar para revisão
Extrair apenas o output final + definir critérios. **Não incluir o contexto de geração.**
```
CONTEÚDO PARA REVISÃO:
[colar apenas o output final]
CRITÉRIOS:
1. Factos verificados (sem "[VERIFICAR: X]" por resolver)
2. URLs funcionais e correctas
3. Datas e valores em EUR correctos
4. PT-PT (não brasileiro): tu/você, descarregar/baixar, ficheiro/arquivo
5. Acentos correctos: á, à, â, ã, é, ê, í, ó, ô, õ, ú, ç
6. Coerência interna (sem contradições)
7. Adequação ao público-alvo
JUDGMENT FRAMEWORK:
[incluir exemplos relevantes de ~/.claude/design/judgment-frameworks/]
```
### Passo 3 — Revisão por segundo agente
Usar `Agent tool` com `model: "sonnet"` passando APENAS o conteúdo + critérios.
Instrução ao segundo agente:
```
És um revisor de qualidade de conteúdo. Verifica o texto contra os critérios fornecidos.
NÃO tens contexto sobre como foi gerado — avalia apenas o output final como leitor externo.
Lista cada problema com localização exacta, ou responde "APROVADO" se não há problemas.
```
### Passo 4 — Corrigir e repetir
Se o revisor retornar problemas:
1. Corrigir cada problema no conteúdo
2. Re-submeter (Passos 2-3)
3. Repetir até "APROVADO" ou máximo 3 iterações
Se após 3 iterações ainda há problemas: escalar ao utilizador com lista de pendentes.
---
## Judgment Frameworks disponíveis
- `~/.claude/design/judgment-frameworks/global.md` — anti-alucinação geral
- `~/.claude/design/judgment-frameworks/wordpress.md` — conteúdo e código WP
- `~/.claude/design/judgment-frameworks/crm.md` — operações CRM
Incluir o framework relevante nos critérios do Passo 2.
---
## Exemplo de uso
```
# Artigo WordPress sobre X gerado. Antes de publicar:
/dual-review
Conteúdo: [artigo completo]
Tipo: artigo-wordpress
Público: PMEs portuguesas
Judgment: ~/.claude/design/judgment-frameworks/wordpress.md
```
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-06","issue":"Placeholder vazio sem validacao previa","fix":"Validacao completa: frontmatter OK (name/description/context), paths judgment-frameworks OK (global/wordpress/crm), workflow 4 passos coerente. Nenhuma correccao necessaria.","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*
+229
View File
@@ -0,0 +1,229 @@
---
name: hub-compile
description: Compilador do 00-Inbox do Hub Obsidian. Classifica ficheiros .md, gera resumos, sugere destino e backlinks, move com aprovação explícita do utilizador. Usar quando "hub-compile", "compilar inbox", "triagem inbox", "processar inbox", "classificar notas".
context: fork
---
# /hub-compile v1.0 — Compilador do Hub Inbox
Processa automaticamente os ficheiros `.md` em `00-Inbox/` do Hub Obsidian: classifica, resume, sugere destino e backlinks, e move apenas com aprovação explícita.
---
## Filosofia
Padrão Karpathy (Raw → Compiler → Wiki): o LLM actua como compilador — lê ficheiros em bruto, extrai estrutura e significado, e propõe organização. O utilizador aprova antes de qualquer movimento.
**Princípio cardinal: NUNCA mover sem aprovação.**
---
## Protocolo de Execução
```
1. LER ficheiros do Inbox
2. CLASSIFICAR cada ficheiro
3. APRESENTAR tabela ao utilizador
4. AGUARDAR aprovação
5. MOVER os aprovados
6. ACTUALIZAR INDEX.md de origem e destino
```
---
## Passo 1 — Ler Inbox
```
- Listar TODOS os .md em /media/ealmeida/Dados/Hub/00-Inbox/
- EXCLUIR INDEX.md
- Para cada ficheiro: ler conteúdo completo
```
---
## Passo 2 — Classificar
Para cada ficheiro, determinar:
### Tipo
| Tipo | Indicadores |
|------|-------------|
| `worklog` | "Worklog", datas de sessão, tool calls, MCPs usados |
| `prompt` | "Prompt", instruções para Claude, specs de módulo |
| `nota-tecnica` | Configurações, comandos, troubleshooting, fixes |
| `planeamento` | "Plano", "migração", "roadmap", decisões activas |
| `facturacao` | Facturas, recibos, datas limite, valores |
| `migracao` | "Migração", "setup", hardware novo, configurações pendentes |
| `stress-test` | Resultados de testes, benchmarks, métricas |
| `outro` | Não se encaixa nas categorias acima |
### Destino Sugerido
| Tipo | Destino |
|------|---------|
| `worklog` | `99-Arquivo/Worklogs/YYYY/MM/` |
| `prompt` | `99-Arquivo/Documentacao-Pontuais/` |
| `nota-tecnica` com valor permanente | `06-Operacoes/Knowledge-Base/MDs/` |
| `nota-tecnica` pontual/resolvida | `99-Arquivo/Documentacao-Pontuais/` |
| `planeamento` activo | **MANTER** (fica no Inbox) |
| `facturacao` | `99-Arquivo/Documentacao-Pontuais/` |
| `migracao` activa | **MANTER** (fica no Inbox) |
| `stress-test` | `99-Arquivo/Documentacao-Pontuais/` |
| `outro` | Consultar utilizador |
### Acção
| Acção | Significado |
|-------|-------------|
| `mover` | Pronto para mover para o destino sugerido |
| `arquivar` | Mover para `99-Arquivo/` |
| `manter` | Deixar no Inbox — activo ou precisa mais trabalho |
| `eliminar` | Duplicado, vazio, ou sem valor — confirmar antes |
### Gerar por ficheiro
- **Resumo:** 2-3 linhas descrevendo o conteúdo essencial
- **Conceitos-chave:** 3-5 termos ou tópicos principais
- **Backlinks sugeridos:** docs existentes no Hub que devem referenciar este ficheiro ou ser referenciados por ele (usar conhecimento do vault — QR-*, PROC-*, etc.)
---
## Passo 3 — Apresentar Tabela
Mostrar ao utilizador antes de qualquer acção:
```markdown
## Hub Compile — Inbox Analysis
**N ficheiros encontrados** | Data: YYYY-MM-DD HH:MM
| # | Ficheiro | Tipo | Acção | Destino | Resumo |
|---|----------|------|-------|---------|--------|
| 1 | `nome.md` | worklog | mover | 99-Arquivo/Worklogs/2026/03/ | Sessão de 31 Mar: implementação X, Y, Z. Duração ~2h. |
| 2 | `nome.md` | planeamento | manter | — (Inbox) | Migração Alurin em curso. Pendentes: configurar Syncthing. |
| 3 | `nome.md` | prompt | mover | 99-Arquivo/Documentacao-Pontuais/ | Prompt para módulo Moloni-Perfex sync. Concluído. |
### Backlinks Sugeridos
| Ficheiro | Backlink para |
|----------|--------------|
| `stress-tests-alurin.md` | `QR-Servidores.md`, `infra.md` (memory) |
| `worklog-2026-03-31.md` | Discussão Logs #31 Desk CRM |
---
**Aprovação necessária.**
Para aprovar todos os movimentos sugeridos: escrever `aprovar tudo`
Para aprovar individualmente: escrever `aprovar 1,3,5` (números da tabela)
Para ajustar uma acção: escrever `1=arquivar` ou `2=eliminar`
Para cancelar: escrever `cancelar`
```
---
## Passo 4 — Aguardar Aprovação
**PARAR aqui. Não executar nada antes da resposta do utilizador.**
Interpretar respostas:
- `aprovar tudo` → processar todos os `mover` e `arquivar` (nunca os `manter`)
- `aprovar 1,3` → processar apenas linhas 1 e 3
- `1=arquivar` → alterar acção da linha 1 para arquivar
- `cancelar` → terminar sem mover nada
---
## Passo 5 — Mover Ficheiros Aprovados
Para cada ficheiro aprovado com acção `mover` ou `arquivar`:
```
1. Verificar se directório de destino existe
- SE não existe: criar com mcp__filesystem__create_directory
2. Mover ficheiro: mcp__filesystem__move_file
3. Confirmar que ficheiro chegou ao destino
4. Registar movimento para actualização de INDEX.md
```
**Formato do path de destino:**
- Worklogs: `/media/ealmeida/Dados/Hub/99-Arquivo/Worklogs/YYYY/MM/nome.md`
- Documentação pontual: `/media/ealmeida/Dados/Hub/99-Arquivo/Documentacao-Pontuais/nome.md`
- Knowledge-Base: `/media/ealmeida/Dados/Hub/06-Operacoes/Knowledge-Base/MDs/nome.md`
---
## Passo 6 — Actualizar INDEX.md
### INDEX.md do Inbox (00-Inbox/INDEX.md)
Remover entradas dos ficheiros movidos. Se INDEX.md não tiver lista estruturada, adicionar nota de actualização no topo.
### INDEX.md do Destino
Para cada destino com movimentos:
1. Ler INDEX.md existente (se existir)
2. Adicionar entradas dos ficheiros movidos
3. Se INDEX.md não existir e destino tem >3 ficheiros → criar
**Formato de entrada no INDEX.md:**
```markdown
| `nome-ficheiro.md` | Tipo | YYYY-MM-DD | Descrição breve |
```
---
## Output Final
```markdown
## Hub Compile — Concluído
**Movidos:** N ficheiros
**Mantidos no Inbox:** M ficheiros
**Eliminados:** 0 (requer confirmação separada)
### Movimentos Realizados
- `worklog-2026-03-31.md` → 99-Arquivo/Worklogs/2026/03/
- `prompt-modulo-moloni.md` → 99-Arquivo/Documentacao-Pontuais/
### Mantidos
- `migracao-alurin-mini-pc.md` — migração activa
- `NovoPC.md` — planeamento em curso
### INDEX.md Actualizados
- 00-Inbox/INDEX.md ✓
- 99-Arquivo/Worklogs/2026/03/INDEX.md ✓
- 99-Arquivo/Documentacao-Pontuais/INDEX.md ✓
```
---
## Regras Obrigatórias
1. **NUNCA mover sem aprovação explícita** do utilizador
2. **Worklogs** vão sempre para `99-Arquivo/Worklogs/YYYY/MM/`
3. **Planeamento activo** e **migração em curso** ficam sempre no Inbox (`manter`)
4. **Prompts concluídos** vão para `99-Arquivo/Documentacao-Pontuais/`
5. **Notas técnicas com valor permanente** vão para `06-Operacoes/Knowledge-Base/MDs/`
6. **Eliminar** requer confirmação separada — nunca eliminar na aprovação em massa
7. **INDEX.md** deve ser actualizado em origem e destino após cada movimento
8. **Usar mcp__filesystem__*** para todas as operações de ficheiros
---
## Anti-Patterns
- **NUNCA** mover com `aprovar tudo` sem excluir os `manter`
- **NUNCA** criar destinos sem verificar se já existem
- **NUNCA** omitir actualização dos INDEX.md
- **NUNCA** classificar como `eliminar` sem justificação clara
- **NUNCA** confundir planeamento activo com documentação pontual
---
*Skill v1.0 | 2026-04-07 | Descomplicar®*
+255
View File
@@ -0,0 +1,255 @@
---
name: monday-briefing
description: Briefing semanal automatizado com 4 componentes — tendências de mercado, métricas chave, acção da semana e contra-argumentos. Usar quando "monday", "briefing segunda", "resumo semanal", "briefing semana", "monday briefing".
context: fork
---
# /monday-briefing v1.0
Briefing semanal com 4 perspectivas: tendências, métricas, acção e realidade.
---
## Protocolo
### Passo 1: Recolher data e período
```
mcp__mcp-time__current_time → data actual
Calcular:
- semana_actual: Segunda a Domingo desta semana
- semana_anterior: Segunda a Domingo da semana passada
- periodo_atual: "Semana W{N} ({DD Mmm} {DD Mmm YYYY})"
```
### Passo 2: Recolher dados em paralelo
> Executar TUDO em paralelo. Registar erros sem bloquear — continuar com dados disponíveis.
```
Em paralelo:
[A] DESK CRM — Métricas da semana
mcp__desk-crm-v3__get_tasks({ date_from: inicio_semana_anterior, date_to: fim_semana_anterior, status: 5 })
→ tarefas_concluidas_semana_ant
mcp__desk-crm-v3__get_tasks({ date_from: inicio_semana, date_to: fim_semana, status: [1,2,3] })
→ tarefas_abertas_semana_atual
mcp__desk-crm-v3__get_timesheets({ date_from: inicio_semana_anterior, date_to: fim_semana_anterior })
→ horas_semana_ant
mcp__desk-crm-v3__get_tickets({ status: [1,2,3] })
→ tickets_abertos
[B] MOLONI — Facturação da semana
mcp__moloni-mcp__list_documents({
document_type: "invoice",
date_from: inicio_semana_anterior,
date_to: fim_semana_anterior
})
→ facturas_semana_ant (valor total + contagem)
mcp__moloni-mcp__list_documents({
document_type: "invoice",
date_from: inicio_semana,
date_to: fim_semana
})
→ facturas_semana_atual (se já existirem)
[C] DESK CRM — Leads e pipeline
mcp__desk-crm-v3__get_leads({ status: [7,14], limit: 20 })
→ leads_novos
mcp__desk-crm-v3__get_estimates({ status: [3,4], limit: 20 })
→ propostas_pipeline
[D] TENDÊNCIAS — WebSearch
WebSearch: "marketing digital tendencias semana {data_atual}"
WebSearch: "SEO updates {mes} {ano}"
WebSearch: "WordPress news {mes} {ano}"
→ 3 tendências relevantes ao negócio Descomplicar
[E] GOOGLE WORKSPACE — Agenda da semana
mcp__google-workspace__calendar_get_events({
user_google_email: "emanuelalmeidaa@gmail.com",
time_min: "{inicio_semana}T00:00:00Z",
time_max: "{fim_semana}T23:59:59Z"
})
→ eventos_semana
```
### Passo 3: Calcular métricas comparativas
```
Calcular variações:
delta_horas = horas_semana_ant vs semana anterior a essa (% variação)
delta_facturas = valor_semana_ant vs média das últimas 4 semanas
taxa_conclusao = tarefas_concluidas / (tarefas_concluidas + abertas) * 100
SE dados incompletos: usar "N/D" e indicar fonte em falta
```
### Passo 4: Gerar briefing em 4 secções
---
## Output
```markdown
# Monday Briefing — {periodo_atual}
*Gerado em {data_hora_atual} | Descomplicar®*
---
## 1. Trend Researcher — O Que Mudou Esta Semana
> Tendências relevantes para o negócio (marketing digital, SEO, WordPress, automação)
**[Tendência 1]**
_Fonte: [URL]_
Impacto potencial: [curto resumo do que muda para a Descomplicar]
**[Tendência 2]**
_Fonte: [URL]_
Impacto potencial: [curto resumo]
**[Tendência 3]**
_Fonte: [URL]_
Impacto potencial: [curto resumo]
---
## 2. Analytics Reporter — Métricas vs Semana Anterior
### Produtividade
| Métrica | Semana Anterior | Esta Semana | Δ |
|---------|----------------|-------------|---|
| Horas registadas | X h | Y h | ±Z% |
| Tarefas concluídas | X | Y | ±Z |
| Tickets abertos | X | Y | ±Z |
### Pipeline Comercial
| Métrica | Valor | Estado |
|---------|-------|--------|
| Facturação semana ant | {valor} EUR | {vs média} |
| Leads novos | X | — |
| Propostas pendentes | X | Total: Y EUR |
| Propostas aceites | X | Total: Y EUR |
### Agenda da Semana
| Data | Evento |
|------|--------|
| {DD Mmm} | {evento} |
| … | … |
> Fontes: Desk CRM + Moloni + Google Calendar
> Dados Google Analytics / GSC: configurar via /n8n-webhook ou GSC MCP
---
## 3. Growth Hacker — 1 Acção Para Esta Semana
**Acção:** [Nome curto e concreto]
**Porquê agora:** [Justificação baseada nos dados das secções 1 e 2]
**3 Passos para executar:**
1. **[Passo 1]** — [Descrição detalhada, quem faz, quando]
2. **[Passo 2]** — [Descrição detalhada, ferramentas necessárias]
3. **[Passo 3]** — [Métrica de validação: como saber que funcionou]
**Tempo estimado:** X horas
**Impacto esperado:** [Métrica específica]
---
## 4. Reality Checker — Contra-Argumentos
> Questionar os pressupostos das secções anteriores antes de agir.
**Sobre as tendências (secção 1):**
- [Contra-argumento]: Pode ser que [tendência X] não se aplique porque [razão específica ao contexto Descomplicar]
- Pergunta a fazer: Temos capacidade para responder a esta tendência esta semana?
**Sobre as métricas (secção 2):**
- [Contra-argumento]: A variação de [±Z%] pode ser [sazonalidade / evento pontual / dado incompleto]
- Atenção: [Métrica Y] está a [subir/descer] — verificar se é tendência real ou ruído
**Sobre a acção (secção 3):**
- [Contra-argumento]: A acção proposta assume que [pressuposto] — validar antes de executar
- Risco principal: [O que pode correr mal e como mitigar]
- Alternativa mais simples: [Versão reduzida da acção com menor risco]
---
*Próximo briefing: Segunda, {data_prox_segunda} 09:00*
*Para agendar: `/schedule "monday-briefing" cron:"0 9 * * 1"`*
```
---
## Envio Automático (opcional)
```
SE argumento "email":
mcp__google-workspace__gmail_send_email({
to: "emanuelalmeidaa@gmail.com",
subject: "Monday Briefing — {periodo_atual}",
body: {output_markdown_acima},
format: "html"
})
SE argumento "inbox" OU sem argumento:
Guardar em: /media/ealmeida/Dados/Hub/00-Inbox/monday-briefing-{YYYY-MM-DD}.md
Formato: frontmatter YAML + conteúdo markdown
SE argumento "terminal":
Mostrar directamente no terminal (default)
```
---
## Como Agendar
Para receber automaticamente todas as segundas às 9h:
```bash
# Via skill /schedule:
/schedule "monday-briefing" cron:"0 9 * * 1"
```
---
## Fontes de Dados
| Fonte | MCP / Ferramenta | Dados |
|-------|-----------------|-------|
| Desk CRM | `mcp__desk-crm-v3` | Tarefas, tickets, timesheets, leads, propostas |
| Moloni | `mcp__moloni-mcp` | Facturação semanal |
| Google Calendar | `mcp__google-workspace` | Agenda da semana |
| Tendências | `WebSearch` | Novidades mercado digital |
| Google Analytics | n8n BI workflow | Sessions, conversões (a configurar) |
| Google Search Console | GSC MCP (quando disponível) | Keywords, cliques orgânicos |
> GA4 e GSC: quando MCPs dedicados estiverem configurados, adicionar ao Passo 2[A]. Ver `/n8n-webhook` para workflow BI existente.
---
## Anti-Patterns
- NUNCA bloquear o briefing por falta de dados GA4/GSC — usar "N/D" e continuar
- NUNCA inventar tendências — apenas WebSearch com fontes verificáveis
- NUNCA recomendar mais de 1 acção na secção 3 (Growth Hacker)
- SEMPRE usar mcp-time para calcular períodos (nunca assumir datas)
- SEMPRE incluir secção Reality Checker — é o que diferencia este briefing
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
*Adicionar nova linha após cada erro corrigido.*
---
*Skill v1.0.0 | 07-04-2026 | Descomplicar®*
+27 -7
View File
@@ -1,6 +1,6 @@
--- ---
name: reflect name: reflect
description: Alias de /worklog. Auto-reflexão e registo de trabalho unificado. /reflect = /worklog (mesmo resultado). /reflect deep = análise profunda com histórico. /reflect week = revisão semanal. Usar quando "reflect", "reflexão", "análise", "melhoria", "insight". description: Alias de /worklog. Auto-reflexão e registo de trabalho unificado. /reflect = /worklog (mesmo resultado). /reflect view = ver últimos registos. /reflect deep = análise profunda com histórico → Discussão #32. /reflect week = revisão semanal → Discussão #32. Usar quando "reflect", "reflexão", "análise", "melhoria", "insight".
context: fork context: fork
--- ---
@@ -8,15 +8,18 @@ context: fork
**`/reflect` = `/worklog`** - Produzem o mesmo resultado. **`/reflect` = `/worklog`** - Produzem o mesmo resultado.
Desde v4.0, worklog e reflect estao unificados. Toda a logica, formatos e workflows estao em `/worklog`. Desde v4.0, worklog e reflect estao unificados. Toda a logica, formatos e workflows estao em `/worklog` (v4.2.0).
## Comandos ## Comandos
| Comando | Equivalente | Descrição | | Comando | Equivalente worklog | Descrição |
|---------|-------------|-----------| |---------|---------------------|-----------|
| `/reflect` | `/worklog` | Registo + reflexão da sessão → Discussão #31 | | `/reflect` | `/worklog` | Registo + reflexão da sessão → Discussão #31 |
| `/reflect deep` | (exclusivo) | Análise profunda com histórico → Discussão #32 | | `/reflect view` | `/worklog view` | Ver últimos registos (discussão #31) |
| `/reflect week` | (exclusivo) | Revisão semanal → Discussão #32 | | `/reflect deep` | `/reflect deep` | Análise profunda com histórico → Discussão #32 |
| `/reflect week` | `/reflect week` | Revisão semanal → Discussão #32 |
> **Nota:** `/reflect deep` e `/reflect week` são comandos partilhados — existem tanto no worklog como aqui. Não são exclusivos do reflect.
## Instrução ## Instrução
@@ -24,9 +27,26 @@ Ao receber `/reflect` (sem argumentos):
1. Executar exactamente o protocolo de `/worklog` 1. Executar exactamente o protocolo de `/worklog`
2. Ver skill `/worklog` (SKILL.md) para formato, workflow e storage 2. Ver skill `/worklog` (SKILL.md) para formato, workflow e storage
Ao receber `/reflect view`:
1. Executar o protocolo de `/worklog view` (ver secção em `/worklog` SKILL.md)
Ao receber `/reflect deep` ou `/reflect week`: Ao receber `/reflect deep` ou `/reflect week`:
1. Ver secções específicas na skill `/worklog` 1. Ver secções específicas na skill `/worklog`
--- ---
*Skill v4.0.0 | 2026-02-06 | Descomplicar(R)* *Skill v4.0.1 | 2026-04-06 | Descomplicar(R)*
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"2026-04-06","issue":"Comandos /reflect deep e /reflect week marcados como '(exclusivo)' na tabela mas existem no worklog SKILL.md — causava confusão sobre origem dos comandos","fix":"Remover '(exclusivo)', mapear correctamente para equivalente worklog e adicionar nota explicativa","source":"auto"}
{"date":"2026-04-06","issue":"Versão reflect desactualizada (v4.0.0) face a worklog (v4.2.0) — utilizador podia assumir reflect obsoleto","fix":"Actualizar referência de versão do worklog para v4.2.0 na descrição; reflect mantém v4.0.1 (alias sem lógica própria)","source":"auto"}
{"date":"2026-04-06","issue":"/worklog view não referenciado em reflect — utilizador com /reflect não sabia como ver registos anteriores","fix":"Adicionar /reflect view como alias de /worklog view na tabela de comandos e na secção de instrução","source":"auto"}
```
*Adicionar nova linha após cada erro corrigido.*