Compare commits

...

21 Commits

Author SHA1 Message Date
ealmeida d3f9c950cd fix(worklog): v4.1 — proíbe fork via Skill/Agent tool (perde contexto)
Skills /worklog e /reflect dependem do histórico conversacional do agente
principal. Invocá-las via Skill tool ou Agent tool cria subagente sem
contexto e reporta 'nothing to log'. Banner obrigatório no topo, fonte A
(conversa) reforçada como primária, fonte C (activity log) rebaixada para
fallback.

Incidente 2026-04-23: após 28h+ trabalho Observabilidade, /worklog via
Skill tool retornou vazio.
2026-04-23 03:35:40 +01:00
ealmeida b6690a75fd feat(today): v11.0 — migração para cron local desktop (CT 102 eliminado)
- Remove SSH dev, todos os logs lidos localmente em /media/ealmeida/Dados/Dev/claude_automations_dev/
- Actualiza descrição, arquitectura e tabela de agentes
- Adiciona weekly-digest-podcast, improvement-evaluator, gitea-ci-cleaner
- Remove referência ao ct-backup-unlock-watchdog (CT 102 eliminado)
2026-04-20 13:28:44 +01:00
ealmeida b3cb108ca7 feat(gestao): remover LightRAG das skills de knowledge — Fase 1 RAG-System
- knowledge/SKILL.md v2.2.0: Família A passa a 4 fontes (Supabase, CC memory, Hub, Desk CRM)
- hub-search/SKILL.md v1.1.0: RAG Trinity actualizada (2 layers)
- research-pipeline/SKILL.md v1.1.0: Layer 3 LightRAG removida
- deep-research/SKILL.md v1.1.0: Layer 3 passa a Web apenas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:21:45 +01:00
ealmeida dada9ef7db feat(skills): integra consulta ao Media Bank D7-MB-001 2026-04-08 23:18:23 +01:00
ealmeida 82063391dd feat(skills): integra consulta ao Media Bank D7-MB-001 2026-04-08 23:18:22 +01:00
ealmeida 940c3903aa feat(skills): integra consulta ao Media Bank D7-MB-001 2026-04-08 23:18:21 +01:00
ealmeida c534051774 feat(gestao/knowledge): v2.1.1 — 17 tools LightRAG-HKU reais
Actualização derivada da restauração do LightRAG-HKU no gateway
(ver Hub/04-Stack/CHANGELOG.md sessão 3 extensão).

A v2.1.0 tinha sido escrita assumindo FastMCP file-based com 11 tools
(lightrag_query, lightrag_stats, etc) porque outra sessão tinha
migrado temporariamente o backend. Essa migração foi revertida e o
stack voltou ao LightRAG-HKU 1.4.13 completo com 17 tools originais.

Mudanças:
- Router Família A agora usa mcp__lightrag__query_document (não lightrag_query)
- Documentada a lista completa de 17 tools MCP (query, insert, pipeline, graph edit)
- Referência à UI rag.descomplicar.pt/webui
- PG storage notado (331 docs workspace default)
- Graceful fallback para mcp__memory-supabase__ quando MCP indisponível

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:17:17 +01:00
ealmeida 1d0b2b5441 feat(gestao/knowledge): v2.1.0 router Família A/B
Correcção arquitectural 08-04-2026. A v2.0.0 tratava NotebookLM como
fonte primária. Isso estava errado — NotebookLM não vê operações, só
tem ebooks e transcripts. Racional em memory/feedback_knowledge-router-
arquitectura.md.

Nova arquitectura (não é fallback linear, é router por tipo):

- Família A (operacional interna, paralelo): LightRAG + memory-supabase +
  grep ~/.claude/projects/*/memory/ cross-projecto + Obsidian/Hub + Desk CRM
- Família B (externa, NotebookLM): só conceptual/teórico/research/mercado
- Ambíguo: perguntar ao utilizador

Tools LightRAG actualizadas para as reais (FastMCP file-based,
confirmadas na recuperação sessão 3 do plano gaps): lightrag_query
(hybrid), lightrag_stats, lightrag_get_entity, lightrag_get_graph.

Grep cross-projecto obrigatório em ~/.claude/projects/*/memory/*.md
(101 ficheiros em 34 projectos) porque o harness só carrega
automaticamente a memória do cwd — este é um gap de contexto do CC
que nenhum sistema anterior endereçava.

Mantidas as tabelas de routing NotebookLM como Família B.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 17:01:44 +01:00
ealmeida 3115ff24a5 chore: remove __pycache__ acidentalmente committed 2026-04-07 05:13:20 +01:00
ealmeida a33c5e1b05 feat(design-media): /clone-style — extracção de design tokens (web + pptx)
Resolve dor real: clonar estilos visuais de sites e slides para propostas.
Tentativas anteriores (Penpot, scrapers HTML, Figma import) falharam porque
tentavam reproduzir layouts. Esta skill extrai tokens (cores, fontes,
espaçamento, raios, sombras) e alimenta gerador (Stitch / design-engine).

Modos:
- /clone-style web <url>: extract-web-tokens.js via chrome real (CSS computado)
- /clone-style slides <pptx>: extract-pptx-theme.py (theme1.xml + slideMasters)
- /clone-style apply <tokens.json>: mapeia para Stitch / design-engine / pptx

Validado: PPTX (Calibri/Calibri Light + 6 accent colors do Office default theme).
Web: aguarda primeiro teste end-to-end com browser real.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 05:13:16 +01:00
ealmeida 37f62eb733 chore(design-media): suspender Penpot, adoptar Stitch como motor principal web/ui
- /penpot-pipeline arquivada (backup GDrive)
- /design v2.1.0: routing actualizado, MCPs reduzidos 5→4, Penpot removido
- design-engine assume infographic/social/logo (era Penpot)
- Stitch assume web/landing/ui (era também Stitch, agora primário)

Decisão sessão 5 (07-04): match com workflow real (mockups para propostas).
Penpot exigia build manual; Stitch faz text→UI generation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 05:06:20 +01:00
ealmeida 2ec16674c2 chore(skills): consolidar n8n-* (6→1) e cwp-* (8→1) em meta-skills
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 05:00:35 +01:00
ealmeida faef9b47dc fix(project-manager): remover Dify KB das descriptions, marcar nota TODO
Dify foi removido 06-03-2026. Skills brainstorm/discover ainda referenciam-no
no corpo. Bump v1.2 + nota top-of-file. Reescrita workflow para próxima sessão.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 04:52:03 +01:00
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
207 changed files with 15316 additions and 4542 deletions
+1
View File
@@ -0,0 +1 @@
design-media/skills/*/references/__pycache__/
+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
+328
View File
@@ -0,0 +1,328 @@
---
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 `gateway.descomplicar.pt`.
## Contexto
```
Repositórios Gitea:
acidaos-core → Rust Core
acidaos-dashboard → Next.js Dashboard
Runners:
self-hosted @ gateway.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
---
## 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.*
+203
View File
@@ -0,0 +1,203 @@
---
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
---
## 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.*
+244
View File
@@ -0,0 +1,244 @@
---
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
---
## 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.*
+251
View File
@@ -0,0 +1,251 @@
---
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
---
## 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.*
+12
View File
@@ -104,3 +104,15 @@ A sandbox fornece um ambiente isolado com dados fictícios para desenvolvimento
- **[references/endpoints.md](references/endpoints.md)** - Catálogo completo de endpoints
- **Docs oficiais:** https://www.moloni.pt/dev/endpoints/
- **Sandbox:** https://www.moloni.pt/dev/sandbox/
---
## 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.*
-301
View File
@@ -1,301 +0,0 @@
---
name: n8n-chatbot
description: Criação de chatbots e workflows com inteligência artificial usando LangChain no n8n.
---
# /n8n-chatbot - Chatbots e AI Agents n8n
Criar chatbots e workflows com AI usando LangChain.
## Contexto NotebookLM
ANTES de executar, consultar notebooks para contexto especializado:
| Notebook | ID | Consultar quando |
|----------|-----|-----------------|
| n8n Deep Research | f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1 | Sempre |
```
mcp__notebooklm__notebook_query({
notebook_id: "f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1",
query: "<adaptar ao contexto do pedido do utilizador>"
})
```
Integrar insights do NotebookLM nas recomendações e decisões.
---
## Uso
```
/n8n-chatbot create <descrição> # Criar chatbot
/n8n-chatbot agent <tipo> # Criar AI agent
/n8n-chatbot rag <knowledge_base> # Criar sistema RAG
```
---
## Workflow Obrigatório
```
1. Health check → mcp__n8n__n8n_health_check()
2. Pesquisar template → mcp__n8n__search_templates({ task: "ai_automation" })
3. Se template OK → mcp__n8n__n8n_deploy_template()
4. Se criar do zero → Seguir fluxo abaixo
```
---
## Nodes LangChain
### Core
| Node | Uso |
|------|-----|
| `@n8n/n8n-nodes-langchain.agent` | AI Agent principal |
| `@n8n/n8n-nodes-langchain.chainLlm` | Chain LLM simples |
| `@n8n/n8n-nodes-langchain.chainRetrievalQa` | RAG Q&A |
### Modelos
| Node | Provider |
|------|----------|
| `@n8n/n8n-nodes-langchain.lmChatOpenAi` | OpenAI GPT |
| `@n8n/n8n-nodes-langchain.lmChatAnthropic` | Claude |
| `@n8n/n8n-nodes-langchain.lmChatOllama` | Ollama local |
### Memória
| Node | Tipo |
|------|------|
| `@n8n/n8n-nodes-langchain.memoryBufferWindow` | Últimas N mensagens |
| `@n8n/n8n-nodes-langchain.memoryPostgresChat` | PostgreSQL |
| `@n8n/n8n-nodes-langchain.memoryRedisChat` | Redis |
### Tools
| Node | Função |
|------|--------|
| `@n8n/n8n-nodes-langchain.toolCalculator` | Cálculos |
| `@n8n/n8n-nodes-langchain.toolCode` | Executar código |
| `@n8n/n8n-nodes-langchain.toolHttpRequest` | Chamar APIs |
| `@n8n/n8n-nodes-langchain.toolWorkflow` | Chamar workflows |
### Vector Stores (RAG)
| Node | Sistema |
|------|---------|
| `@n8n/n8n-nodes-langchain.vectorStoreSupabase` | Supabase |
| `@n8n/n8n-nodes-langchain.vectorStorePinecone` | Pinecone |
| `@n8n/n8n-nodes-langchain.vectorStorePgVector` | PostgreSQL |
---
## Chatbot Básico
### Estrutura
```
Webhook/Trigger
LLM Chat Model (OpenAI/Claude)
Memory (Buffer)
Agent
Resposta
```
### Implementação
```javascript
// 1. Modelo LLM
mcp__n8n__get_node({
nodeType: "@n8n/n8n-nodes-langchain.lmChatOpenAi",
detail: "standard"
})
// 2. Memória
mcp__n8n__get_node({
nodeType: "@n8n/n8n-nodes-langchain.memoryBufferWindow",
detail: "standard"
})
// 3. Agent
mcp__n8n__get_node({
nodeType: "@n8n/n8n-nodes-langchain.agent",
detail: "standard"
})
```
---
## RAG (Retrieval Augmented Generation)
### Estrutura
```
Documentos
Embeddings
Vector Store
Query (pergunta)
Retriever
LLM (resposta contextualizada)
```
### Configuração Vector Store
```javascript
mcp__n8n__validate_node({
nodeType: "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
config: {
mode: "insert", // ou "retrieve"
tableName: "documents",
queryName: "match_documents"
},
mode: "minimal"
})
```
---
## AI Agent com Tools
### Estrutura
```
Input
Agent
├── Tool: Calculator
├── Tool: HTTP Request
├── Tool: Code
└── Tool: Workflow
Output
```
### Configuração Agent
```javascript
mcp__n8n__validate_node({
nodeType: "@n8n/n8n-nodes-langchain.agent",
config: {
agentType: "conversationalAgent",
systemMessage: "Tu és um assistente prestável...",
options: {
returnIntermediateSteps: true
}
},
mode: "minimal"
})
```
---
## Exemplos Práticos
### Chatbot de Suporte
```
Webhook (mensagem cliente)
Memory PostgreSQL (histórico)
Vector Store (docs suporte)
Chain Retrieval QA
Webhook Response
```
### Agent CRM
```
Webhook (comando)
Agent
├── Tool: Pesquisar clientes
├── Tool: Criar lead
└── Tool: Actualizar tarefa
Slack (resultado)
```
### Resumo de Documentos
```
Webhook (upload PDF)
PDF Extract
Text Splitter
LLM Chain (resumo)
Email (enviar resumo)
```
---
## Templates Recomendados
```javascript
// AI templates
mcp__n8n__search_templates({
searchMode: "by_task",
task: "ai_automation"
})
// Por keyword
mcp__n8n__search_templates({
searchMode: "keyword",
query: "chatbot langchain openai"
})
```
---
## Credenciais Necessárias
| Provider | Credencial | Node |
|----------|------------|------|
| OpenAI | API Key | lmChatOpenAi |
| Anthropic | API Key | lmChatAnthropic |
| Supabase | URL + Key | vectorStoreSupabase |
| Pinecone | API Key | vectorStorePinecone |
---
## Boas Práticas
| Prática | Razão |
|---------|-------|
| System prompt claro | Define comportamento |
| Temperatura baixa (0.1-0.3) | Respostas consistentes |
| Memória limitada | Performance |
| Retry on error | Resiliência |
| Logs de conversas | Debug e melhoria |
---
## Troubleshooting
| Problema | Solução |
|----------|---------|
| Respostas inconsistentes | Baixar temperatura |
| Contexto perdido | Verificar memória |
| RAG não encontra | Verificar embeddings |
| Timeout | Aumentar limite |
| Token limit | Resumir contexto |
---
*Skill v1.0 | Descomplicar®*
-114
View File
@@ -1,114 +0,0 @@
---
name: n8n-health
description: Diagnóstico de conectividade e estado da instância n8n. Verificação de saúde do sistema.
---
# /n8n-health - Diagnóstico n8n
Verificar conectividade e estado da instância n8n.
## Contexto NotebookLM
ANTES de executar, consultar notebooks para contexto especializado:
| Notebook | ID | Consultar quando |
|----------|-----|-----------------|
| n8n Deep Research | f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1 | Sempre |
```
mcp__notebooklm__notebook_query({
notebook_id: "f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1",
query: "<adaptar ao contexto do pedido do utilizador>"
})
```
Integrar insights do NotebookLM nas recomendações e decisões.
---
## Uso
```
/n8n-health # Status rápido
/n8n-health verbose # Diagnóstico completo
```
---
## Instância
| Aspecto | Valor |
|---------|-------|
| URL | `https://automator.descomplicar.pt` |
| MCP | `mcp__n8n__*` |
---
## Execução
### Status Rápido (default)
```
1. mcp__n8n__n8n_health_check({ mode: "status" })
2. Reportar: status, URL, versão, response time
```
### Diagnóstico Completo (verbose)
```
1. mcp__n8n__n8n_health_check({ mode: "diagnostic", verbose: true })
2. Reportar: env vars, tool status, cache, erros
```
---
## Output Esperado
```
n8n Health Check
----------------
Status: OK | ERRO
URL: https://automator.descomplicar.pt
MCP: 2.33.x
Response: XXXms
Workflows: XX activos
```
---
## Se Falhar
| Erro | Causa | Solução |
|------|-------|---------|
| Connection refused | n8n offline | Verificar servidor |
| 401 Unauthorized | API key inválida | Regenerar no n8n |
| Timeout | Rede lenta | Verificar latência |
### Diagnóstico Manual
```bash
# Verificar se n8n responde
curl -I https://automator.descomplicar.pt
# Verificar API
curl -H "X-N8N-API-KEY: $KEY" https://automator.descomplicar.pt/api/v1/workflows
# Logs MCP
~/.claude/logs/mcp-n8n.log
```
---
## Skills Relacionadas
| Skill | Quando Usar |
|-------|-------------|
| `/n8n-webhook` | Criar webhooks |
| `/n8n-schedule` | Automações cron |
| `/n8n-sync` | Sincronização dados |
| `/n8n-notify` | Alertas |
| `/n8n-chatbot` | AI/Chatbots |
---
*Skill v1.0 | Descomplicar®*
-234
View File
@@ -1,234 +0,0 @@
---
name: n8n-notify
description: Criação de sistemas de notificações e alertas n8n via Slack, email e SMS.
disable-model-invocation: true
---
# /n8n-notify - Notificações e Alertas n8n
Criar sistemas de alertas via Slack, email, SMS.
---
## Uso
```
/n8n-notify create <descrição> # Criar sistema de alertas
/n8n-notify slack <mensagem> # Quick Slack notification
/n8n-notify email <para> <assunto> # Quick email
```
---
## Workflow Obrigatório
```
1. Health check → mcp__n8n__n8n_health_check()
2. Pesquisar template → mcp__n8n__search_templates({ query: "notification" })
3. Se template OK → mcp__n8n__n8n_deploy_template()
4. Se criar do zero → Seguir fluxo abaixo
```
---
## Canais Disponíveis
| Canal | Node | Uso |
|-------|------|-----|
| Slack | `nodes-base.slack` | Notificações equipa |
| Email | `nodes-base.emailSend` | Alertas formais |
| Telegram | `nodes-base.telegram` | Alertas mobile |
| Discord | `nodes-base.discord` | Comunidades |
| SMS | `nodes-base.twilio` | Alertas críticos |
---
## Slack
### Documentação
```javascript
mcp__n8n__get_node({
nodeType: "nodes-base.slack",
detail: "standard",
includeExamples: true
})
```
### Configuração
```javascript
mcp__n8n__validate_node({
nodeType: "nodes-base.slack",
config: {
resource: "message",
operation: "post",
channel: "#alertas",
text: "Mensagem de alerta"
},
mode: "minimal"
})
```
### Mensagem Formatada (Blocks)
```javascript
{
blocksUi: {
blocksValues: [
{
type: "header",
text: { type: "plain_text", text: "Alerta" }
},
{
type: "section",
text: { type: "mrkdwn", text: "*Detalhes:*\n{{ $json.message }}" }
}
]
}
}
```
---
## Email
### Configuração
```javascript
mcp__n8n__validate_node({
nodeType: "nodes-base.emailSend",
config: {
fromEmail: "alertas@descomplicar.pt",
toEmail: "emanuel@descomplicar.pt",
subject: "Alerta: {{ $json.title }}",
text: "{{ $json.message }}"
},
mode: "minimal"
})
```
---
## Padrões Comuns
### Webhook → Slack
```
Webhook (evento externo)
Set (formatar)
Slack (enviar)
```
### Monitor → Multi-canal
```
Schedule (cada 5min)
HTTP Request (check health)
IF (erro?)
↓ TRUE
Slack + Email (alertar)
```
### Error Handler
```
Qualquer workflow
↓ (erro)
Error Trigger
Slack (alertar erro)
```
---
## Níveis de Alerta
| Nível | Canal | Quando |
|-------|-------|--------|
| Info | Slack | Eventos normais |
| Warning | Slack + Email | Atenção necessária |
| Critical | Todos + SMS | Acção imediata |
### Implementação
```
IF (severity = "critical")
↓ TRUE
Slack + Email + SMS
↓ FALSE
IF (severity = "warning")
↓ TRUE
Slack + Email
↓ FALSE
Slack
```
---
## Exemplos
### Alerta de Servidor Down
```
Schedule (5min)
HTTP Request (ping servidor)
IF (falhou?)
↓ TRUE
Slack (#infra)
Email (admin)
```
### Novo Lead
```
Webhook (lead criado)
Set (formatar)
Slack (#vendas)
```
### Factura Vencida
```
Schedule (diário 9h)
HTTP Request (facturas vencidas)
Loop (cada factura)
Email (cliente)
Slack (#contabilidade)
```
---
## Templates
```javascript
mcp__n8n__search_templates({
searchMode: "keyword",
query: "slack notification alert"
})
```
---
## Troubleshooting
| Problema | Solução |
|----------|---------|
| Slack não envia | Verificar token e canal |
| Email em spam | Configurar SPF/DKIM |
| Rate limited | Agrupar notificações |
---
*Skill v1.0 | Descomplicar®*
-169
View File
@@ -1,169 +0,0 @@
---
name: n8n-schedule
description: Criação de workflows n8n com execução agendada via cron para automações recorrentes.
disable-model-invocation: true
---
# /n8n-schedule - Automações Agendadas n8n
Criar workflows com execução agendada (cron).
---
## Uso
```
/n8n-schedule create <descrição> # Criar automação agendada
/n8n-schedule list # Listar agendamentos
/n8n-schedule disable <id> # Desactivar
```
---
## Workflow Obrigatório
```
1. Health check → mcp__n8n__n8n_health_check()
2. Pesquisar template → mcp__n8n__search_templates({ task: "scheduling" })
3. Se template OK → mcp__n8n__n8n_deploy_template()
4. Se criar do zero → Seguir fluxo abaixo
```
---
## Expressões Cron Comuns
| Expressão | Descrição |
|-----------|-----------|
| `0 9 * * *` | Diário às 9h |
| `0 9 * * 1-5` | Seg-Sex às 9h |
| `0 */2 * * *` | A cada 2 horas |
| `*/15 * * * *` | A cada 15 minutos |
| `0 0 1 * *` | Dia 1 de cada mês |
| `0 3 * * 0` | Domingos às 3h |
### Formato
```
┌───────── minuto (0-59)
│ ┌─────── hora (0-23)
│ │ ┌───── dia mês (1-31)
│ │ │ ┌─── mês (1-12)
│ │ │ │ ┌─ dia semana (0-6)
* * * * *
```
---
## Configuração Schedule Trigger
```javascript
mcp__n8n__validate_node({
nodeType: "nodes-base.scheduleTrigger",
config: {
rule: {
interval: [{
field: "cronExpression",
expression: "0 9 * * 1-5"
}]
}
},
mode: "minimal"
})
```
---
## Timezone
```javascript
{
options: {
timezone: "Europe/Lisbon"
}
}
```
---
## Exemplos
### Relatório Diário
```
Schedule (0 9 * * 1-5)
PostgreSQL (query)
Set (formatar)
Email (enviar)
```
### Backup Semanal
```
Schedule (0 3 * * 0)
SSH (backup)
IF (sucesso?)
Slack (confirmar/alertar)
```
### Limpeza de Logs
```
Schedule (0 2 * * *)
SSH (limpar)
Slack (reportar)
```
---
## Gestão
### Desactivar
```javascript
mcp__n8n__n8n_update_partial_workflow({
id: "wf-xxx",
operations: [{ type: "deactivateWorkflow" }]
})
```
### Reactivar
```javascript
mcp__n8n__n8n_update_partial_workflow({
id: "wf-xxx",
operations: [{ type: "activateWorkflow" }]
})
```
### Ver Execuções
```javascript
mcp__n8n__n8n_executions({
workflowId: "wf-xxx",
limit: 10,
status: "all"
})
```
---
## Troubleshooting
| Problema | Solução |
|----------|---------|
| Não executa | Verificar workflow activo |
| Hora errada | Verificar timezone |
| Duplicado | Verificar múltiplos triggers |
---
*Skill v1.0 | Descomplicar®*
-168
View File
@@ -1,168 +0,0 @@
---
name: n8n-sync
description: Sincronização de dados entre sistemas via workflows n8n. Mantém dados consistentes entre plataformas.
disable-model-invocation: true
---
# /n8n-sync - Sincronização de Dados n8n
Manter dados sincronizados entre sistemas.
---
## Uso
```
/n8n-sync create <origem> <destino> # Criar sync
/n8n-sync list # Listar syncs
/n8n-sync status <workflow_id> # Ver estado
```
---
## Workflow Obrigatório
```
1. Health check → mcp__n8n__n8n_health_check()
2. Pesquisar template → mcp__n8n__search_templates({ task: "data_sync" })
3. Se template OK → mcp__n8n__n8n_deploy_template()
4. Se criar do zero → Seguir fluxo abaixo
```
---
## Padrões de Sync
### One-Way (Unidireccional)
```
Origem → Transform → Destino
```
### Two-Way (Bidireccional)
```
A ←→ B (com resolução de conflitos)
```
### Hub-and-Spoke
```
A ↔ HUB ↔ B
C
```
---
## Nodes por Sistema
### APIs/CRM
| Node | Sistema |
|------|---------|
| `nodes-base.httpRequest` | APIs genéricas |
| `nodes-base.webhook` | Receber dados |
### Bases de Dados
| Node | Sistema |
|------|---------|
| `nodes-base.postgres` | PostgreSQL |
| `nodes-base.mySql` | MySQL |
| `nodes-base.mongoDb` | MongoDB |
### Ficheiros
| Node | Sistema |
|------|---------|
| `nodes-base.googleSheets` | Google Sheets |
| `nodes-base.spreadsheetFile` | Excel/CSV |
| `nodes-base.ftp` | FTP/SFTP |
---
## Exemplo: CRM → Sheets
```
Schedule (horário)
HTTP Request (GET leads)
IF (há dados?)
Set (mapear campos)
Google Sheets (append)
Slack (confirmar)
```
---
## Estratégias
| Estratégia | Uso |
|------------|-----|
| Full Sync | Apagar tudo + inserir tudo |
| Incremental | Apenas modificados (updated_at) |
| Delta | Comparar hashes |
---
## Upsert Pattern
```javascript
{
nodeType: "nodes-base.postgres",
config: {
operation: "upsert",
table: "clientes",
columns: "email,nome,empresa",
conflictColumns: "email"
}
}
```
---
## Gestão de Erros
### Retry
```javascript
{
options: {
retry: {
maxRetries: 3,
retryInterval: 1000
}
}
}
```
### Dead Letter Queue
```
Operação
↓ (erro)
Error Trigger
BD (guardar erro)
Slack (alertar)
```
---
## Troubleshooting
| Problema | Solução |
|----------|---------|
| Duplicados | Usar upsert |
| Timeout | Batches menores |
| Rate limit | Adicionar delays |
---
*Skill v1.0 | Descomplicar®*
-160
View File
@@ -1,160 +0,0 @@
---
name: n8n-webhook
description: Criação e gestão de webhooks n8n para receber dados de sistemas externos.
---
# /n8n-webhook - Webhooks n8n
Criar e gerir webhooks para receber dados externos.
---
## Uso
```
/n8n-webhook create <descrição> # Criar novo webhook
/n8n-webhook list # Listar webhooks existentes
/n8n-webhook test <workflow_id> # Testar webhook
```
---
## Workflow Obrigatório
```
1. Health check → mcp__n8n__n8n_health_check()
2. Pesquisar template → mcp__n8n__search_templates({ query: "webhook" })
3. Se template OK → mcp__n8n__n8n_deploy_template()
4. Se criar do zero → Seguir fluxo abaixo
```
---
## Criar Webhook do Zero
### Passo 1: Documentação do Node
```javascript
mcp__n8n__get_node({
nodeType: "nodes-base.webhook",
detail: "standard",
includeExamples: true
})
```
### Passo 2: Validar Configuração
```javascript
mcp__n8n__validate_node({
nodeType: "nodes-base.webhook",
config: {
httpMethod: "POST",
path: "meu-webhook",
responseMode: "onReceived"
},
mode: "minimal"
})
```
### Passo 3: Nodes de Processamento
| Node | Uso |
|------|-----|
| `nodes-base.set` | Transformar dados |
| `nodes-base.if` | Condicionais |
| `nodes-base.code` | JavaScript custom |
| `nodes-base.httpRequest` | Chamar APIs |
### Passo 4: Deploy
```javascript
mcp__n8n__n8n_create_workflow({
name: "Webhook - Descrição",
nodes: [...],
connections: {...},
active: true
})
```
---
## Configurações Webhook
| Parâmetro | Opções | Default |
|-----------|--------|---------|
| `httpMethod` | GET, POST, PUT, DELETE | POST |
| `path` | String única | (obrigatório) |
| `authentication` | none, basicAuth, headerAuth | none |
| `responseMode` | onReceived, lastNode | onReceived |
---
## URL do Webhook
Após deploy:
```
https://automator.descomplicar.pt/webhook/<path>
```
Modo teste (workflow inactivo):
```
https://automator.descomplicar.pt/webhook-test/<path>
```
---
## Exemplos
### Webhook → Slack
```
Webhook (POST /notify)
Set (formatar)
Slack (enviar)
```
### Webhook → CRM
```
Webhook (POST /lead)
HTTP Request (criar no Desk)
Email (notificar)
```
---
## Testar
```javascript
mcp__n8n__n8n_test_workflow({
workflowId: "wf-xxx",
inputData: {
body: { "test": "data" },
headers: { "Content-Type": "application/json" }
}
})
```
```bash
curl -X POST https://automator.descomplicar.pt/webhook/meu-webhook \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
```
---
## Troubleshooting
| Problema | Solução |
|----------|---------|
| 404 Not Found | Workflow não está activo |
| 401 Unauthorized | Verificar autenticação |
| Dados não chegam | Verificar responseMode |
---
*Skill v1.0 | Descomplicar®*
+270
View File
@@ -0,0 +1,270 @@
---
name: n8n
description: Meta-skill n8n para criação e gestão de workflows na instância automator.descomplicar.pt. Cobre health check, webhooks, schedule (cron), sync de dados, notify (Slack/email/SMS) e chatbots/AI agents (LangChain/RAG). Triggers — n8n, workflow, automação, webhook, schedule, cron, sync, notify, alerta, slack, chatbot, ai agent, langchain, rag, automator, health check n8n.
---
# /n8n - Meta-skill n8n
Skill unificada para a instância n8n Descomplicar (`https://automator.descomplicar.pt`, MCP `mcp__n8n__*`). Substitui as antigas n8n-chatbot, n8n-health, n8n-notify, n8n-schedule, n8n-sync, n8n-webhook.
## Contexto NotebookLM (sempre antes de executar)
| Notebook | ID |
|----------|-----|
| n8n Deep Research | `f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1` |
```
mcp__notebooklm__notebook_query({ notebook_id: "f2c809b8-1cb5-4dd0-aa7e-be2cfb6704d1", query: "<adaptar ao pedido>" })
```
## Workflow obrigatório (qualquer criação)
```
1. mcp__n8n__n8n_health_check()
2. mcp__n8n__search_templates({ task: "<webhook|scheduling|data_sync|notification|ai_automation>" })
3. Se template adequado -> mcp__n8n__n8n_deploy_template()
4. Caso contrário, criar do zero seguindo a secção apropriada abaixo
```
---
## 1. Health (diagnóstico)
```
/n8n health # status rápido
/n8n health verbose # diagnóstico completo
```
```js
mcp__n8n__n8n_health_check({ mode: "status" })
mcp__n8n__n8n_health_check({ mode: "diagnostic", verbose: true })
```
Output esperado: status (OK/ERRO), URL, versão MCP, response time, workflows activos.
Erros comuns: Connection refused (n8n offline), 401 (API key inválida — regenerar), timeout (rede). Diagnóstico manual:
```bash
curl -I https://automator.descomplicar.pt
curl -H "X-N8N-API-KEY: $KEY" https://automator.descomplicar.pt/api/v1/workflows
tail ~/.claude/logs/mcp-n8n.log
```
---
## 2. Webhook
Receber dados de sistemas externos.
```
/n8n webhook create <descrição>
/n8n webhook list
/n8n webhook test <workflow_id>
```
```js
mcp__n8n__get_node({ nodeType: "nodes-base.webhook", detail: "standard", includeExamples: true })
mcp__n8n__validate_node({ nodeType: "nodes-base.webhook", config: { httpMethod: "POST", path: "meu-webhook", responseMode: "onReceived" }, mode: "minimal" })
mcp__n8n__n8n_create_workflow({ name: "Webhook - X", nodes: [...], connections: {...}, active: true })
```
Parâmetros: `httpMethod` (GET/POST/PUT/DELETE, default POST), `path` (obrigatório), `authentication` (none/basicAuth/headerAuth), `responseMode` (onReceived/lastNode).
URLs: produção `https://automator.descomplicar.pt/webhook/<path>` | teste `https://automator.descomplicar.pt/webhook-test/<path>`.
Nodes processamento: `nodes-base.set`, `nodes-base.if`, `nodes-base.code`, `nodes-base.httpRequest`.
Teste:
```js
mcp__n8n__n8n_test_workflow({ workflowId: "wf-xxx", inputData: { body: {test:"data"}, headers: {"Content-Type":"application/json"} } })
```
```bash
curl -X POST https://automator.descomplicar.pt/webhook/meu-webhook -H "Content-Type: application/json" -d '{"test":"data"}'
```
Troubleshooting: 404 (workflow não activo), 401 (auth), dados não chegam (responseMode).
---
## 3. Schedule (cron)
Workflows com execução agendada.
```
/n8n schedule create <descrição>
/n8n schedule list
/n8n schedule disable <id>
```
Cron comuns: `0 9 * * *` (diário 9h), `0 9 * * 1-5` (Seg-Sex 9h), `0 */2 * * *` (cada 2h), `*/15 * * * *` (15min), `0 0 1 * *` (dia 1), `0 3 * * 0` (domingos 3h).
```js
mcp__n8n__validate_node({
nodeType: "nodes-base.scheduleTrigger",
config: { rule: { interval: [{ field: "cronExpression", expression: "0 9 * * 1-5" }] }, options: { timezone: "Europe/Lisbon" } },
mode: "minimal"
})
```
Gestão:
```js
mcp__n8n__n8n_update_partial_workflow({ id: "wf-xxx", operations: [{ type: "deactivateWorkflow" }] })
mcp__n8n__n8n_update_partial_workflow({ id: "wf-xxx", operations: [{ type: "activateWorkflow" }] })
mcp__n8n__n8n_executions({ workflowId: "wf-xxx", limit: 10, status: "all" })
```
Exemplos: relatório diário (Schedule -> Postgres -> Set -> Email), backup semanal (Schedule -> SSH -> IF -> Slack), limpeza logs.
Troubleshooting: não executa (workflow inactivo), hora errada (timezone), duplicado (múltiplos triggers).
---
## 4. Sync (sincronização de dados)
```
/n8n sync create <origem> <destino>
/n8n sync list
/n8n sync status <workflow_id>
```
Padrões: One-Way (origem -> transform -> destino), Two-Way (com resolução conflitos), Hub-and-Spoke.
Nodes:
- APIs: `nodes-base.httpRequest`, `nodes-base.webhook`
- BD: `nodes-base.postgres`, `nodes-base.mySql`, `nodes-base.mongoDb`
- Ficheiros: `nodes-base.googleSheets`, `nodes-base.spreadsheetFile`, `nodes-base.ftp`
Estratégias: Full Sync, Incremental (updated_at), Delta (hashes).
Upsert:
```js
{ nodeType: "nodes-base.postgres", config: { operation: "upsert", table: "clientes", columns: "email,nome,empresa", conflictColumns: "email" } }
```
Erros: retry (`{ options: { retry: { maxRetries: 3, retryInterval: 1000 } } }`), Dead Letter Queue (Error Trigger -> BD -> Slack).
Exemplo CRM->Sheets: Schedule -> HTTP GET leads -> IF -> Set -> Google Sheets append -> Slack.
Troubleshooting: duplicados (upsert), timeout (batches menores), rate limit (delays).
---
## 5. Notify (alertas)
```
/n8n notify create <descrição>
/n8n notify slack <mensagem>
/n8n notify email <para> <assunto>
```
Canais: Slack (`nodes-base.slack`), Email (`nodes-base.emailSend`), Telegram, Discord, SMS Twilio.
Slack:
```js
mcp__n8n__validate_node({
nodeType: "nodes-base.slack",
config: { resource: "message", operation: "post", channel: "#alertas", text: "..." },
mode: "minimal"
})
```
Mensagem formatada (Blocks): header + section com `mrkdwn` e `{{ $json.message }}`.
Email:
```js
mcp__n8n__validate_node({
nodeType: "nodes-base.emailSend",
config: { fromEmail: "alertas@descomplicar.pt", toEmail: "emanuel@descomplicar.pt", subject: "Alerta: {{ $json.title }}", text: "{{ $json.message }}" },
mode: "minimal"
})
```
Padrões: Webhook->Slack, Monitor->Multi-canal (Schedule -> HTTP -> IF -> Slack+Email), Error Handler (Error Trigger -> Slack).
Níveis: Info (Slack), Warning (Slack+Email), Critical (Slack+Email+SMS) — implementar com IF aninhado por `severity`.
Troubleshooting: Slack não envia (token/canal), email em spam (SPF/DKIM), rate limited (agrupar).
---
## 6. Chatbot / AI Agents (LangChain)
```
/n8n chatbot create <descrição>
/n8n chatbot agent <tipo>
/n8n chatbot rag <knowledge_base>
```
### Nodes LangChain
Core: `@n8n/n8n-nodes-langchain.agent`, `chainLlm`, `chainRetrievalQa`.
Modelos: `lmChatOpenAi`, `lmChatAnthropic`, `lmChatOllama`.
Memória: `memoryBufferWindow`, `memoryPostgresChat`, `memoryRedisChat`.
Tools: `toolCalculator`, `toolCode`, `toolHttpRequest`, `toolWorkflow`.
Vector Stores: `vectorStoreSupabase`, `vectorStorePinecone`, `vectorStorePgVector`.
### Chatbot básico
```
Webhook -> LLM Chat -> Memory Buffer -> Agent -> Resposta
```
### RAG
```
Documentos -> Embeddings -> Vector Store -> Query -> Retriever -> LLM
```
```js
mcp__n8n__validate_node({
nodeType: "@n8n/n8n-nodes-langchain.vectorStoreSupabase",
config: { mode: "insert", tableName: "documents", queryName: "match_documents" },
mode: "minimal"
})
```
### AI Agent com tools
```js
mcp__n8n__validate_node({
nodeType: "@n8n/n8n-nodes-langchain.agent",
config: { agentType: "conversationalAgent", systemMessage: "Tu és um assistente prestável...", options: { returnIntermediateSteps: true } },
mode: "minimal"
})
```
### Exemplos práticos
- Suporte: Webhook -> Memory Postgres -> Vector Store -> Chain Retrieval QA -> Webhook Response.
- Agent CRM: Webhook -> Agent (tools: pesquisar/criar lead/actualizar tarefa) -> Slack.
- Resumo PDFs: Webhook -> PDF Extract -> Text Splitter -> LLM Chain -> Email.
### Credenciais
OpenAI/Anthropic (API Key), Supabase (URL+Key), Pinecone (API Key).
### Boas práticas
System prompt claro | temperatura 0.1-0.3 | memória limitada | retry on error | logs de conversas.
### Troubleshooting
Inconsistente (baixar temperatura), contexto perdido (memória), RAG vazio (embeddings), timeout (limite), token limit (resumir).
---
## Templates
```js
mcp__n8n__search_templates({ searchMode: "by_task", task: "ai_automation" })
mcp__n8n__search_templates({ searchMode: "keyword", query: "chatbot langchain openai" })
```
---
**Versão:** 2.0.0 (consolidação 6->1, 07-04-2026) | **Autor:** Descomplicar®
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+12
View File
@@ -122,3 +122,15 @@ mcp__memory-supabase__save_memory {
---
*Core Standards v1.1 | 2026-03-12*
---
## 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.*
+43 -127
View File
@@ -1,149 +1,65 @@
---
name: agent-context-injector
description: Injecção dinâmica de contexto específico para cada agente — MCPs disponíveis, skills relevantes e datasets Dify.
description: Injeccao dinamica de contexto (MCPs e Skills) nos agentes via script Python + hook SessionStart com deteccao de staleness.
user-invocable: false
allowed-tools: Read, Glob, Grep, ToolSearch
---
# Agent Context Injector
Injecção dinâmica de contexto específico para cada agente.
Regeneracao automatica das seccoes "Your Available MCPs" e "Your Available Skills" em todos os agentes.
## Triggers
## Como funciona
Esta skill é activada automaticamente via hook `SubagentStart` quando:
- Um subagente é iniciado via Task tool
- Contexto precisa ser enriquecido com recursos do agente
1. **Hook SessionStart** (`~/.claude/hooks/agent-context-refresh.sh`) calcula hash dos inputs
2. Se hash mudou → executa `~/.claude/scripts/regenerate-agent-context.py`
3. Script le frontmatter de cada agente, inventario MCPs, mapeamento domain e skills dos plugins
4. Gera seccoes entre marcadores `<!-- BEGIN:AUTO-CONTEXT -->` / `<!-- END:AUTO-CONTEXT -->`
5. Guarda novo hash em `~/.claude/.agent-context-hash`
## Capabilities
## Ficheiros
### 1. Context Building
- Consultar mapeamento agente → recursos na BD
- Gerar lista de MCPs disponíveis para o agente
- Gerar lista de skills relevantes
- Incluir datasets Dify para consulta automática
| Ficheiro | Funcao |
|----------|--------|
| `~/.claude/scripts/regenerate-agent-context.py` | Script principal de regeneracao |
| `~/.claude/hooks/agent-context-refresh.sh` | Hook SessionStart com staleness |
| `~/.claude/_resources/domain-mcp-map.json` | Mapeamento domain -> MCPs recomendados |
| `~/.claude/_resources/mcps.json` | Inventario de 34+ MCPs |
| `~/.claude/.agent-context-hash` | Hash MD5 dos inputs (staleness) |
### 2. Token Optimization
- Calcular tokens do contexto gerado
- Priorizar recursos por relevância
- Truncar se exceder limite (~800 tokens)
- Cache de contextos frequentes
## Dados de entrada
### 3. Dynamic Injection
- Adicionar contexto ao prompt do agente
- Incluir instruções de uso dos recursos
- Configurar auto-consult para datasets
- **Agentes:** `~/.claude/agents/*.md` — frontmatter com `domain`, `skills`
- **MCPs:** `~/.claude/_resources/mcps.json` — lista com `id`, `name`, `category`
- **Domain map:** `~/.claude/_resources/domain-mcp-map.json` — primary/recommended por domain
- **Skills:** `descomplicar-plugins/*/skills/*/SKILL.md` — frontmatter com `name`, `description`
## Template de Contexto
## Performance
```markdown
## Recursos Disponíveis
| Cenario | Tempo |
|---------|-------|
| Sem mudancas (hash match) | ~66ms |
| Com regeneracao (61 agentes) | ~2-3s |
### MCPs Activos
$MCP_LIST
- Usar proactivamente para operações relevantes
## Manutencao
### Skills Recomendadas
$SKILLS_LIST
- Invocar quando tarefa corresponder
- **Adicionar MCP:** actualizar `mcps.json` e `domain-mcp-map.json` → proximo SessionStart regenera
- **Adicionar skill:** criar SKILL.md no plugin → proximo SessionStart regenera
- **Adicionar agente:** criar .md com frontmatter `domain:` → proximo SessionStart gera contexto
- **Mudar domain map:** editar `domain-mcp-map.json` → proximo SessionStart regenera
### Knowledge Base (Dify)
$DATASETS_LIST
- AUTO-CONSULT: Consultar ANTES de responder
- Query template: "$QUERY_TEMPLATE"
## Tarefa Desk
### Plugins
$PLUGINS_LIST
- Comandos disponíveis: $PLUGIN_COMMANDS
#1996 — Sistema injeccao Skills e MCPs nos agentes
---
## Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
## Workflow
```
SUBAGENT START → QUERY BD → BUILD CONTEXT → INJECT → EXECUTE
```
1. **Hook SubagentStart** dispara
2. **Identificar agente** pelo `subagent_type`
3. **Query MySQL**:
```sql
SELECT r.resource_type, r.resource_id, r.priority
FROM cr_agent_resources r
JOIN cr_agents a ON r.agent_id = a.id
WHERE a.slug = '{agent_slug}'
AND r.auto_inject = TRUE
ORDER BY r.priority ASC;
```
4. **Consultar agent-knowledge-config.json** para datasets
5. **Gerar contexto** com template
6. **Calcular tokens** e optimizar se necessário
7. **Injectar** no prompt do agente
## Métricas Target
| Métrica | Target |
|---------|--------|
| Tempo de injecção | < 2s |
| Tokens médios | ~772 |
| Cache hit rate | > 60% |
| Erro rate | < 1% |
## Exemplo de Output
Para `wordpress-plugin-developer`:
```markdown
## Recursos Disponíveis
### MCPs Activos
- `cwp` - Gestão servidor CentOS WebPanel
- `ssh-unified` - Acesso SSH a servidores
- `filesystem` - Operações de ficheiros
### Skills Recomendadas
- `/wp-dev` - Desenvolvimento WordPress
- `/wp-performance` - Optimização performance
- `/elementor` - Desenvolvimento Elementor
### Knowledge Base (Dify)
- `wordpress-development` - Docs WP, hooks, filters
- `woocommerce-api` - API WooCommerce
- AUTO-CONSULT: Consultar ANTES de implementar
### Plugins
- `superpowers` - TDD obrigatório
- `code-review` - Review automático
```
## Configuração
Ficheiro `agent-knowledge-config.json`:
```json
{
"wordpress-plugin-developer": {
"datasets": ["wordpress-development", "woocommerce-api"],
"auto_consult": true,
"query_template": "WordPress {topic} best practices 2026",
"priority_datasets": ["wordpress-development"]
}
}
```
## Integração com Scripts Existentes
Este skill complementa (não substitui) os scripts Python existentes:
- `inject-mcp-context.py` - Continua activo
- `inject-skills-context.py` - Continua activo
A skill adiciona:
- Datasets Dify dinâmicos
- Plugins activos
- Contexto mais rico e actualizado
## Limites
- Máximo ~800 tokens de contexto injectado (para preservar espaço)
- Não modifica comportamento do agente, apenas enriquece contexto
- Depende de mapeamentos correctos em `cr_agent_resources`
- Cache de 5 minutos pode mostrar dados desactualizados
- Não funciona para agentes não registados na BD
*Adicionar nova linha após cada erro corrigido.*
@@ -283,3 +283,14 @@ Component Generator:
- Não cria componentes duplicados (verifica slug existente)
- Requer conexão MySQL para registo em cr_*
- Não modifica componentes existentes (usar Edit tool)
---
## 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.*
@@ -260,3 +260,15 @@ Resultado:
- Backup não inclui tabelas não-cr_*
- Optimização pode demorar em tabelas grandes (>1M registos)
- Não substitui backups gerais do Desk CRM
---
## 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.*
@@ -203,3 +203,15 @@ Infrastructure Manager:
- Detecção de órfãos limitada a tabelas cr_* conhecidas
- Não corrige problemas automaticamente (apenas reporta)
- Telemetria depende de hooks activos e funcionais
---
## 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.*
+12
View File
@@ -175,3 +175,15 @@ Link Desk CRM: `https://desk.descomplicar.pt/admin/projects/view/65`
---
**Desk CRM:** Projecto #65, Task #1637
---
## 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.*
+28 -15
View File
@@ -18,30 +18,30 @@ Esta skill deve ser activada quando:
## 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
- Avaliar relevância baseada no contexto actual
- Identificar plugins com funcionalidades sobrepostas
- Detectar plugins desactualizados ou abandonados
### 2. Evaluation
### 3. Evaluation
- Analisar qualidade do código (se open source)
- Verificar compatibilidade com sistema actual
- Avaliar segurança (hooks, permissões)
- Medir popularidade e manutenção activa
### 3. Installation Management
### 4. Installation Management
- Instalar plugins recomendados
- Configurar hooks e MCPs do plugin
- Resolver conflitos com plugins existentes
- 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
| Marketplace | URL | Tipo |
@@ -56,12 +56,12 @@ Esta skill deve ser activada quando:
```
score = 0
score += keyword_match * 3 # Max 3
score += category_align * 2 # Max 2
score += popularity # Max 2 (>1k stars)
score += recent_update # Max 1 (<30 days)
score += no_conflicts * 2 # Max 2
# Total max: 10
score += keyword_match * 3 # Max 3 (bool: 0|1)
score += category_align * 2 # Max 2 (bool: 0|1)
score += popularity # Max 2 (tiered: 0=<100 stars, 1=100-1k, 2=>1k)
score += recent_update # Max 1 (bool: 1 se último commit <30 dias)
score += no_conflicts * 2 # Max 2 (bool: 0|1)
# Total max: 3 + 2 + 2 + 1 + 2 = 10
```
## Workflow
@@ -97,3 +97,16 @@ Assistant: [Activa plugin-curator]
- NUNCA instalar plugins de fontes não verificadas
- Verificar SEMPRE conflitos antes de instalar
- 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.*
+12
View File
@@ -141,3 +141,15 @@ Avalia todas as regras e sugere `/plugin-config apply` se detectar alteracoes ne
---
*Skill v3.0.0 | 04-03-2026 | Descomplicar*
---
## 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.*
@@ -188,3 +188,15 @@ Quality Validator:
- Não modifica componentes (apenas lê e reporta)
- Não cria componentes (usar component-generator)
- Não executa correções automáticas (usar /descomplicar:upgrade)
---
## 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.*
@@ -223,3 +223,15 @@ Relationship Manager:
- Análise de impacto limitada a relacionamentos directos
- Não propaga alterações automaticamente (requer confirmação)
- Depende de consistência das tabelas cr_* na BD
---
## 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.*
+4 -2
View File
@@ -1,7 +1,7 @@
{
"name": "crm-ops",
"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": {
"name": "Descomplicar - Crescimento Digital",
"url": "https://descomplicar.pt"
@@ -14,6 +14,8 @@
"leads",
"facturacao",
"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)
+64 -16
View File
@@ -1,10 +1,10 @@
---
name: auto-expense
description: Criação automática de despesas a partir de facturas detectadas no IMAP e tickets. Extrai dados, verifica duplicados e cria despesas no Desk CRM com PDF anexo.
description: Criação automática de despesas a partir de facturas detectadas no IMAP e tickets. Extrai dados, verifica duplicados por reference_no e cria despesas no Desk CRM com PDF anexo.
disable-model-invocation: true
---
# /auto-expense v1.0
# /auto-expense v1.1
Cria despesas automaticamente a partir de facturas detectadas pelo IMAP e tickets.
@@ -49,28 +49,57 @@ Para cada factura na lista:
3. EXTRAIR DO HTML:
- Valor (padroes: $XX.XX, XX,XX EUR, USD XX.XX, Total: XX.XX)
- Referencia/Invoice number
- Referencia/Invoice number (OBRIGATORIO — guardar para dedup)
- Data da factura
```
4. VERIFICAR DUPLICADO (2 camadas):
Camada 1 - Desk CRM:
Pesquisar: mesmo fornecedor + mesmo valor (±0.05) + mesma data (±3 dias)
### Passo 3: Verificar duplicados (OBRIGATORIO — 3 camadas)
> **CRITICO: Este passo NUNCA pode ser saltado. Se saltado, causa duplicacao massiva de despesas.**
```
Camada 0 — Referencia de factura (PRIMARIA, mais fiavel):
get_expenses(search: "<reference_no>")
Para cada resultado: comparar campo reference_no
Se alguma despesa tem reference_no IGUAL → DUPLICADO CONFIRMADO
→ NAO criar, registar como duplicado com ID existente
Camada 1 — Fornecedor + Valor + Data:
get_expenses(search: "<fornecedor>")
Filtrar: mesmo valor (±0.05) + mesma data (±3 dias)
Se match → NAO criar, registar como duplicado
5. CRIAR DESPESA:
Camada 2 — Expense name pattern:
get_expenses(search: "<fornecedor> - <reference_no>")
Se match exacto no expense_name → NAO criar, registar como duplicado
REGRA: Se QUALQUER camada detecta duplicado → PARAR imediatamente.
Nunca criar despesa sem passar as 3 camadas com sucesso.
Registar cada duplicado detectado no output JSON (campo "duplicados").
```
### Passo 4: Criar despesa
```
APENAS se Passo 3 passou sem detectar duplicado:
mcp__desk-crm-v3__create_expense({
category: [cat_id da tabela],
amount: [valor],
date: [data factura YYYY-MM-DD],
expense_name: "[Fornecedor] - [Referencia]",
reference_no: "[numero factura/referencia]",
note: "Auto-criado via /auto-expense",
currency: [2=USD ou 3=EUR],
tax: [0 ou 1],
send_invoice_to_customer: 0
})
OBRIGATORIO: campo reference_no DEVE ser preenchido com o numero
de factura extraido. Este campo e a chave primaria de deduplicacao.
```
### Passo 3: PDF (se existir anexo)
### Passo 5: PDF (se existir anexo)
```
a. GUARDAR LOCAL:
@@ -100,14 +129,14 @@ c. REGISTAR no Desk BD:
d. LIMPAR temporarios
```
### Passo 4: Actualizar CSV
### Passo 6: Actualizar CSV
```
CSV Path: /media/ealmeida/Dados/GDrive/Cloud/ADM_Descomplicar/Financeiro/Contabilidade/YYYY/MAPA-DESPESAS-YYYY.csv
Formato linha: id_desk;data;categoria;fornecedor;descricao;valor;SIM;ficheiro;email;Auto /auto-expense
```
### Passo 5: Escrever output JSON
### Passo 7: Escrever output JSON
```
Escrever em ~/.claude-work/today-expenses-{date}.json:
@@ -115,12 +144,15 @@ Escrever em ~/.claude-work/today-expenses-{date}.json:
"despesas_criadas": [
{"id": 1180, "fornecedor": "MEO", "valor": 76.26, "moeda": "EUR", "referencia": "FT A/861215955"}
],
"duplicados": 0,
"duplicados": [
{"fornecedor": "MEO", "referencia": "FT A/861215955", "existente_id": 1175, "camada": 0}
],
"flagged": [
{"fornecedor": "Desconhecido", "nota": "TOConline - emitente desconhecido: XPTO LDA"}
],
"erros": [],
"total_processadas": 1
"total_processadas": 1,
"total_duplicados": 0
}
```
@@ -152,7 +184,7 @@ tax = 0 → Fornecedores estrangeiros
send_invoice_to_customer = 0 → OBRIGATORIO (sem default na BD)
reference_no → coluna correcta (NAO "reference")
reference_no → coluna correcta (NAO "reference") — CHAVE DE DEDUPLICACAO
```
---
@@ -167,7 +199,8 @@ reference_no → coluna correcta (NAO "reference")
|--------|-----------|-------|-------|-----|-----|
### Duplicados Detectados (Y)
- [Fornecedor] [Valor] - ja existe como #ID
| Fornecedor | Ref | ID Existente | Camada |
|-----------|-----|-------------|--------|
### Pendentes Revisao (Z)
- [Plataforma] - emitente desconhecido: [nome]
@@ -179,11 +212,26 @@ reference_no → coluna correcta (NAO "reference")
- NUNCA usar currency=1 (nao existe)
- NUNCA converter USD para EUR (manter original com currency=2)
- NUNCA criar despesa sem verificar duplicado primeiro
- NUNCA criar despesa sem verificar duplicado primeiro (3 camadas obrigatorias)
- NUNCA omitir send_invoice_to_customer=0
- NUNCA omitir reference_no ao criar despesa (chave primaria de dedup)
- NUNCA saltar a Camada 0 (referencia de factura) — e a mais fiavel
- SEMPRE ler o email/ticket HTML para extrair valor real (nunca assumir)
- SEMPRE incluir reference_no quando disponivel
- SEMPRE logar duplicados detectados no output JSON com camada e ID existente
---
*Skill v1.0.0 | 04-03-2026 | Descomplicar®*
*Skill v1.1.0 | 30-03-2026 | Descomplicar | Fix: dedup por reference_no (DES-137)*
---
## 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.*
+12
View File
@@ -293,3 +293,15 @@ Skill:
3. Executar workflow integrado
Output: [resultado completo com referências]
```
---
## 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.*
+12
View File
@@ -223,3 +223,15 @@ Skill:
3. Executar workflow integrado
Output: [resultado completo com referências]
```
---
## 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.*
-432
View File
@@ -1,432 +0,0 @@
---
name: crm-ops
description: Operações CRM seguras com verificação obrigatória de duplicados e confirmações. Distinção Lead vs Customer, Proposal vs Estimate. Criação de entidades CRM.
disable-model-invocation: true
---
# /crm-ops - Operações CRM Seguras
Skill para operações CRM com verificações obrigatórias de duplicados e confirmações.
## Metadata
- **Version**: 1.2.0
- **Author**: Descomplicar
- **Date**: 2026-01-28
- **Status**: Active
---
## Quando Usar
- Criar lead, customer, proposal, estimate
- Pesquisar entidades CRM
- Converter lead para customer
- Operações que envolvem orçamentos/propostas
- Qualquer operação que pode criar duplicados
## Quando NÃO Usar
- Para desenvolvimento WordPress (usar /wp-dev)
- Para criar orçamentos completos (usar /orcamento)
- Para análise de leads (usar /lead-approach)
---
## DEFINIÇÕES CRÍTICAS
### Lead vs Customer
| Aspecto | LEAD | CUSTOMER |
|---------|------|----------|
| **O que é** | Contacto inicial, prospect | Cliente com relação comercial |
| **Quando usar** | Primeiro contacto, ainda a avaliar | Após qualificação, vai comprar |
| **Tabela** | `tblleads` | `tblclients` + `tblcontacts` |
| **Recebe** | Proposals (orçamentos) | Estimates, Invoices |
| **Conversão** | Pode virar Customer | Já é cliente |
**REGRA:** Novos contactos são SEMPRE leads primeiro. Só se tornam customers após qualificação.
### Proposal vs Estimate
| Aspecto | PROPOSAL (Orçamento) | ESTIMATE |
|---------|---------------------|----------|
| **Para quem** | **LEADS** (prospects) | **CUSTOMERS** (clientes) |
| **Quando usar** | Utilizador pede "orçamento" | Cliente existente, pedido formal |
| **Tabela** | `tblproposals` | `tblestimates` |
| **Converte para** | Nada (lead vira customer primeiro) | Invoice directamente |
| **Termo PT** | **Orçamento, Proposta** | Estimativa |
> **IMPORTANTE:** Quando o utilizador pede um "orçamento", usar **PROPOSAL** (para leads).
> Estimates são para clientes já existentes com pedidos formais.
### Fluxo Comercial Correcto
```
┌─────────────────────────────────────────────────────────────────────┐
│ FLUXO COMERCIAL PERFEX │
└─────────────────────────────────────────────────────────────────────┘
LEAD CUSTOMER
│ │
▼ ▼
PROPOSAL ──────────────────────▶ ESTIMATE
(orçamento) converter lead (formal)
│ para customer │
│ │ ▼
│ │ INVOICE
│ │ │
└───────────────┴──────────────────┘
PAYMENT
```
**Resumo:**
- Lead + Orçamento = **Proposal**
- Customer + Orçamento formal = **Estimate**
- Estimate aceite = **Invoice**
---
## Protocolo
### REGRA 0: NUNCA CRIAR SEM VERIFICAR (CRÍTICA)
> **PROIBIDO criar Lead ou Customer sem verificar se já existe.**
Esta regra é INVIOLÁVEL. Mesmo que o utilizador peça para criar, PRIMEIRO:
```
1. Pesquisar em LEADS: get_leads() + filtrar por nome/email/empresa
2. Pesquisar em CUSTOMERS: search_customers(termo)
3. SE encontrar match:
- MOSTRAR resultados ao utilizador
- PERGUNTAR: "Encontrei [X]. É este ou criar novo?"
4. SE não encontrar:
- PERGUNTAR: "Não encontrei [Nome]. Confirmas criação?"
5. SÓ CRIAR após confirmação explícita
```
**Violação desta regra causa duplicados que prejudicam operações comerciais.**
### REGRA 1: VERIFICAR DUPLICADOS (Detalhado)
ANTES de criar QUALQUER entidade (Lead, Customer, Proposal, Estimate):
1. Pesquisar por nome/email/empresa:
- `search_customers` para clientes
- `get_leads` com filtro search para leads
2. Se match encontrado: MOSTRAR ao utilizador
3. Se match parcial: PERGUNTAR se é o mesmo
4. Se sem match: PERGUNTAR confirmação antes de criar
### REGRA 2: CONFIRMAR ANTES DE CRIAR
NUNCA criar entidade sem confirmação EXPLÍCITA:
- Lead: "Não encontrei este contacto. Criar lead [Nome] com email [Email]?"
- Customer: "Criar cliente [Empresa]? (ACÇÃO IRREVERSÍVEL - só para clientes qualificados)"
- Proposal: "Criar orçamento para lead [Nome] no valor de [X]?"
- Estimate: "Criar estimativa formal para cliente [Empresa] no valor de [X]?"
### REGRA 3: MODELO DE DADOS PERFEX
| Regra | Descrição |
|-------|-----------|
| Email em tblcontacts | Email do cliente está em tblcontacts, NÃO em tblclients |
| userid é o ID | Usar `userid` para clientes, não `customer_id` |
| Contacto principal | `is_primary = 1` para contacto principal |
| Source obrigatório | Leads precisam de source_id (buscar default) |
| Itens em tblitemable | Todos os itens (estimate, invoice, proposal) usam `tblitemable` com `rel_type` |
| rel_type para items | 'estimate', 'invoice', 'proposal', 'credit_note' |
## Comandos
| Comando | Descrição |
|---------|-----------|
| `/crm-ops search <termo>` | Pesquisa unificada em leads + customers |
| `/crm-ops lead create` | Criar lead COM verificação de duplicados |
| `/crm-ops lead convert <id>` | Converter lead em customer |
| `/crm-ops customer create` | Criar customer COM confirmação obrigatória |
| `/crm-ops estimate create` | Criar estimate COM validação cliente |
| `/crm-ops status` | Mostrar códigos de status |
## Fluxos Detalhados
### Criar Lead
```
1. Receber dados do lead (nome, email, empresa)
2. search_customers(email/nome)
3. get_leads(search=email/nome)
4. SE match encontrado:
- Mostrar resultados
- Perguntar: "Usar existente ou criar novo?"
5. SE criar novo:
- Buscar source default se não fornecido
- create_lead
6. Retornar ID do lead criado
```
### Converter Lead para Customer
```
1. Verificar lead existe: get_lead(lead_id)
2. Mostrar dados do lead ao utilizador
3. Perguntar: "Converter lead X para cliente?"
4. SE confirmado:
- convert_lead_to_customer
- Notas são transferidas automaticamente
5. Retornar ID do novo cliente
```
### Criar Customer (SEM lead)
```
1. SEMPRE perguntar confirmação ao utilizador
2. Verificar se existe lead para converter
- SE existe: usar convert_lead_to_customer
3. SE não existe lead:
- search_customers para verificar duplicados
- Confirmar criação
- create_customer
```
### Criar Estimate
```
1. Identificar cliente (perguntar se não especificado)
2. get_customer para verificar se existe
- SE não existe: PARAR, NÃO criar customer automaticamente
- Perguntar se deve criar customer primeiro
3. Confirmar itens e valores com utilizador
4. create_estimate
5. Perguntar se deve enviar: send_estimate
```
### Criar Proposal (Suporta Lead OU Customer)
> **CORRIGIDO v3.5.3:** Proposals agora suportam leads directamente.
```
1. Identificar se é Lead ou Customer
2. Usar o parâmetro correcto:
- Lead: create_proposal(lead_id=204, subject="...")
- Customer: create_proposal(client_id=42, subject="...")
3. NÃO usar ambos parâmetros (um OU outro)
```
### Editar Proposal
```
1. Obter proposal_id
2. update_proposal(proposal_id=X, subject="...", status=2)
```
**Status de Proposal:**
- 1 = Draft
- 2 = Sent
- 3 = Open
- 4 = Revised
- 5 = Declined
- 6 = Accepted
### Adicionar Itens a Proposal (v3.5.4)
```
1. Preparar array de itens com: description, qty, rate, unit, long_description
2. Chamar add_proposal_items:
add_proposal_items(
proposal_id=78,
clear_existing=true, // opcional: limpar itens anteriores
items=[
{ description: "Serviço X", qty: 1, rate: 500, unit: "un" },
{ description: "Horas Dev", qty: 10, rate: 60, unit: "hora" }
]
)
3. Total da proposta é actualizado automaticamente
```
### Listar Itens de Proposal
```
get_proposal_items(proposal_id=78)
```
Retorna lista de itens com quantidade, valor e total calculado.
### Converter Estimate para Invoice
```
1. get_estimate para verificar status
2. SE status != 4 (Aceite): PARAR e informar
3. Confirmar com utilizador
4. convert_estimate_to_invoice
5. Retornar ID da nova factura
```
## Status Codes
### Estimates
- 1 = Rascunho
- 2 = Enviado
- 3 = Visto
- 4 = Aceite (pode converter)
- 5 = Recusado
- 6 = Expirado
### Proposals
- 1 = Draft
- 2 = Sent
- 3 = Open
- 4 = Revised
- 5 = Declined
- 6 = Accepted
### Invoices
- 1 = Unpaid
- 2 = Paid
- 3 = Partially Paid
- 4 = Overdue
## MCP Tools
### Leads
- get_leads - Listar leads com filtros
- create_lead - Criar lead
- update_lead - Actualizar lead
- convert_lead_to_customer - Converter para cliente
- lead_scoring - Pontuar lead
- lead_analytics - Métricas
### Customers
- get_customers - Listar clientes
- get_customer - Detalhes cliente
- create_customer - Criar cliente
- search_customers - Pesquisa multi-campo
- update_customer - Actualizar
- delete_customer - Eliminar
- manage_customer_contacts - Gerir contactos
- create/get/update/delete_customer_note - Notas
### Estimates
- get_estimates - Listar orçamentos
- get_estimate - Detalhes
- create_estimate - Criar orçamento
- update_estimate - Actualizar
- send_estimate - Marcar como enviado
- convert_estimate_to_invoice - Converter para factura
- estimate_analytics - Métricas
### Proposals
- get_proposals - Listar propostas
- create_proposal - Criar proposta (suporta lead_id OU client_id)
- update_proposal - Editar proposta existente
- add_proposal_items - Adicionar itens/linhas a proposta
- get_proposal_items - Listar itens de uma proposta
- proposal_builder - Construtor interactivo
- proposal_analytics - Métricas
## Anti-Patterns (NUNCA fazer)
### Criação sem Verificação (CRÍTICO)
1. **NUNCA** criar lead sem pesquisar se já existe
2. **NUNCA** criar customer sem pesquisar se já existe
3. **NUNCA** assumir que entidade não existe - verificar SEMPRE
### Confusão de Entidades
4. Criar customer quando devia ser lead (novos contactos = leads)
5. Usar estimate para leads (usar proposal)
6. Usar proposal para customers qualificados (usar estimate)
7. Criar customer automaticamente para associar estimate
### Erros Técnicos
8. Converter estimate não-aceite para invoice
9. Aceder a email directamente em tblclients (usar JOIN com tblcontacts)
10. Usar tabelas inventadas (ex: tblitems_in) - verificar schema real primeiro
### Terminologia
- Utilizador diz "orçamento" para lead → usar **PROPOSAL**
- Utilizador diz "orçamento" para cliente existente → usar **ESTIMATE**
## Exemplos
### Exemplo 1: Criar lead com verificação
```
User: /crm-ops lead create nome="João Silva" email="joao@example.com"
→ Pesquisa em leads e customers
→ Não encontra duplicado
→ Pergunta: "Não encontrei João Silva. Confirmas criação?"
→ User: Sim
→ Cria lead #215
→ Confirma: "Lead #215 criado com sucesso"
```
### Exemplo 2: Detectar duplicado
```
User: /crm-ops customer create empresa="TechStart Lda"
→ Pesquisa customers
→ Encontra match: TechStart Lda (#42)
→ Mostra: "Encontrei TechStart Lda (#42). É este ou criar novo?"
→ User: É esse
→ Retorna dados do cliente existente
```
### Exemplo 3: Proposal para lead
```
User: Criar orçamento para lead João Silva
→ Verifica que é lead (não customer)
→ Usa create_proposal(lead_id=215)
→ Adiciona itens via add_proposal_items
→ Confirma: "Proposal #78 criada para lead #215"
```
## Checklist Pré-Operação
- [ ] Verificar duplicados
- [ ] Confirmar com utilizador
- [ ] Validar campos obrigatórios
- [ ] Usar source/status default se não fornecido
- [ ] Mostrar resultado da operação
## Integração
- **MCP:** desk-crm-v3
- **Procedimento:** [[PROC-CRM-Operacoes]]
- **CLAUDE.md:** Secção "CRM (Perfex/DeskCRM)"
## Changelog
### v1.2.0 (2026-01-28)
- **REGRA 0** adicionada: NUNCA criar lead/customer sem verificar existência
- Secção "DEFINIÇÕES CRÍTICAS" com distinção clara:
- Lead vs Customer (tabela comparativa)
- Proposal vs Estimate (tabela comparativa)
- Diagrama de fluxo comercial actualizado
- "Orçamento" = Proposal (para leads), não Estimate
- Anti-patterns reorganizados por categoria
- Terminologia PT clarificada
### v1.1.0 (2026-01-28)
- Adicionadas ferramentas de itens: add_proposal_items, get_proposal_items
- Documentado padrão tblitemable para itens de documentos
- Adicionados novos anti-patterns (tabelas inventadas, proposals vs estimates)
- Fluxo completo para adicionar itens a proposals
- Actualizada lista de MCP tools para proposals
### v1.0.0 (2026-01-28)
- Versão inicial completa
- Fluxo comercial documentado
- Regras de verificação
- Status codes
- Integração com MCP desk-crm-v3
### v0.1.0 (2026-01-28)
- Estrutura inicial da skill
- Definição de comandos e fluxos
---
**Criado:** 2026-01-28
**Actualizado:** 2026-01-28
**Motivo:** Prevenção de erros CRM após incidente de duplicação
+18
View File
@@ -306,6 +306,24 @@ Skills descontinuadas:
- Distinção Lead vs Customer
- Proposal vs Estimate
---
## Self-Healing
Antes de executar, ler `~/.claude-work/healing/crm.jsonl` (se existir). Cada linha é um padrão de erro conhecido:
```json
{"date":"YYYY-MM-DD","issue":"descrição do problema","fix":"como evitar","source":"user|auto"}
```
Se encontrares um padrão relevante ao contexto actual, aplica o fix preventivamente. Após cada erro ou correcção do utilizador nesta skill, **adicionar nova linha** ao healing log com o padrão aprendido.
---
*Skill v2.0.0 | 2026-02-05 | Descomplicar®*
## Healing Log
<!-- Registo automático de erros e correcções nesta skill -->
+18
View File
@@ -235,6 +235,24 @@ Ao entrar numa pasta:
### v1.0.0
- Versão inicial
---
## Self-Healing
Antes de executar, ler `~/.claude-work/healing/desk.jsonl` (se existir). Cada linha é um padrão de erro conhecido:
```json
{"date":"YYYY-MM-DD","issue":"descrição do problema","fix":"como evitar","source":"user|auto"}
```
Se encontrares um padrão relevante ao contexto actual, aplica o fix preventivamente. Após cada erro ou correcção do utilizador nesta skill, **adicionar nova linha** ao healing log com o padrão aprendido.
---
*Skill v3.0.0 | 2026-02-05 | Descomplicar®*
## Healing Log
<!-- Registo automático de erros e correcções nesta skill -->
+174
View File
@@ -0,0 +1,174 @@
---
name: estrategia-marca
description: Cria estratégias de marca completas seguindo a metodologia Descomplicar® (ACIDA + Framework 16Ps). Inclui fase de pesquisa de mercado com /deep-research antes do briefing. Guia a análise de público, posicionamento, Pitch Canvas, copywriting e documento final entregável. Usar quando o utilizador diz "estratégia de marca", "branding", "criar marca", "posicionamento", "16Ps", "/estrategia-marca", "análise de público", "narrativa de marca", "proposta de valor", "pitch canvas", "pain + gain", "copywriting estratégico", "identidade de marca", "pesquisa de mercado para marca", ou quando um cliente adquire o serviço EST-MRK-010.
---
# Skill: Estratégia de Marca
Guia completo para criar estratégias de marca Descomplicar® — da pesquisa de mercado ao documento final entregável.
---
## Fluxo de trabalho (8 fases)
### Fase 0 — Pesquisa de mercado
Antes do briefing com o cliente, fazer pesquisa independente. Verificar primeiro se já existem ficheiros de pesquisa (ex: pasta `Pesquisas/` no projecto).
**Se a pesquisa já existe:** ler os ficheiros relevantes e extrair síntese.
**Se não existe:** usar `/deep-research` (ou `mcp__tavily__tavily_research`) com os seguintes focos:
1. **Mercado/sector** — dimensão, crescimento, tendências, regulação
2. **Concorrentes** — posicionamento, mensagens, pricing, pontos fracos
3. **Público** — linguagem online, canais activos, dores expressas em fóruns/reviews
4. **Oportunidades** — gaps de mercado, tendências emergentes não exploradas
Guardar síntese em `Pesquisas/sintese-mercado.md` no projecto do cliente.
**Resultado esperado:** chegar ao briefing já com hipóteses validadas sobre o mercado e o público — não para impor, mas para fazer perguntas mais certeiras e poupar tempo ao cliente.
### Fase 1 — Activação e contexto
Ao iniciar, perguntar:
- Qual o nome do cliente/marca?
- Já existe briefing ou material de partida?
- Qual o sector/indústria?
- Temos exemplos de concorrentes?
Se existir projecto no Desk CRM, verificar com `get_project` antes de prosseguir.
### Fase 2 — Briefing estruturado
Conduzir entrevista com as perguntas de `references/perguntas-briefing.md`.
Organizar por blocos:
1. Negócio (problema, serviços, mercado)
2. Público-alvo (segmentos identificados)
3. Posicionamento actual vs desejado
4. Tom de voz e personalidade
5. Concorrência e diferenciação
### Fase 3 — Fundamentos estratégicos
Desenvolver com o cliente:
- **Proposta de valor única** — o que nos torna únicos, diferenciais, benefícios por camada
- **Missão, Visão, Valores e Objectivos** — com exemplos de como se manifestam na prática
- **Apresentação sumária** — empresa + serviços com tabela clara
- **Posicionamento** — declaração de posicionamento testável
Ver `references/framework-16ps.md` → Bloco A para questões orientadoras.
### Fase 4 — Análise de público (20 pontos por segmento)
**Obrigatório:** Antes dos segmentos psicográficos, identificar os nichos sectoriais relevantes para o produto. Usar `references/nichos.md` para seleccionar e analisar **pelo menos 5 nichos específicos** (ex: clínicas de saúde, imobiliárias, agências digitais — não "PMEs" como categoria vaga). Para cada nicho preencher os 8 pontos do guia de análise sectorial. Cruzar com os 20 pontos psicográficos abaixo para construir personas completas.
Para cada segmento identificado, desenvolver os 20 pontos na seguinte ordem:
1. Perfil Demográfico
2. Perfil Psicográfico
3. Dores
4. Anseios
5. Desejos
6. Frustrações
7. Preocupações
8. Medos
9. Inimigos
10. Linguagem
11. Como procuram ajuda/informação/dicas
12. Canais digitais activos
13. Estilo de Decisão
14. Mudanças (que sabem necessárias)
15. Resistência à mudança
16. Objecções típicas (+ como ultrapassar)
17. Forma de gerar emoção
18. Argumentos (a que são mais sensíveis)
19. Concorrentes (que alternativas avaliam)
20. Propostas Recusadas (e porquê)
Ver `references/metodologia-acida.md` para contexto e profundidade em cada ponto.
### Fase 5 — Pitch Canvas
Estrutura de 5 elementos:
- **Para quem:** segmento + problema específico
- **O problema:** dor principal na linguagem do cliente
- **A solução:** mecanismo único de resolução
- **O resultado:** transformação concreta (antes/depois + métrica)
- **Por que nós:** razão para acreditar
Criar também a **Declaração de mudança no mundo** — frase que resume o impacto maior da marca.
### Fase 6 — Copywriting estratégico
Sequência obrigatória:
1. **Questionamento estratégico** — Qual é o objectivo da comunicação? Que transformação prometemos?
2. **Pain + Gain** — formulação problema/resultado na linguagem do cliente; depois refinar com especificidades do sector
3. **Narrativa por segmento** — fórmula: Problema (dor do público) → Solução (serviços) → Resultado (benefícios concretos)
4. **Mensagem central** — 1 frase que toda a equipa sabe de cor
5. **Headlines** — por segmento (principal + secundária)
Ver `references/narrativas-copywriting.md` para templates e exemplos reais.
### Fase 7 — Documento final + Investimentos
Completar as secções finais:
- **Demonstração dos serviços** — como demonstrar, preparação, follow-up
- **Investimentos prioritários** — canais, orçamento, ROI esperado
- **KPIs** — baseline + metas a 3m, 6m, 12m
- **Inventário de activos** — o que existe, estado, prioridade
Ver `references/template-documento.md` para a estrutura completa do documento.
**Checklist de entrega:**
- [ ] Pesquisa de mercado feita (Fase 0)
- [ ] Proposta de valor única definida
- [ ] Missão, Visão, Valores escritos
- [ ] Apresentação sumária da empresa e serviços
- [ ] Mínimo 5 nichos sectoriais analisados (8 pontos cada) — ver `references/nichos.md`
- [ ] Mínimo 2 segmentos psicográficos com 20 pontos completos
- [ ] Pitch Canvas preenchido
- [ ] Declaração de mudança no mundo
- [ ] Pain + Gain (original + refinado)
- [ ] Narrativa por segmento (Problema → Solução → Resultado)
- [ ] Mensagem central definida
- [ ] Investimentos prioritários identificados
- [ ] KPIs definidos com metas
---
## Referências (carregar conforme necessário)
| Ficheiro | Quando carregar |
|----------|----------------|
| `references/metodologia-acida.md` | Fases 3-4: ACIDA, 20 pontos por segmento |
| `references/framework-16ps.md` | Fase 3: fundamentos estratégicos (Bloco A) |
| `references/perguntas-briefing.md` | Fase 2: conduzir entrevista cliente |
| `references/narrativas-copywriting.md` | Fase 6: copywriting, Pain+Gain, narrativas |
| `references/template-documento.md` | Fase 7: estrutura completa do documento |
| `references/nichos.md` | Fase 4: análise sectorial dos 10 nichos PT/EU (mínimo 5 obrigatórios) |
---
## Contexto do serviço
- **Código:** EST-MRK-010
- **Preço:** 900 EUR
- **Prazo médio:** 30h de trabalho
- **Entregáveis:** Documento estratégico completo, dashboard personas, narrativa de marca, apresentação executiva editável, guia de implementação, sessão de alinhamento com equipa
- **Suporte pós-entrega:** WhatsApp 1 mês
Complementar com Branding WOW (BRAND-ESS/DIG/COM: 1.8004.500 EUR) se o cliente precisar de identidade visual.
---
## 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.*
@@ -0,0 +1,193 @@
# Framework 16Ps — Referência Completa
Estrutura os 16 elementos da estratégia de marca em 4 blocos. Para cada P, incluir as questões orientadoras ao preencher.
---
## Bloco A — Fundamentos estratégicos
### P1: Problema
> Qual o problema principal que a marca resolve?
- Problema de negócio que a estratégia precisa resolver
- Impacto desse problema no cliente (custo, tempo, risco, reputação)
- Urgência da solução: por que resolver agora?
- Consequências de não resolver
*Exemplo SFV:* "Facturas de electricidade crescentes que consomem margens das empresas e rendimento das famílias, sem solução acessível percebida."
### P2: Propósito
> Por que existe esta marca além do lucro?
- **Missão:** o que fazemos e para quem (hoje)
- **Visão:** onde queremos chegar (3-5 anos)
- **Valores:** 3-5 valores fundamentais com descrição de como se manifestam
- **Propósito:** impacto no mundo que justifica a existência da marca
*Estrutura valores:* [Nome do Valor] — [Como se manifesta na prática]
### P3: Proposta de Valor
> O que tornamos possível que os concorrentes não conseguem?
- Valor único que só esta marca entrega
- Diferenciais competitivos (lista)
- Benefícios principais (funcionais + emocionais)
- Formula: Para [segmento], que [dor/desejo], a [marca] oferece [solução] que [resultado único], ao contrário de [alternativa], porque [razão para acreditar]
### P4: Posicionamento
> Que lugar específico ocupa na mente do cliente?
- Posição actual no mercado (percepção real)
- Posição desejada (percepção target)
- Declaração de posicionamento (1-2 frases)
- Território da marca: categoria, concorrência directa, diferenciação
- Atributos únicos que definem esse território
*Declaração-tipo:* "Para [público], somos a única [categoria] que [benefício único] porque [prova]."
### P5: Performance
> Como medimos o sucesso?
- KPIs principais (5-7 métricas)
- Metas específicas a 3, 6 e 12 meses
- Indicadores de sucesso por área (brand awareness, conversão, satisfação)
- Frequência de monitorização e responsável
---
## Bloco B — Público e pesquisa
### P6: Público-alvo
> Quem são exactamente os nossos clientes?
- Segmento principal + segmentos secundários
- Critérios de segmentação (demográficos, comportamentais, psicográficos)
- Volume estimado de cada segmento
- Comportamento de compra: frequência, ticket médio, canal preferido
### P7: Pesquisa de mercado
> Que dados sustentam as nossas decisões?
- Dados de mercado: dimensão, crescimento, tendências
- Insights de comportamento do consumidor
- Oportunidades identificadas (não aproveitadas pela concorrência)
- Ameaças e riscos do mercado
### P8: Personas
> Quem é o nosso cliente ideal em detalhe?
Para cada persona:
- **Foto + nome fictício + idade + profissão**
- **Biografia resumida** (um dia típico)
- **Dores principais** (3-5)
- **Objectivos** (profissionais + pessoais)
- **Canais preferidos** (onde está, o que consome)
- **Citação representativa** ("Eu quero/preciso/temo...")
- **Frase de posicionamento** para esta persona
### P9: Perfil
> Quais as características quantificáveis de cada segmento?
Análise de 20 pontos por segmento (ver template completo em `template-documento.md`):
- Demográfico: idade, género, localização, rendimento, educação, sector, cargo, empresa
- Comportamental: rotina, hábitos, processo de decisão, critérios de escolha
- Psicográfico: valores, aspirações, mentalidade, atitude à inovação
- Jornada: awareness, consideração, decisão
### P10: Pain Points
> Quais as dores mais urgentes e dolorosas?
- Dores principais (urgentes, que precisam resolver já)
- Frustrações (já tentaram outras soluções sem resultado)
- Necessidades não atendidas (o mercado não resolve bem)
- Medos relacionados com a compra ou com não comprar
---
## Bloco C — Produto e serviço
### P11: Portfolio
> O que vendemos exactamente?
- Lista de produtos/serviços principais
- Características técnicas vs benefícios percebidos
- Arquitectura de oferta: entrada, core, premium
- Casos de uso reais (exemplos concretos de aplicação)
### P12: Preço e valor
> Como justificamos o que cobramos?
- Estratégia de preços (custo+margem, valor percebido, concorrência, freemium)
- Posicionamento de valor: acessível, médio-alto, premium, luxo
- Política comercial: descontos, bundles, condições de pagamento
- ROI estimado para o cliente (quanto ganha/poupa ao escolher-nos)
### P13: Processos críticos
> Que processos garantem a experiência prometida?
- Processo de entrega do serviço/produto (passo a passo)
- Pontos de controlo de qualidade
- Garantias e políticas de satisfação
- Gestão de reclamações
### P14: Parcerias estratégicas
> Com quem nos aliamos para ampliar valor?
- Parceiros principais (nome, tipo, contribuição)
- Tipos de parceria: distribuição, tecnologia, referência, co-marketing
- Benefícios mútuos de cada parceria
- Parcerias a desenvolver (gap de oportunidade)
### P15: Plataforma
> Onde operamos digitalmente?
- Canais digitais activos: website, redes sociais, marketplaces, apps
- Presença online actual vs ideal
- Infraestrutura tecnológica (CRM, email, analytics, automação)
- Prioridades de investimento digital
---
## Bloco D — Promoção e comunicação
### P16: Promoção
> Como chegamos ao público-alvo?
- Canais principais com objectivos específicos por canal
- Tácticas específicas (conteúdo, SEO, email, WhatsApp, eventos)
- Calendário promocional (frequência, momentos-chave)
- Budget orientativo por canal
### P17: Publicidade
> Como amplificamos com investimento pago?
- Estratégia de anúncios: plataformas, formato, objectivo
- Budget mensal e distribuição
- KPIs de publicidade (CPL, ROAS, CPA)
- Frequência e ciclo de renovação de criativos
### P18: PR e referências
> Como construímos credibilidade externa?
- Estratégia de relações públicas
- Parcerias com influenciadores (relevância > alcance)
- Imprensa e media especializada
- Programa de referências/embaixadores
### P19: Presença digital
> Qual a nossa estratégia de conteúdo?
- Estratégia de conteúdo por canal
- Frequência de publicação
- Pilares de conteúdo (3-5 temas centrais)
- Gestão de comunidade: resposta, engagement, moderação
### P20: Proximidade — narrativa e impacto
> Que história contamos que ressoa emocionalmente?
- **Declaração de Impacto:** frase que resume a essência e impacto da marca
- **Narrativa principal:** história de origem ou transformação
- **Pain + Gain por segmento:** o que perdiam antes → o que ganham agora
- **Mensagem central:** 1 frase que todos os colaboradores sabem de cor
*Nota: O "Bloco D" tem 5 Ps numerados de 16 a 20 — alguns documentos listam apenas 16 Ps no total (agrupando Promoção, Publicidade e PR num único P). Adaptar conforme o nível de detalhe necessário.*
@@ -0,0 +1,127 @@
# Metodologia ACIDA — Referência Completa
## 1. As 5 fases ACIDA
### A — Atrair atenção
O público está sobrecarregado de informação. A forma correcta de chamar a atenção não é destacar produtos — é conectar com o que emocionalmente mais interessa ao público: **as suas próprias dores e desejos**.
Acções práticas:
- Headlines que falam directamente da dor ou desejo do segmento
- Conteúdo que provoca reconhecimento imediato ("é exactamente o meu problema")
- Formatos visuais que param o scroll: vídeo curto, imagem disruptiva, estatística chocante
### C — Construir confiança
Após conquistar atenção, estabelecer relacionamentos autênticos através de:
- Transparência, honestidade e autenticidade na comunicação
- Demonstrar compreensão profunda das dores e desejos do cliente
- Partilhar conhecimento e experiência profissional abertamente
- Educar o público para decisões mais informadas
- Estabelecer autoridade que permite influenciar percepções
Formatos: artigos de blog, estudos de caso, testemunhos, webinars, guias gratuitos.
### I — Despertar interesse
Com confiança estabelecida, a comunicação torna-se altamente personalizada.
> "Não vendemos produtos nem serviços; oferecemos soluções específicas para os seus desafios."
Ferramentas:
- Rastreamento de interacções para identificar segmentos de clientes
- Conteúdo customizado baseado em comportamentos anteriores
- Resolução antecipada de objecções conhecidas
- Nutrição de relacionamentos via email, WhatsApp, SMS, redes sociais
### D — Estimular a decisão
A decisão será favorável se o **valor percebido > preço a pagar**.
Obstáculos a superar:
- O "muro invisível" criado por dúvidas do consumidor
- Medo do arrependimento pós-compra
- Necessidade de prova social e garantias sólidas
Ferramentas: comparações, garantias, testemunhos de clientes reais, demonstrações, ROI calculado.
### A — Incentivar a acção
Converter interesse em acção através de:
- Chamadas à acção (CTA) claras e convincentes
- Criação de sentido de urgência (real, não artificial)
- Cumprimento de promessas
- Superação de expectativas na experiência do cliente
---
## 2. Análise do público-alvo — 8 dimensões
Para cada segmento, investigar as 8 dimensões antes de escrever qualquer copy:
### Dimensão 1: Perfil demográfico e psicográfico
- Características mensuráveis: idade, género, localização, rendimento, educação, cargo
- Traços de personalidade: valores, crenças, atitudes, estilo de vida
- *Pergunta-chave: "Quem é esta pessoa na vida real?"*
### Dimensão 2: Dores, desejos e frustrações
- Dores activas: problemas que precisam resolver agora
- Desejos: o que querem alcançar/ter/ser
- Frustrações: o que já tentaram e não funcionou
- *Pergunta-chave: "O que os mantém acordados à noite? O que sonham?"*
### Dimensão 3: Preocupações e geração de emoção
- O que os preocupa a médio/longo prazo
- Como a nossa marca pode responder emocionalmente (não apenas racionalmente)
- *Pergunta-chave: "Que emoção queremos que sintam quando nos encontram?"*
### Dimensão 4: Medos, inimigos e mudanças
- Medos concretos (perder negócio, ser enganado, falhar)
- "Inimigos" percebidos (concorrentes, reguladores, tendências de mercado)
- Mudanças que temem ou resistem
- *Pergunta-chave: "O que os impede de agir?"*
### Dimensão 5: Anseios, interesses e linguagem
- O que aspiram a ser/ter/fazer
- Interesses e hobbies (pistas para onde comunicar)
- Linguagem que usam (jargão do sector, palavras que ressoam vs que afastam)
- *Pergunta-chave: "Como falam entre si? Que palavras usam?"*
### Dimensão 6: Pesquisa de informação e influenciadores
- Onde procuram informação (Google, YouTube, LinkedIn, feiras, colegas)
- A quem pedem conselho (influenciadores, peers, família)
- Fontes que consideram credíveis
- *Pergunta-chave: "Como encontraram a nossa categoria de produto/serviço?"*
### Dimensão 7: Dúvidas e perguntas
- Objecções previsíveis antes da compra
- Perguntas que fazem nas reuniões de vendas
- Informação que precisam para decidir
- *Pergunta-chave: "Quais as 5 objecções mais frequentes?"*
### Dimensão 8: Estilo de decisão e concorrentes
- Processo de decisão: individual vs colectivo, rápido vs lento
- Factores comparativos: preço, qualidade, confiança, referências
- Concorrentes directos que avaliam em paralelo
- *Pergunta-chave: "Com quem nos comparam? Por que nos escolhem ou não?"*
---
## 3. Pilares estratégicos ACIDA
- **Crença central:** o centro do marketing digital são os princípios fundamentais de marketing + website — não as redes sociais
- **Proposta de valor:** "Criamos Resultados" — problema → solução → resultados esperados
- **Website como hub central:** não repositório, mas centro operacional integrado com CRM
- **Ecossistema multi-canal:** email, SMS/WhatsApp, SEO, Google/Meta Ads, website, redes sociais (como parte, não como centro)
- **Melhoria contínua:** métricas objectivas → ciclo iterativo baseado em dados
---
## 4. ACIDA 2.0 — Fases operacionais
| Fase | Acções |
|------|--------|
| **1. Análise** | Segmentação público, posicionamento, estruturação oferta, montagem narrativa |
| **2. Criação** | Recursos, copywriting e design, website e plataformas, automação |
| **3. Implementação** | Conteúdos e canais, blog e email marketing, redes sociais, marketplaces |
| **4. Desenvolvimento** | Funil de vendas, tráfego e anúncios, conteúdos, newsletters |
| **5. Acompanhamento** | Gestão de resultados, métricas e KPIs, optimização contínua, suporte |
@@ -0,0 +1,154 @@
# Narrativas e Copywriting Estratégico
Templates e exemplos reais de narrativas Descomplicar®. Baseados nos projectos SFV, LJM, MCT e Espiral Senior.
---
## 1. Fórmula central: Dor → Solução → Resultado
Estrutura base para qualquer narrativa por segmento:
```
DOR: [Nome do segmento] enfrenta [problema específico e urgente].
Sem solução, [consequência negativa concreta].
SOLUÇÃO: [Nome da marca] resolve isto através de [mecanismo único].
[Diferencial que os concorrentes não têm].
RESULTADO: O resultado é [benefício tangível e mensurável].
[Prova social ou garantia que aumenta credibilidade].
```
**Exemplo SFV (segmento Empresas):**
> Dor: As PMEs enfrentam facturas de electricidade crescentes que consomem margens já apertadas.
> Solução: A SFV instala painéis solares personalizados com análise de consumo prévia — sem adiantamento para projectos qualificados.
> Resultado: Redução de 60-90% na factura eléctrica, com ROI em 4-7 anos e garantia de 25 anos nos painéis.
**Exemplo MCT (segmento Oficinas):**
> Dor: Mecânicos perdem tempo e dinheiro com ferramentas que chegam erradas, incompletas ou que avariam em obra.
> Solução: A Carritools fornece equipamento profissional com assessoria técnica presencial e substituição imediata em caso de avaria.
> Resultado: Menos tempo parado, mais trabalhos concluídos, clientes mais satisfeitos.
---
## 2. Declaração de Impacto
Uma frase poderosa que abre o documento e resume a essência da marca. Deve:
- Ser memorável (10-15 palavras máximo)
- Combinar emoção + resultado
- Não ser genérica ("líderes de mercado", "qualidade e inovação")
**Exemplos reais:**
| Cliente | Declaração de Impacto |
|---------|----------------------|
| SFV Solar | "Energia (quase) Grátis para Famílias e Empresas" |
| Espiral Senior | "Envelhecer em Dignidade, no Lugar que Mais Ama" |
| Descomplicar® | "Criamos Resultados!" |
**Fórmulas para gerar Declaração de Impacto:**
- `[Verbo de transformação] + [benefício desejado] + [para quem]`
- `[Adjectivo emocional] + [resultado concreto]`
- `[Benefício surpreendente] + [para quem] + [sem o custo habitual]`
---
## 3. Mensagens-chave por tipo de segmento
### Segmento decisor (CEO/Gerente)
Foco: ROI, risco reduzido, credibilidade, tempo poupado.
Template:
> "Mais de [N] empresas como a sua já [resultado]. A nossa abordagem garante [benefício financeiro] em [prazo], com [garantia específica]."
### Segmento utilizador final (técnico/operacional)
Foco: facilidade de uso, suporte, fiabilidade, não criar problemas.
Template:
> "Simples de implementar, sem interrupções ao seu trabalho. Em caso de dúvida, temos suporte [detalhe] para que nunca fique bloqueado."
### Segmento referenciador (parceiro/consultor)
Foco: credibilidade para recomendar, win-win, diferenciação para os seus clientes.
Template:
> "Ao recomendar [marca], está a oferecer aos seus clientes [resultado], o que reforça a sua autoridade como [cargo/papel]."
### Segmento influenciador (família/comunidade)
Foco: valores partilhados, impacto positivo, pertença.
Template:
> "Não é só [produto/serviço]. É uma escolha que [impacto maior]: [dimensão ambiental/social/familiar]."
---
## 4. Gestão de objecções — estrutura padrão
Para cada objecção, responder sempre com:
1. **Validar** — reconhecer que é uma preocupação legítima
2. **Reframeamento** — mudar o ângulo de análise
3. **Prova** — exemplo, dado ou testemunho que confirma
4. **CTA suave** — próximo passo de baixo compromisso
**Objecções universais e respostas tipo:**
| Objecção | Resposta base |
|----------|--------------|
| "É caro" | "Entendo a preocupação. O nosso preço reflecte [diferencial]. Clientes como [X] recuperaram o investimento em [prazo]. Posso mostrar-lhe o cálculo?" |
| "Preciso de pensar" | "Faz todo o sentido. O que precisa de esclarecer para se sentir confiante? Posso enviar [recurso específico] que costuma ajudar nesta fase." |
| "Já tentei algo parecido e não funcionou" | "Compreendo — essa experiência é frustrante. O que tipicamente falha é [causa]. A nossa abordagem resolve isto de forma diferente: [diferencial]." |
| "Não tenho tempo agora" | "Respeitamos o seu tempo. É por isso que o nosso processo começa com apenas [X horas], e tratamos nós de [trabalho pesado]." |
| "Preciso de aprovação interna" | "Claro. Posso preparar um resumo executivo de 1 página para facilitar a aprovação? Tenho feito isto para outros clientes com muito bom resultado." |
---
## 5. Tom de voz por personalidade de marca
### Marca especialista/técnica (ex: SFV, Carritools)
- Linguagem precisa, dados concretos, terminologia do sector
- Evitar: exageros sem prova, linguagem emocional excessiva
- Usar: casos reais, números, especificações, garantias técnicas
### Marca próxima/humana (ex: Espiral Senior, Loja da Maria)
- Linguagem calorosa, inclusiva, em 2ª pessoa
- Evitar: jargão técnico, distância corporativa
- Usar: histórias pessoais, empatia directa, linguagem do dia-a-dia
### Marca inovadora/disruptiva (ex: Descomplicar, SaaS)
- Linguagem energética, directa, com algum desafio ao status quo
- Evitar: clichés do sector, promessas vazias
- Usar: contraste antes/depois, resultados surpreendentes, "E se..."
---
## 6. Estrutura de testemunho ideal
Baseado nos testemunhos reais recolhidos nos projectos:
```
[Nome próprio + cargo + empresa] — [cidade, se relevante]
"[Frase de impacto espontânea que resume o resultado]"
Contexto: [Situação antes de contratar]
Resultado: [Mudança concreta e mensurável após]
Recomendação: [Indicação explícita para outros como ele]
```
**Exemplo real SFV:**
> "Ricardo Castelão, Director Financeiro, Empresa de Distribuição — Porto
> 'Reduzimos a nossa factura eléctrica em 73% no primeiro ano.'
> Contexto: Gastávamos 4.200 EUR/mês em electricidade, sem alternativa viável.
> Resultado: Passámos para 1.134 EUR/mês. O sistema pagou-se em 5,5 anos.
> Recomendação: Para qualquer empresa com consumo acima de 1.500 EUR/mês, é obrigatório analisar esta opção."
---
## 7. Headlines de alto impacto — padrões
Padrões que funcionam consistentemente nos projectos Descomplicar:
- **Resultado específico:** "Reduza a sua factura eléctrica em 70% sem investimento inicial"
- **Pergunta dor:** "Ainda a pagar [problema] quando existe solução comprovada?"
- **Autoridade + resultado:** "Como [N] empresas [resultado] com [solução]"
- **Contrafactual:** "E se a sua maior despesa se transformasse no seu maior activo?"
- **Urgência real:** "A [mudança de mercado/regulação] está a mudar tudo — [posição da marca]"
- **Social proof:** "Mais de [N] clientes em [região] já [resultado]"
@@ -0,0 +1,318 @@
# Análise de Nichos — Guia de Segmentação Sectorial
Para marcas com público PME, "PME" é demasiado vasto. Identificar os nichos sectoriais específicos permite mensagens certeiras, canais certos e ROI superior. Qualquer estratégia de marca deve analisar **pelo menos 5 nichos específicos** relevantes para o produto/serviço.
---
## Como usar este guia
1. Identificar os nichos onde o produto/serviço tem tracção real ou potencial
2. Para cada nicho seleccionado, preencher os 8 pontos de análise sectorial
3. Cruzar com os 20 pontos da análise de público (template-documento.md § 5) para o perfil completo
4. Priorizar os 3 nichos de maior potencial para messaging principal
---
## Os 8 pontos de análise por nicho
Para cada nicho, responder:
1. **Dimensão e contexto** — quantas empresas em PT/EU, crescimento do sector, maturidade digital
2. **Dores operacionais específicas** — o que os cansa no dia-a-dia (não genérico: específico do sector)
3. **Funcionalidades mais relevantes** — o que do produto resolve melhor o problema deste nicho
4. **Linguagem de venda** — palavras que usam, palavras que evitam, jargão do sector
5. **Canal de aquisição principal** — onde estão, como chegam ao produto
6. **Objecção principal** — o bloqueio mais frequente e como ultrapassar
7. **Trigger de compra** — o momento/evento que precipita a decisão
8. **Pricing sweet spot** — o que pagam por ferramentas similares, sensibilidade ao preço
---
## Os 10 nichos de PME mais relevantes (PT/EU)
### Nicho 1 — Saúde Privada
**Quem:** Clínicas dentárias, psicólogos, nutricionistas, fisioterapeutas, clínicas médicas privadas, terapeutas.
**Dimensão PT:** +12.000 clínicas e consultórios privados. Sector em crescimento pós-pandemia. Alta concentração em Lisboa, Porto e litoral.
**Dores operacionais:**
- Agenda manual ou em sistemas desactualizados (Doctoralia, papel)
- Falhas de consulta (no-shows) sem sistema de lembretes automatizado
- Secretaria sobrecarregada com marcações e confirmações por telefone
- Facturação em saúde com complexidade fiscal (isenção IVA, recibos verdes)
- RGPD em saúde: dados sensíveis com requisitos legais estritos
**Funcionalidades mais relevantes:** lembretes automáticos de consulta por WhatsApp/SMS, confirmação/cancelamento por WhatsApp, reagendamento automático, facturação PT com isenção IVA, base de conhecimento para FAQ de pacientes.
**Linguagem de venda:** "reduzir faltas à consulta", "libertar a secretária para o que importa", "pacientes confirmam pelo WhatsApp", "agenda sempre actualizada". Evitar: "automação", "IA", "bot".
**Canal de aquisição:** associações profissionais (OMD, Ordem dos Psicólogos), LinkedIn de gestores de clínica, referência entre profissionais de saúde, Google Ads ("software gestão clínica", "agenda online clínica").
**Objecção principal:** "Os meus pacientes são mais velhos e não usam WhatsApp." → Resposta: "O sistema funciona igualmente por SMS. E os cuidadores/filhos que marcam as consultas estão todos no WhatsApp."
**Trigger de compra:** crescimento de lista de espera que a secretária já não consegue gerir; terceira consulta cancelada sem aviso no mesmo mês.
**Pricing sweet spot:** €50-150/mês (referência: Doctoralia €80-200/mês).
---
### Nicho 2 — Imobiliárias e Mediação
**Quem:** Agências imobiliárias independentes, mediadores certificados (AMI), promotores imobiliários, gestoras de condomínios.
**Dimensão PT:** +5.000 agências com licença AMI activas. Mercado em alta, mas muito fragmentado. Alta dependência de WhatsApp para comunicação com compradores/vendedores.
**Dores operacionais:**
- Leads entram por portais (Imovirtual, Idealista, OLX) e ficam sem resposta rápida
- Gestão de visitas manual: telefonemas para confirmar, reagendar, cancelar
- Follow-up de compradores perdido no WhatsApp pessoal do agente
- Quando o agente sai, leva os contactos consigo
- Proposta/minuta demoram dias
**Funcionalidades mais relevantes:** resposta automática a leads de portais, qualificação de leads por WhatsApp, agendamento de visitas com confirmação automática, CRM com histórico centralizado (não no telemóvel do agente), geração de propostas.
**Linguagem de venda:** "nunca perde um lead do Idealista", "as visitas confirmam-se sozinhas", "quando o agente sai, o cliente fica na empresa", "responde ao lead em 2 minutos, a qualquer hora".
**Canal de aquisição:** associações (APEMIP, ASIP), LinkedIn de directores de agência, eventos do sector imobiliário, Google Ads ("CRM imobiliário Portugal", "software mediação imobiliária").
**Objecção principal:** "Já usamos o CRM do Idealista." → Resposta: "O CRM do portal gere os leads do portal. O AcidaOS centraliza todos os portais + WhatsApp + email num só sítio, com o histórico completo de cada cliente."
**Trigger de compra:** perda de uma venda grande por demora na resposta ao lead; saída de um agente que levou a carteira de clientes.
**Pricing sweet spot:** €80-200/mês (referência: Salesforce RE €150-300/mês, CRMs sectoriais €50-150/mês).
---
### Nicho 3 — Construção e Remodelação
**Quem:** Empreiteiros de construção civil, empresas de remodelação e acabamentos, serralheiros, carpinteiros, canalizadores com equipa, empresas de pintura.
**Dimensão PT:** sector fortíssimo — construção representa ~7% do PIB PT. Altamente fragmentado, maioria micro-empresas 1-20 pessoas. Baixa digitalização. Alta dependência de telefonema e referência.
**Dores operacionais:**
- Orçamentos demoram dias ou semanas a chegar ao cliente
- Clientes ligam 5 vezes para saber se o orçamento chegou
- Gestão de obras espalhada por papel, WhatsApp e memória do encarregado
- Facturação atrasada em relação ao trabalho realizado (meses de delay)
- Cobranças de pagamentos em atraso constrangem a relação com o cliente
**Funcionalidades mais relevantes:** geração de orçamentos, follow-up automático ("o seu orçamento foi enviado — alguma dúvida?"), facturação automática por fase de obra, lembretes de pagamento, agenda de obras com alertas de prazo.
**Linguagem de venda:** "orçamento pronto em horas, não dias", "o cliente sabe sempre o estado da obra", "recebe quando acaba, não quando se lembra". Evitar linguagem tech — falar em "tempo poupado" e "dinheiro recebido".
**Canal de aquisição:** referência entre empresários do sector, associações (AICCOPN, AECOPS), Facebook Groups de empreiteiros e remodelações, feiras de construção.
**Objecção principal:** "A minha secretária já faz isso." → Resposta: "E quando ela está de férias? O AcidaOS não vai de férias."
**Trigger de compra:** perda de um contrato por orçamento que chegou tarde; mês com 3 facturas por emitir de obras já concluídas.
**Pricing sweet spot:** €30-80/mês (sector muito sensível ao preço, mas disposto a pagar se ROI for claro e imediato).
---
### Nicho 4 — Agências Digitais e Criativas
**Quem:** Agências de marketing digital, design, comunicação, relações públicas, fotografia/vídeo, produção de conteúdo.
**Dimensão PT:** +3.500 agências activas. Sector muito competitivo, margens a comprimir. Muitas em transição de "serviços de execução" para "serviços de estratégia + produto".
**Dores operacionais:**
- Relatórios mensais para clientes consomem 2-3 dias de trabalho manual
- Gestão de aprovações de conteúdo por WhatsApp e email (versões perdidas)
- Timesheets manuais → facturação imprecisa → conflitos com clientes
- Escalabilidade travada: para crescer precisa de contratar
- Receita 100% baseada em horas → vulnerável a perdas de cliente
**Funcionalidades mais relevantes:** geração automática de relatórios mensais, portal do cliente com aprovação de conteúdos, registo automático de horas, facturação por projecto, upsell/cross-sell automatizado (ex: "o teu plano inclui X — quer adicionar Y?").
**Linguagem de venda:** "relatórios que se fazem sozinhos", "o cliente aprova no portal, não por email", "receita recorrente sem aumentar a equipa", "white-label para revender aos teus clientes".
**Canal de aquisição:** LinkedIn (muito activo neste nicho), eventos de marketing (RD Summit, Social Media Week), comunidades Slack de marketers, referência entre agências.
**Objecção principal:** "Já usamos Monday/Asana/Notion." → Resposta: "O AcidaOS integra com essas ferramentas. Mas adiciona a camada de IA que automatiza o que ainda fazem manualmente: relatórios, aprovações, facturação."
**Trigger de compra:** perda de 20% da margem num trimestre por horas não facturadas; cliente grande que pediu relatórios mais frequentes sem pagar mais.
**Pricing sweet spot:** €100-300/mês; alto potencial para plano Partner/white-label (€500-1.000/mês).
---
### Nicho 5 — Comércio B2B e Distribuição
**Quem:** Distribuidores, grossistas, representantes comerciais, importadores, empresas de venda a retalhistas.
**Dimensão PT:** sector fundamental da economia, muito diversificado. Ciclos de venda mais longos, pedidos recorrentes, relacionamento comercial crítico.
**Dores operacionais:**
- Pedidos chegam por WhatsApp, email e telefone — sem registo centralizado
- Catálogo de produtos actualizado só existe em Excel ou PDF
- Comerciais perdem tempo a dar preços e a verificar stock pelo telefone
- Dívidas de clientes descobertas tarde (só quando o contabilista avisa)
- Fidelização: o cliente vai ao concorrente se não for contactado regularmente
**Funcionalidades mais relevantes:** chatbot de catálogo e preços por WhatsApp, processamento de pedidos automático, alertas de pagamentos em atraso, follow-up automático de clientes inativos ("não nos pede há 30 dias — tudo bem?"), facturação automática por encomenda.
**Linguagem de venda:** "o cliente pede pelo WhatsApp e a factura sai automática", "nunca perde uma encomenda por estar em reunião", "sabe quem não lhe compra há um mês antes de o perder".
**Canal de aquisição:** associações sectoriais, feiras B2B, LinkedIn de directores comerciais, referência entre distribuidores.
**Objecção principal:** "Os meus clientes são empresas — preferem email formal." → Resposta: "O sistema funciona por email também. E o WhatsApp para os urgentes — que são 80% dos pedidos reais."
**Trigger de compra:** perda de cliente para concorrente por resposta mais rápida; mês com facturas em atraso acima de €10K.
**Pricing sweet spot:** €100-250/mês (dispostos a pagar pelo ROI directo em cobranças e pedidos capturados).
---
### Nicho 6 — Restauração e Hotelaria
**Quem:** Restaurantes, cafés, bares, hotéis boutique, alojamentos locais, serviços de catering, espaços de eventos.
**Dimensão PT:** +80.000 estabelecimentos de restauração. Sector de margens apertadas, alta rotatividade de staff, sazonalidade intensa.
**Dores operacionais:**
- Reservas por telefone interrompem o serviço → perdidas quando está cheio
- Grupos e eventos corporativos: orçamentação manual e demorada
- Gestão de feedback online (Google, Tripadvisor) sem resposta sistemática
- Campanhas de WhatsApp para promoções especiais feitas manualmente
- Alojamento local: check-in remoto, comunicação com hóspedes em múltiplas línguas
**Funcionalidades mais relevantes:** reservas e confirmações por WhatsApp, resposta automática a reviews Google, campanhas de promoções ("mesa disponível para amanhã?"), comunicação com hóspedes em PT/EN/ES automática, facturação de eventos.
**Linguagem de venda:** "mesa reservada e confirmada sem tirar o empregado do serviço", "campanhas de promoção para a base de clientes em 2 minutos", "hóspedes atendidos em qualquer língua, a qualquer hora".
**Canal de aquisição:** associações (AHRESP, ARESP), feiras do sector (Horexpo, BTL), Instagram/Facebook de restaurateurs, referência entre proprietários.
**Objecção principal:** "O meu cliente quer falar com uma pessoa." → Resposta: "O sistema trata das confirmações de rotina. Quando o cliente quer falar com alguém, o sistema escala — e o teu staff tem mais tempo para isso."
**Trigger de compra:** mesa dupla marcada no mesmo horário; alta temporada com reservas a escapar por não conseguir atender o telefone.
**Pricing sweet spot:** €30-80/mês (margens apertadas — proposta tem de ser de ROI imediato e muito claro).
---
### Nicho 7 — Contabilidade e Consultoria
**Quem:** Gabinetes de contabilidade, TOCs (Técnicos Oficiais de Contas), escritórios de advogados, consultores de gestão, solicitadores.
**Dimensão PT:** +8.000 gabinetes de contabilidade registados. Sector muito regulado, conservador, mas sob pressão de digitalização e de novas exigências da AT.
**Dores operacionais:**
- Clientes entregam documentação de forma caótica (papel, foto de WhatsApp, email)
- Prazos fiscais críticos (IRS, IRC, IVA, SS) gerem-se manualmente com risco de multa
- Comunicação de alertas a clientes por email → baixa taxa de abertura
- Facturação de honorários por horas não registadas sistematicamente
- Novos clientes: onboarding burocrático e demorado
**Funcionalidades mais relevantes:** portal de recolha de documentos do cliente, alertas de prazos fiscais automáticos por WhatsApp, registo automático de horas, facturação mensal, onboarding digital de clientes.
**Linguagem de venda:** "o cliente entrega os documentos pelo WhatsApp e chegam organizados", "o cliente recebe o alerta de IVA no dia certo, não quando já passou", "sem ligar 5 vezes para pedir o recibo". Evitar: "IA", "automação" — usar "sistema", "organização", "processo".
**Canal de aquisição:** Ordem dos Contabilistas Certificados, formações profissionais obrigatórias, referência entre TOCs, LinkedIn de gestores de gabinetes.
**Objecção principal:** "Os nossos clientes são conservadores e resistem a mudanças." → Resposta: "O cliente não vê nenhuma mudança — continua a mandar fotos para o WhatsApp. Só que chegam organizadas ao sistema em vez de à caixa de entrada da Ana."
**Trigger de compra:** multa de cliente por prazo fiscal falhado por comunicação deficiente; novo quadro legal que aumenta o volume de entregas obrigatórias.
**Pricing sweet spot:** €50-150/mês (sector conservador no pricing mas com ROI muito mensurável em tempo poupado).
---
### Nicho 8 — E-commerce e Retalho Online
**Quem:** Lojas online, marcas DTC (direct-to-consumer), revendedores em marketplace (Amazon PT, FNAC, Worten), lojas omnicanal (físico + online).
**Dimensão PT:** +25.000 lojas online activas. Crescimento acelerado mas altíssima competição e margens em queda.
**Dores operacionais:**
- Volume de mensagens de suporte pós-venda (estado da encomenda, devoluções) insustentável
- Carrinhos abandonados sem follow-up automático → receita perdida
- Campanhas de reactivação de clientes inativos feitas manualmente
- Devoluções: processo manual, email interminável, cliente frustrado
- Avaliações negativas sem resposta → impacto na conversão
**Funcionalidades mais relevantes:** suporte automático de "onde está a minha encomenda" por WhatsApp, follow-up de carrinho abandonado, campanha de reactivação de clientes inativos, gestão de devoluções automatizada, resposta a reviews.
**Linguagem de venda:** "responde a 80% das perguntas de suporte sem intervenção humana", "recupera 15% dos carrinhos abandonados com um WhatsApp certo", "o cliente fica satisfeito sem precisar de esperar por email".
**Canal de aquisição:** comunidades de e-commerce (Shopify PT Facebook Group, grupos LinkedIn de e-commerce), eventos (eCommerce Day, NOS Alive), agências de e-commerce como parceiros.
**Objecção principal:** "Já usamos o suporte do Shopify." → Resposta: "O suporte do Shopify trata do que está dentro da plataforma. O AcidaOS trata do WhatsApp, do email e das mensagens do Instagram — que é de onde vêm 70% das perguntas reais."
**Trigger de compra:** Black Friday com volume de suporte 5x superior ao habitual sem equipa para responder; mês com carrinho abandonado acima de 70% sem follow-up.
**Pricing sweet spot:** €69-149/mês (familiarizados com SaaS, comparam com Gorgias €10-150/mês, Tidio €29-100/mês).
---
### Nicho 9 — Educação e Formação
**Quem:** Centros de formação profissional, explicadores e centros de explicações, escolas de línguas, escolas de música/artes, coaches e mentores, plataformas de formação online.
**Dimensão PT:** sector em expansão acelerada. Formação profissional fortemente subsidiada (FSE/IEFP) com requisitos administrativos pesados.
**Dores operacionais:**
- Matrículas e inscrições por telefone e email — processo manual e demorado
- Comunicação com pais (no caso de menores) caótica e dispersa
- Cobranças de mensalidades em atraso constrangem a relação com o aluno/família
- Certificados e documentação de formação gerados manualmente
- Formação subsidiada: relatórios e documentação obrigatória para financiamento
**Funcionalidades mais relevantes:** inscrições online com confirmação automática, comunicação com pais por WhatsApp, cobranças automáticas com link de pagamento (MB Way), geração de certificados, relatórios de frequência.
**Linguagem de venda:** "os pais recebem updates do filho pelo WhatsApp, sem ligar para a recepção", "as inscrições chegam organizadas, não por telefone", "as mensalidades cobram-se sozinhas no dia certo".
**Canal de aquisição:** DGERT (entidade reguladora de formação), LinkedIn de directores pedagógicos, grupos Facebook de formadores, referência entre centros.
**Objecção principal:** "Temos sistema de gestão escolar." → Resposta: "O AcidaOS complementa — trata da comunicação e cobranças que o sistema escolar não faz."
**Trigger de compra:** período de matrículas com recepção sobrecarregada; mensalidade em atraso de mais de 3 meses por falta de follow-up.
**Pricing sweet spot:** €50-120/mês (sensíveis ao preço mas com ROI claro em cobranças recuperadas).
---
### Nicho 10 — Serviços Técnicos Especializados
**Quem:** Empresas de IT/informática, AVAC, electricistas com empresa, empresas de segurança e alarmes, canalizadores, empresas de manutenção de equipamentos.
**Dimensão PT:** dezenas de milhares de micro e pequenas empresas. Alta dependência de WhatsApp para comunicar com técnicos e clientes. Muito fragmentado.
**Dores operacionais:**
- Chamadas de avaria chegam fora de horas sem registo
- Orçamentos de intervenções demoram dias (técnico tem de ver primeiro)
- Scheduling de técnicos manual — conflitos de agenda e deslocações ineficientes
- Contrato de manutenção: clientes que deviam contactar para revisão e não contactam
- Relatório de intervenção escrito à mão ou por memória do técnico
**Funcionalidades mais relevantes:** triagem automática de avarias fora de horas (gravidade, urgência), agendamento de técnicos por disponibilidade, geração de relatório de intervenção por voz (técnico descreve verbalmente → relatório gerado), alertas de manutenção preventiva, facturação de serviço.
**Linguagem de venda:** "o técnico descreve o trabalho pelo WhatsApp e o relatório fica pronto", "as chamadas de avaria fora de horas ficam registadas e triadas", "o cliente de manutenção recebe o alerta de revisão no mês certo".
**Canal de aquisição:** associações sectoriais (ANEOP, ASIAM), LinkedIn de gestores de empresa técnica, grupos Facebook de técnicos, referência entre pares.
**Objecção principal:** "Os meus técnicos não usam computador." → Resposta: "Exactamente por isso — o AcidaOS funciona pelo WhatsApp que eles já usam. O relatório faz-se com uma nota de voz."
**Trigger de compra:** chamada de avaria urgente perdida fora de horas; técnico que sai e leva o registo das intervenções que fez.
**Pricing sweet spot:** €40-100/mês (dispostos a pagar pelo valor em tempo poupado e em trabalho não perdido).
---
## Tabela resumo — priorização por atractividade
| Nicho | Volume PT | Urgência da dor | Disposição a pagar | Canal de entrada | Score |
|-------|-----------|----------------|-------------------|-----------------|-------|
| Saúde Privada | Alta | Muito alta | Alta | Associações + Google | ⭐⭐⭐⭐⭐ |
| Imobiliárias | Média | Alta | Alta | LinkedIn + portais | ⭐⭐⭐⭐⭐ |
| Agências Digitais | Média | Alta | Muito alta | LinkedIn + eventos | ⭐⭐⭐⭐⭐ |
| E-commerce | Alta | Alta | Alta | Comunidades + parceiros | ⭐⭐⭐⭐ |
| Contabilidade | Alta | Média-alta | Média | Ordem OCC + formação | ⭐⭐⭐⭐ |
| Construção | Muito alta | Alta | Média | Referência + associações | ⭐⭐⭐⭐ |
| Comércio B2B | Alta | Alta | Média-alta | Feiras + LinkedIn | ⭐⭐⭐⭐ |
| Serviços Técnicos | Muito alta | Média | Média | Referência + grupos | ⭐⭐⭐ |
| Educação | Média | Média | Baixa-média | DGERT + referência | ⭐⭐⭐ |
| Restauração | Muito alta | Média | Baixa | AHRESP + Instagram | ⭐⭐⭐ |
**Top 3 para arranque:** Saúde Privada, Imobiliárias, Agências Digitais — dor alta, disposição a pagar alta, canais de entrada claros.
@@ -0,0 +1,113 @@
# Perguntas de Briefing — Entrevista Estratégica
Guia de entrevista estruturado para conduzir o briefing inicial com o cliente.
Adaptar ao sector e nível de maturidade da marca.
---
## Bloco 1 — O negócio
### Contexto actual
1. O que faz a sua empresa, em termos simples?
2. Há quantos anos está no mercado? Como surgiu?
3. Qual a dimensão actual: equipa, facturação, clientes?
4. Qual é o maior desafio que enfrenta hoje no negócio?
5. O que o distingue dos concorrentes? (resposta espontânea — não sugerir)
### Serviços e produtos
6. Quais são os seus produtos/serviços principais?
7. Qual gera mais receita? Qual tem mais potencial?
8. Existe algum produto que quer destacar mais? Porquê?
9. Que resultados concretos entregam aos clientes?
### Posicionamento actual
10. Se pedisse a um cliente para descrever a sua empresa em 3 palavras, o que diria?
11. Existe uma percepção de mercado que quer mudar?
12. Onde se posiciona em preço vs concorrência? (mais caro, igual, mais barato) Porquê?
---
## Bloco 2 — O cliente ideal
### Segmentação
13. Quem é o seu cliente ideal? Descreva-o em detalhe.
14. Tem mais do que um tipo de cliente? Como os diferencia?
15. Qual o cliente que mais valoriza o que fazem e paga melhor?
16. Existe algum cliente que não quer ter? Porquê?
### Comportamento de compra
17. Como é que os clientes chegam até si? (canal principal de aquisição)
18. Quanto tempo demora tipicamente desde o primeiro contacto até fechar negócio?
19. Quem toma a decisão de compra? É uma pessoa ou um grupo?
20. Que objecções ouve mais frequentemente antes de fechar?
### Relação com clientes
21. Qual foi o feedback mais positivo que recebeu de um cliente? (pedir citação exacta)
22. Qual foi a queixa mais comum? Como resolveram?
23. Tem clientes que recomendam espontaneamente? O que dizem?
---
## Bloco 3 — Mercado e concorrência
### Mercado
24. Em que mercado opera? Geográfico (local, nacional, internacional)?
25. O mercado está a crescer, estável ou a contrair?
26. Que tendência do mercado mais o preocupa? Qual mais o entusiasma?
27. Existe sazonalidade? Em que períodos?
### Concorrência
28. Quem são os 3 principais concorrentes?
29. Em que é que são melhores? Em que é que são piores?
30. Por que é que um cliente nos escolhe a nós vs ao concorrente X?
31. Existe algum concorrente que admira (mesmo que de outra área)?
---
## Bloco 4 — Visão e ambição
### Onde quer chegar
32. Qual é o objectivo da empresa a 3 anos?
33. O que precisa de mudar para chegar lá?
34. Existe um modelo de empresa que admira ou quer imitar? Porquê?
35. Se tivesse recursos ilimitados, o que faria primeiro?
### Marca e identidade
36. Que 3 adjectivos descrevem a personalidade ideal da marca?
37. Que marcas (de qualquer sector) admira pela comunicação? O que lhes agrada?
38. Existe uma história de origem da empresa que emociona? (fundador, momento de viragem)
39. Que valores são inegociáveis? O que nunca fariam por dinheiro?
### Tom de voz
40. A marca é mais formal ou informal? Mais técnica ou acessível?
41. Usa humor na comunicação? Em que contextos?
42. Existe linguagem/palavras que NÃO deve usar?
---
## Bloco 5 — Recursos e restrições
### Capacidade
43. Qual o budget mensal disponível para marketing?
44. Existe equipa interna de marketing ou será tudo externalizado?
45. Quem aprova conteúdos? Qual o processo de revisão?
### Prazo
46. Existe algum lançamento, evento ou data importante a curto prazo?
47. Quando precisa de ter a estratégia operacional?
### Material existente
48. Existe alguma estratégia anterior? O que funcionou? O que não funcionou?
49. Que activos existem: website, redes sociais, base de emails, testemunhos, cases?
50. Existem fotos/vídeos profissionais? Em que estado está a identidade visual?
---
## Notas de condução da entrevista
- Fazer max 15-20 perguntas numa sessão (60-90 min)
- Priorizar: Blocos 1, 2 e 4 na primeira sessão
- Blocos 3 e 5 podem ser preenchidos com pesquisa independente
- Pedir sempre exemplos concretos e citações textuais de clientes
- Quando a resposta é vaga, fazer "pode dar-me um exemplo específico?"
- Gravar a sessão (com autorização) para não perder citações úteis
@@ -0,0 +1,374 @@
# Template: Documento de Estratégia de Marca
Estrutura completa do documento entregável ao cliente. Baseado nos projectos SFV, LJM, MCT, Espiral Senior e Sintricare.
Adaptar secções ao sector e complexidade do cliente.
---
## Cabeçalho do documento
```
---
title: [Nome da Marca] — Estratégia de Marca
cliente: [Nome do cliente]
código: EST-MRK-010
versão: 1.0
data: [DD-MM-YYYY]
elaborado: Descomplicar® — Agência de Aceleração Digital
status: draft | aprovado
---
```
---
## DECLARAÇÃO DE IMPACTO
> **[Uma frase poderosa — 10-15 palavras máximo]**
> *A essência e o impacto da marca numa linha.*
---
## ÍNDICE
1. Apresentação e Fundamentos Estratégicos
2. Proposta de Valor Única
3. Missão, Visão, Valores e Objectivos
4. Apresentação Sumária da Empresa e Serviços
5. Segmentação e Análise Detalhada de Público
6. Pitch Canvas
7. Copywriting Estratégico
8. Estratégia de Comunicação e Canais
9. Investimentos Prioritários
10. Monitorização e KPIs
11. Inventário de Activos de Marketing
---
## 1. Apresentação e Fundamentos Estratégicos
### 1.1 Contexto actual
- **Mercado:** [Análise do mercado actual — dimensão, tendências, oportunidades]
- **Concorrência:** [Principais concorrentes e posições]
- **Desafios:** [Principais desafios enfrentados pela marca]
- **Oportunidades:** [Oportunidades identificadas]
### 1.2 Problema a resolver
[Identificação clara do problema de negócio que esta estratégia precisa resolver — qual é o problema central que impede o crescimento ou o impacto da marca?]
---
## 2. Proposta de Valor Única
### 2.1 O que nos torna únicos
[O que tornamos possível que os concorrentes não conseguem. Ser específico — evitar "qualidade e experiência".]
### 2.2 Diferenciais competitivos
1. [Diferencial 1 — explicar o mecanismo único que o cria]
2. [Diferencial 2]
3. [Diferencial 3]
### 2.3 Benefícios por camada
| Tipo | Benefícios |
|------|-----------|
| **Funcionais** | [O que o produto/serviço faz concretamente] |
| **Emocionais** | [Como o cliente se sente ao usar/contratar] |
| **Identitários** | [O que diz sobre o cliente escolher esta marca] |
---
## 3. Missão, Visão, Valores e Objectivos
### 3.1 Missão
> [O que fazemos, para quem e como — acção no presente. Max 2 frases.]
### 3.2 Visão
> [Onde queremos estar e que impacto queremos ter em 3-5 anos. Max 2 frases.]
### 3.3 Valores
- **[Valor 1]** — [Como se manifesta na prática, no dia-a-dia da empresa]
- **[Valor 2]** — [Como se manifesta]
- **[Valor 3]** — [Como se manifesta]
- **[Valor 4]** — [Como se manifesta] *(opcional)*
### 3.4 Objectivos estratégicos
- **Curto prazo (6m):** [2-3 objectivos mensuráveis]
- **Médio prazo (1 ano):** [2-3 objectivos]
- **Longo prazo (3 anos):** [Ambição de impacto]
---
## 4. Apresentação Sumária da Empresa e Serviços
### 4.1 Quem somos
[Parágrafo de apresentação — quem são, o que fazem, há quanto tempo, dimensão, missão em acção]
### 4.2 Serviços/Produtos principais
| Serviço/Produto | Descrição | Para quem | Resultado principal |
|----------------|-----------|-----------|-------------------|
| [Nome] | — | — | — |
| [Nome] | — | — | — |
### 4.3 Posicionamento
[Declaração de posicionamento — o lugar único que a marca ocupa na mente do cliente]
> "Para [público], somos a única [categoria] que [benefício único] porque [prova]."
---
## 5. Segmentação e Análise Detalhada de Público
*Repetir a estrutura completa dos 20 pontos para cada segmento identificado.*
---
### 5.X — [Nome do Segmento]
*[Breve descrição de quem é este segmento — 2 linhas]*
#### 1. Perfil Demográfico
[Idade, género, localização, rendimento, nível de educação, profissão, cargo, tipo/dimensão de empresa, estado civil, composição familiar — tudo o que é mensurável e verificável]
#### 2. Perfil Psicográfico
[Valores pessoais, crenças, atitude perante a vida, estilo de vida, motivações profundas, relação com a categoria de produto/serviço, identidade social — o que não se mede mas define quem são]
#### 3. Dores
[Problemas activos e urgentes que precisam resolver. O que os está a prejudicar agora. Dores específicas do dia-a-dia relacionadas com o que a marca resolve.]
#### 4. Anseios
[O que aspiram a ser, ter ou alcançar. Sonhos profissionais e pessoais. A versão ideal do futuro que imaginam.]
#### 5. Desejos
[O que querem concretamente — mais imediato e específico que os anseios. Desejos práticos relacionados com a nossa oferta.]
#### 6. Frustrações
[O que já tentaram fazer ou comprar sem resultado. Soluções que prometeram e não entregaram. O cansaço acumulado de não resolver o problema.]
#### 7. Preocupações
[O que os inquieta a médio/longo prazo. Cenários negativos que imaginam. Preocupações sistémicas relacionadas com a sua vida ou negócio.]
#### 8. Medos
[Medos concretos associados à compra ou à não-compra. Medo de errar, de ser enganado, de perder dinheiro, de ser julgado. O que os paralisa antes de decidir.]
#### 9. Inimigos
[Os "vilões" da história deste segmento — concorrentes que os desiludiram, sistemas que os prejudicam, tendências que os ameaçam, pessoas ou entidades a quem culpam o problema]
#### 10. Linguagem
[As palavras e expressões exactas que usam para descrever o problema, a solução e os resultados. Jargão do sector. O que dizem aos amigos. O que escrevem no Google. Evitar linguagem que usamos internamente mas eles não usam.]
#### 11. Como procuram ajuda, informação ou dicas?
[Onde vão quando têm o problema: Google (que pesquisas fazem?), YouTube, grupos Facebook, LinkedIn, amigos, consultores, feiras, etc. Que tipo de conteúdo consomem para se informar?]
#### 12. Canais digitais
[Em que plataformas estão activos: Facebook, Instagram, LinkedIn, TikTok, YouTube, email, WhatsApp, fóruns, etc. Com que frequência? Em que contexto (trabalho vs lazer)?]
#### 13. Estilo de Decisão
[Como tomam decisões de compra: rápido vs deliberado, emocional vs racional, individual vs colectivo, impulsivo vs comparativo. Que factores pesam mais? Precisam de aprovação de terceiros?]
#### 14. Mudanças
[Mudanças que sabem e sentem necessárias nas suas vidas ou negócio. Passos que sabem que precisam dar mas ainda não deram. A consciência que já têm do problema.]
#### 15. Resistência à Mudança
[De que maneira resistem à mudança? Que desculpas usam para adiar? Como os podemos ajudar a ultrapassar essa resistência? Que argumentos reduzem o atrito?]
#### 16. Objecções Típicas
[As objecções mais frequentes às ofertas comerciais desta categoria. Como as podemos antecipar e superar? Respostas específicas a cada objecção.]
| Objecção | Como ultrapassar |
|----------|----------------|
| — | — |
| — | — |
| — | — |
#### 17. Forma de Gerar Emoção
[Que tipo de conteúdo, história ou mensagem os move emocionalmente? O que os faz parar no scroll? O que os faz partilhar? Qual o gatilho emocional mais poderoso para este segmento?]
#### 18. Argumentos
[A que argumentos são mais sensíveis? Como os podemos persuadir a agir? Que tipo de prova precisam: dados, testemunhos, demonstrações, garantias? Qual a sequência de persuasão ideal?]
#### 19. Concorrentes
[Que outras entidades lhes oferecem o mesmo tipo de serviço ou solução alternativa? Como se comparam a nós em percepção de valor?]
#### 20. Propostas Recusadas
[Que propostas é que este segmento tem recusado e porquê? O que dizem explicitamente e o que dizem implicitamente? O que não querem mais ouvir?]
---
## 6. Pitch Canvas
### 6.1 O que é o Pitch Canvas?
O Pitch Canvas é uma ferramenta de comunicação estratégica que resume, numa única estrutura visual, o essencial da proposta de valor da empresa. É útil porque:
- Força clareza e síntese (não há espaço para vagueza)
- Alinha toda a equipa na mesma mensagem
- Serve de base para qualquer peça de comunicação
- Torna a proposta de valor testável e iterável
### 6.2 Utilidade específica para [Nome da Marca]
[Como o Pitch Canvas pode ajudar esta marca concretamente — que clareza traz, que conversas simplifica, onde pode ser usado]
### 6.3 Os 5 elementos do Pitch Canvas
**Para quem:**
> [Segmento principal — quem são e qual o problema específico]
**O problema:**
> [Dor principal, urgente e real — formulada na linguagem do cliente]
**A solução:**
> [O que oferecemos — mecanismo único de resolução]
**O resultado:**
> [Transformação concreta — antes vs depois, com métrica se possível]
**Por que nós:**
> [Razão para acreditar — o que nos torna credíveis e únicos]
### 6.4 Declaração de mudança no mundo
> **"[Nome da Marca] está a mudar [o quê] para [quem], através de [como], tornando possível [impacto maior]."**
---
## 7. Copywriting Estratégico
### 7.1 Questionamento estratégico
**Qual é o objectivo da comunicação?**
[Definir claramente o que queremos que o público faça, sinta ou pense após cada comunicação. Sem objectivo claro não há comunicação eficaz.]
**Que transformação prometemos?**
[A transformação específica que a marca entrega — não o produto, mas a mudança de estado do cliente]
### 7.2 Pain + Gain (Problema e Resultado)
> **Pain:** [O problema central na perspectiva do cliente — formulado com a dor, não com o produto]
> **Gain:** [O resultado desejado — formulado com o benefício, não com a funcionalidade]
*Revisão com questões específicas do sector:*
> **Pain refinado:** [Após aprofundar com o briefing — mais específico, com linguagem do cliente]
> **Gain refinado:** [Com métricas ou resultados concretos já entregues a outros clientes]
### 7.3 Narrativa por segmento
*Fórmula: Problema (dor do público) → Solução (serviços da empresa) → Resultado (benefícios concretos)*
**[Segmento A]:**
> **Problema:** [Dor específica e urgente deste segmento, na sua linguagem]
> **Solução:** [Como a marca resolve de forma única — mecanismo específico]
> **Resultado:** [Benefício tangível e mensurável + prova social ou garantia]
**[Segmento B]:**
> **Problema:** [...]
> **Solução:** [...]
> **Resultado:** [...]
*(Repetir para cada segmento)*
### 7.4 Mensagem central da marca
> **"[A frase que todos os colaboradores sabem de cor — resumo da proposta de valor em 10 palavras]"**
### 7.5 Headlines por segmento
| Segmento | Headline principal | Headline secundária |
|----------|------------------|-------------------|
| [Seg. A] | — | — |
| [Seg. B] | — | — |
---
## 8. Demonstração dos Serviços
### 8.1 Como demonstrar [serviço/produto principal]
**Preparação personalizada:**
[O que preparar antes da demonstração para cada segmento]
**Introdução interactiva:**
[Como começar — conectar com a dor antes de mostrar a solução]
**Demonstração ao vivo:**
[O que mostrar, em que ordem, com que foco]
**Casos de uso:**
[Exemplos reais de clientes similares — antes/depois]
**Q&A:**
[Perguntas frequentes na demonstração e respostas modelo]
**Follow-up:**
[Próximo passo após a demonstração — o que enviar, quando contactar]
---
## 9. Investimentos Prioritários
### 9.1 Prioridades imediatas (impacto/esforço)
| Prioridade | Investimento | Impacto esperado | Prazo | Custo estimado |
|-----------|-------------|-----------------|-------|---------------|
| 1 | [Ex: Website + SEO] | — | 30-60d | — |
| 2 | [Ex: Google Ads] | — | 30d | — |
| 3 | [Ex: Email marketing] | — | 60d | — |
### 9.2 Estratégia de canais
| Canal | Objectivo | Frequência | KPI | Budget mensal |
|-------|-----------|-----------|-----|--------------|
| Website | — | — | — | — |
| Google Ads | — | — | — | — |
| Meta Ads | — | — | — | — |
| LinkedIn | — | — | — | — |
| Email | — | — | — | — |
| WhatsApp | — | — | — | — |
### 9.3 Pilares de conteúdo
1. [Pilar 1 — tema + tipos de conteúdo + frequência]
2. [Pilar 2]
3. [Pilar 3]
---
## 10. Monitorização e KPIs
### 10.1 Dashboard de métricas
| Área | KPI | Baseline | Meta 3m | Meta 6m | Meta 12m |
|------|-----|---------|---------|---------|----------|
| Brand | Notoriedade espontânea | — | — | — | — |
| Tráfego | Visitas/mês | — | — | — | — |
| Leads | Leads qualificados/mês | — | — | — | — |
| Conversão | Taxa de fecho | — | — | — | — |
| Retenção | NPS | — | — | — | — |
### 10.2 Ciclo de optimização
- **Revisão mensal:** métricas de canal, ajuste de conteúdo
- **Revisão trimestral:** avaliação de ROI, ajuste de orçamento
- **Revisão anual:** actualização estratégica completa
---
## 11. Inventário de Activos de Marketing
| Activo | Localização | Estado actual | Prioridade |
|--------|------------|--------------|-----------|
| Website | [URL] | — | — |
| Blog/Artigos | — | — | — |
| Redes sociais | — | — | — |
| Base de emails | — | — | — |
| Testemunhos/Cases | — | — | — |
| Materiais impressos | — | — | — |
| Apresentações | — | — | — |
| Fotos/Vídeos profissionais | — | — | — |
---
## Notas de implementação
1. **Sessão de alinhamento:** Apresentar o documento à equipa antes de implementar
2. **Validação:** Partilhar narrativas com 2-3 clientes actuais antes de publicar
3. **Implementação faseada:** Começar pelos canais de maior impacto e menor esforço
4. **Suporte:** WhatsApp durante 1 mês para dúvidas de implementação (EST-MRK-010)
---
*Elaborado por Descomplicar® — Agência de Aceleração Digital*
*emanuel@descomplicar.pt | descomplicar.pt*
+43 -12
View File
@@ -1,6 +1,6 @@
---
name: expense
description: Gestao de despesas Desk CRM com PDF obrigatorio. Registar, categorizar e analisar despesas com verificacao de duplicados, upload SFTP e arquivo mensal automatico.
description: Gestao de despesas Desk CRM com PDF obrigatorio. Registar, categorizar e analisar despesas com verificacao de duplicados por reference_no, upload SFTP e arquivo mensal automatico.
---
# /expense - Gestao de Despesas
@@ -55,18 +55,27 @@ Para mapeamento completo de fornecedores, emails e padroes PDF para categorias:
- Bypass valido apenas para: AT, Salarios, transferencias bancarias
2. LER O PDF: Extrair dados reais do documento
- NUNCA copiar valor de um PDF para outro
- EXTRAIR reference_no (numero factura) — OBRIGATORIO para dedup
3. OBRIGATORIO: get_expense_categories(with_stats=true)
4. Identificar categoria correcta na lista
5. VERIFICAR DUPLICADOS:
5. VERIFICAR DUPLICADOS (3 camadas — OBRIGATORIO):
Camada 0 — Referencia de factura (PRIMARIA):
- get_expenses(search: "<reference_no>")
- Se alguma despesa tem reference_no IGUAL → DUPLICADO → PARAR
Camada 1 — Fornecedor + Valor + Data:
- get_expenses(search: "<fornecedor>")
- Mesmo fornecedor + valor + data = duplicado
- Mesmo numero factura = duplicado
- Mesmo fornecedor + valor (±0.05) + data (±3 dias) = duplicado
Camada 2 — Expense name:
- get_expenses(search: "<fornecedor> - <reference_no>")
- Se match exacto → duplicado
Se QUALQUER camada detecta duplicado → NAO criar, informar utilizador
6. Recolher dados:
- category_id, amount, currency (EUR=3, USD=2), date (YYYY-MM-DD)
- reference_no (numero factura — OBRIGATORIO)
- note (incluir numero factura), send_invoice_to_customer = 0
- Opcionais: client_id, project_id, billable, tax
7. CONFIRMAR com utilizador (mostrar resumo)
8. create_expense
8. create_expense (INCLUIR reference_no no payload)
9. UPLOAD PDF ao Desk via SFTP:
a. mkdir -p no servidor: /home/ealmeida/desk.descomplicar.pt/uploads/expenses/<id>
b. mcp__ssh-unified__sftp_upload(server:"desk", local_path, remote_path)
@@ -104,7 +113,7 @@ Para mapeamento completo de fornecedores, emails e padroes PDF para categorias:
Para protocolo completo de processamento de tickets de contabilidade: ver `references/ticket-processing.md`
**Resumo:** Obter ticket -> verificar anexos -> verificar duplicados -> extrair dados -> confirmar -> criar despesa -> upload PDF -> arquivo mensal.
**Resumo:** Obter ticket -> verificar anexos -> verificar duplicados (3 camadas) -> extrair dados -> confirmar -> criar despesa -> upload PDF -> arquivo mensal.
---
@@ -136,15 +145,16 @@ Para protocolo completo de processamento de tickets de contabilidade: ver `refer
**Despesas:**
4. Criar despesa sem category_id
5. Nao validar data (formato YYYY-MM-DD)
6. Criar despesa sem verificar duplicados primeiro
6. Criar despesa sem verificar duplicados primeiro (3 camadas obrigatorias)
7. Criar despesa sem reference_no (chave primaria de dedup)
**Valores de PDFs:**
7. Assumir que ficheiros com nomes semelhantes tem o mesmo valor
8. SEMPRE ler CADA PDF individualmente para extrair o valor real
8. Assumir que ficheiros com nomes semelhantes tem o mesmo valor
9. SEMPRE ler CADA PDF individualmente para extrair o valor real
**Tickets:**
9. Processar ticket sem verificar anexos PDF
10. Assumir que ticket com recibo = despesa nao lancada
10. Processar ticket sem verificar anexos PDF
11. Assumir que ticket com recibo = despesa nao lancada
---
@@ -152,8 +162,11 @@ Para protocolo completo de processamento de tickets de contabilidade: ver `refer
- [ ] Listar categorias existentes
- [ ] Validar categoria correcta
- [ ] Extrair reference_no do PDF/factura
- [ ] Verificar duplicados (3 camadas)
- [ ] Confirmar dados com utilizador
- [ ] Usar formato data YYYY-MM-DD
- [ ] Incluir reference_no no create_expense
- [ ] Incluir nota descritiva
---
@@ -164,6 +177,24 @@ Para protocolo completo de processamento de tickets de contabilidade: ver `refer
- `references/ticket-processing.md` - Protocolo completo de processamento de tickets
- `references/changelog.md` - Historico de alteracoes
---
**Criado:** 2026-02-05 | **Actualizado:** 2026-02-12
## Self-Healing
Antes de executar, ler `~/.claude-work/healing/expense.jsonl` (se existir). Cada linha é um padrão de erro conhecido:
```json
{"date":"YYYY-MM-DD","issue":"descrição do problema","fix":"como evitar","source":"user|auto"}
```
Se encontrares um padrão relevante ao contexto actual, aplica o fix preventivamente. Após cada erro ou correcção do utilizador nesta skill, **adicionar nova linha** ao healing log com o padrão aprendido.
---
**Criado:** 2026-02-05 | **Actualizado:** 2026-03-30 | Fix: dedup 3 camadas com reference_no (DES-137)
## Healing Log
<!-- Registo automático de erros e correcções nesta skill -->
+12
View File
@@ -253,3 +253,15 @@ Acções:
---
*Skill v1.0.0 | 2026-02-05 | Descomplicar®*
---
## 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.*
+150
View File
@@ -0,0 +1,150 @@
---
name: orcamento
description: Criação de orçamentos Descomplicar baseados nos itens oficiais do Desk CRM. Versão light para heartbeats.
disable-model-invocation: true
---
# Orçamento — Referência Rápida
## Fonte de verdade: Desk CRM (`tblitems` + `tblitems_groups`)
651 itens em 14 grupos. Consultar SEMPRE o CRM para preços actualizados.
## Sintaxe
```
/orcamento [cliente] [tipo] [-MEN|-TRI]
```
| Código | Tipo | Grupo CRM |
|--------|------|-----------|
| `starter` | StarterWP | Websites |
| `corporate` | CorporateWP | Websites |
| `care` | CareWP | Websites |
| `ecom` | eCommerceWP | Websites |
| `mkt` | Marketing 360 | Marketing |
| `man` | Manutenção | Suporte |
| `deskcrm` | DeskCRM | DeskCRM |
| `chatbot` | Chatbot | Chatbots |
| `acceleratorx` | AcceleratorX | Tecnologia |
## Variantes de facturação
| Flag | Unit | Pesquisa CRM |
|------|------|-------------|
| (nenhum) | ano | Item base |
| `-MEN` | mensalidade | `WHERE description LIKE 'Mensalidade%...'` |
| `-TRI` | trimestral | `WHERE description LIKE 'Trimestral%...'` |
Preços das variantes são definidos no CRM (podem incluir markup). Nunca calcular por divisão simples.
## Protocolo
### 1. Identificar cliente
```
mcp__desk-crm-v3__search_customers query="[nome]" fields="company,vat"
```
### 2. Consultar preços
```bash
# Itens base (setup/pontuais)
mysql -u root ealmeida_desk24 -e "
SELECT description, rate, unit FROM tblitems
WHERE group_id = [GROUP_ID]
AND description LIKE '%[PACOTE]%'
AND unit NOT IN ('mensalidade','trimestral','anuidade')
ORDER BY description;"
# Itens recorrentes (com variante)
mysql -u root ealmeida_desk24 -e "
SELECT description, rate, unit FROM tblitems
WHERE group_id = [GROUP_ID]
AND description LIKE '[Mensalidade|Trimestral]%[PACOTE]%'
ORDER BY description;"
```
Ou via MCP:
```
mcp__desk-crm-v3__price_management action="get_pricing_insights" params={"group": "[GRUPO]"}
```
### 3. Criar estimate
```
mcp__desk-crm-v3__create_estimate
client_id=[id]
date=[hoje]
expiry_date=[hoje + 30 dias]
items=[{description, qty, rate, unit}]
terms="[termos]"
```
**Formato item:** `{"description": "...", "qty": 1, "rate": 700, "unit": "un"}`
**Unidades:** `un` (pontual), `mensalidade` (-MEN), `trimestral` (-TRI), `anuidade` (defeito)
### 4. Termos por variante
- **Sem flag:** "50% na adjudicação + 50% na entrega"
- **-MEN:** "Setup: 50%+50% | Recorrência: facturação mensal antecipada"
- **-TRI:** "Setup: 50%+50% | Recorrência: facturação trimestral antecipada"
## Preços de referência (consultar CRM para valores reais)
### Websites
| Produto | Setup | Anuidade |
|---------|-------|----------|
| StarterWP | 700 | 250 |
| CorporateWP | 900 | 299 |
| eCommerceWP | 1100 | 349 |
| CareWP | 1300 | 350 |
### DeskCRM
| Produto | Anuidade |
|---------|----------|
| Starter | 400 |
| Profissional | 800 |
| Avançado | 1500 |
| Enterprise | 3000 |
### AcceleratorX
| Produto | Setup |
|---------|-------|
| WP ProCMS | 650 |
| e-Commerce | 750 |
| Care | 750 |
| School Manager | 850 |
### Chatbots
| Produto | Setup |
|---------|-------|
| Básico | 350 |
| Avançado | 850 |
## Checklist
- [ ] Cliente identificado/criado no CRM
- [ ] Tipo seleccionado
- [ ] Preços consultados no CRM
- [ ] Valores calculados (subtotal + IVA 23%)
- [ ] Recorrência calculada
- [ ] Estimate criado (status: Draft)
- [ ] Resumo apresentado
## MCPs
```
mcp__desk-crm-v3__search_customers
mcp__desk-crm-v3__create_customer
mcp__desk-crm-v3__create_estimate
mcp__desk-crm-v3__price_management
```
---
**Versão**: 4.1.0-light | **Base**: 4.1.0
+12
View File
@@ -512,3 +512,15 @@ INSERT INTO tblskill_agent_metrics (
---
**Versao**: 4.1.0 | **Data**: 2026-03-12 | **Fonte de Verdade**: Desk CRM (tblitems)
---
## 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.*
+49
View File
@@ -365,3 +365,52 @@ mcp__mcp-time__current_time - Data/hora actual
---
**Versao**: 1.0.0 | **Data**: 2026-03-06 | **Template**: descomplicar-proposal-template.pptx
---
## Media Bank (D7-MB-001)
**Quando consultar:** antes de gerar o deck da proposta — para hero da capa, backgrounds de slides de secção e imagens ilustrativas. Garante consistência visual e evita dependência de geração IA por cada proposta.
**Workflow tentativa-primeiro:**
1. Pesquisar via MCP `media-bank`:
```
mcp__media-bank__search_media(
query="<sector/serviço do cliente em EN>",
type="image",
tema="<um dos 9 temas alinhado com serviço>",
orientation="landscape",
min_quality=8, # exigência mais alta para propostas
min_width=1920,
exclude_used_in_last_days=60,
limit=5
)
```
2. Avaliar candidatos por `description_en` + `quality_score` + alinhamento com identidade visual Descomplicar.
3. Se ≥1 adequado → usar `path_local` directamente no PPTX (slide master / capa) ou compor no template.
4. Se nenhum → fallback para geração IA (Flux) ou biblioteca de stock interna.
5. Marcar uso: `mcp__media-bank__mark_used(asset_id, {type:"proposal-deck", ref:"<cliente>-<data>", date:"<YYYY-MM-DD>"})`.
**Fallback REST** (se MCP indisponível):
```bash
SK=$(grep SERVICE_KEY /media/ealmeida/Dados/Hub/05-Projectos/Banco-Imagens-Videos/scripts/.env | cut -d= -f2)
curl -s "https://mem.descomplicar.pt/rest/v1/media_bank_assets?type=eq.image&orientation=eq.landscape&quality_score=gte.8&deleted_at=is.null&order=quality_score.desc&limit=5" \
-H "apikey: $SK" -H "Authorization: Bearer $SK"
```
**Regra inviolável:** matéria-prima local. Usar como input no template PPTX — NUNCA servir o ficheiro raw ao cliente sem integração no deck (overlays, branding, layout).
Ver `Hub/06-Operacoes/Procedimentos/D7-Tecnologia/MCP/PROC-Media-Bank.md` (D7-MB-001) 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.*
+386
View File
@@ -0,0 +1,386 @@
---
name: proposta-visual
description: Criação completa de propostas comerciais visuais — página web (propostas.descomplicar.pt) + PDF exportável + PPTX editável. Recolhe dados CRM, gera JSON, renderiza condicionalmente e faz deploy.
---
# Skill /proposta-visual — Propostas Comerciais Visuais
Cria propostas comerciais profissionais com 3 outputs: página web interactiva, PDF exportável e PPTX editável.
## Triggers
- `/proposta-visual`
- "proposta visual", "proposta web", "criar proposta", "nova proposta", "proposta para [cliente]"
## Quando usar
- Criar proposta comercial completa para um cliente
- Gerar página web + PDF + PPTX de uma proposta
- Actualizar proposta existente com novos dados
## Quando NÃO usar
- Apenas orçamento sem visual (usar `/orcamento`)
- Apenas PPTX sem página web (usar `/proposal-deck`)
- Análise de lead sem proposta (usar `/lead-approach`)
---
## Projecto base
| Campo | Valor |
|-------|-------|
| **Código fonte** | `/media/ealmeida/Dados/Dev/Propostas/` |
| **Stack** | React 18 + Vite + Tailwind + @react-pdf/renderer + Recharts + Framer Motion + Lucide React |
| **Live** | `propostas.descomplicar.pt/{slug}` |
| **Deploy** | Docker Swarm EasyPanel, serviço `descomplicar_propostas`, ficheiros `/opt/propostas/` |
| **DNS** | `propostas.descomplicar.pt` → 5.9.90.70 (Cloudflare proxied) |
| **Template PPTX** | `/media/ealmeida/Dados/Hub/90-Templates/Comercial/descomplicar-proposal-template.pptx` |
---
## REGRAS CRÍTICAS (ler antes de qualquer implementação)
### 1. PT-PT obrigatório — acentos em TODO o texto
Todos os textos no JSON, componentes web e componentes PDF DEVEM ter acentos PT-PT correctos:
- ✓ migração, tradução, integração, opções, condições, execução, acção
- ✗ migracao, traducao, integracao, opcoes, condicoes, execucao, accao
**Verificar no PDF:** labels hardcoded em `PDFWorkDone.jsx` e `PDFDocument.jsx` — já corrigidos mas confirmar sempre.
### 2. JSON data-driven — renderização condicional obrigatória
O `ProposalView.jsx` e o `PDFDocument.jsx` renderizam secções **condicionalmente** com base nos dados. Se um campo é `null`, `[]` ou não existe, a secção NÃO aparece.
**Regra:** NUNCA assumir que todos os campos existem. Cada proposta pode ter um subconjunto diferente de secções.
| Campo JSON | Secção web | Secção PDF | Condição |
|-----------|-----------|-----------|----------|
| `context.brandStrategy` | BrandStrategy | PageBrandStrategy | `!= null` |
| `salesData` | SalesChart | PageSales | `.length > 0` |
| `context.diagnosis` | Context | — | `.length > 0` |
| `context.scores` | ScoreGrid | PDFScores | `.length > 0` |
| `service360` | Service360 | PageService360 | `!= null` |
| `plans` | PricingCards | PDFPricing | `.length > 0` |
| `licenses` | LicensePack | PageLicenses | `!= null` |
| `workDone` | WorkDone | PDFWorkDone | `.length > 0` |
| `roadmap` | Roadmap | PDFWorkDone | `.length > 0` |
| `conditions` | Conditions | PDFWorkDone (pág. separada) | `.length > 0` |
### 3. Título dinâmico — campo `title` no JSON
O título da proposta (Hero web + capa PDF) vem do campo `title` no JSON:
- Proposta 360°: `"title": "Descomplicar 360°"`
- Migração técnica: `"title": "Migração Bookeo"`
- Website: `"title": "Website Profissional"`
- Fallback: `"Proposta Comercial"`
**NUNCA** hardcodar "Descomplicar 360°" — usar `data.title`.
### 4. Preços flexíveis — não assumir mensalidades
Os planos suportam dois formatos de preço:
**Mensalidade (avença):**
```json
{
"monthly": 459,
"hours": 8,
"originalPrice": 540,
"discount": 15
}
```
Mostra: "459 €/mês" + "8h/mês incluídas · contrato anual"
**Preço único (investimento):**
```json
{
"price": 750,
"priceLabel": "EUR + IVA",
"priceSubtitle": "Investimento único · prazo 1-2 semanas",
"monthly": null,
"hours": null
}
```
Mostra: "750 EUR + IVA" + "Investimento único · prazo 1-2 semanas"
**Campos usados:** `plan.price ?? plan.monthly` para o valor, `plan.priceLabel ?? "€/mês"` para a unidade, `plan.priceSubtitle` para a descrição abaixo.
### 5. react-pdf — bugs conhecidos e PROIBIÇÕES
| Proibição | Porquê | Alternativa |
|-----------|--------|-------------|
| `gap` + `flexWrap` juntos | Crasha silenciosamente | `marginRight` + `marginBottom` nos items |
| `borderColor` com `rgba()` | Renderiza verde | Cor sólida (ex: `#D4A020`, `#E8E8E8`) |
| Import de componentes SVG (`<Svg>`, `<Circle>`) | Crasha web worker do PDFDownloadLink | Implementar gráficos inline com `<View>` |
| `Font.register` com fontes locais/CDN em multi-página | Falha silenciosa | Usar Helvetica/Helvetica-Bold (built-in) |
| `href` vazio no PDFDownloadLink | PDF não gerou — verificar consola | Cache do browser — Ctrl+Shift+R |
### 6. Página 360° (service360) — contextualizar
A secção service360 no PDF usa o label "O QUE PROPOMOS" (genérico) e o título "As nossas soluções para o seu negócio". Os dados vêm do JSON `service360.areas[]`.
Para propostas que NÃO são 360°, adaptar os `areas` ao contexto:
- Migração técnica: features da migração
- Website: áreas do serviço web
- SEO: pilares do trabalho SEO
Se `service360` for `null`, a secção não aparece.
### 7. Condições comerciais — página separada no PDF
As condições estão numa página PDF separada (não na mesma que o roadmap) para evitar corte entre páginas. O componente `PDFWorkDone` retorna um Fragment com 2 Pages.
---
## Protocolo
### Sintaxe
```
/proposta-visual [cliente] [tipo-serviço]
```
### Fase 1: Análise do contexto
**ANTES de criar o JSON, responder a estas perguntas:**
1. **Que tipo de proposta é?** (360°, website, migração técnica, SEO, eCommerce, outro)
2. **O preço é mensal ou único?** → define `monthly` vs `price`/`priceLabel`/`priceSubtitle`
3. **Que secções se aplicam?** → define que campos preencher no JSON
4. **Há dados quantitativos?** (vendas, scores SEO, KPIs) → define `salesData`, `context.scores`
5. **Há trabalho já realizado?** → define `workDone`
6. **Quantas opções de preço?** → define `plans[]`
**Mapa de secções por tipo de proposta:**
| Secção | 360° | Website | Migração | SEO | eCommerce |
|--------|:----:|:-------:|:--------:|:---:|:---------:|
| `title` | Descomplicar 360° | Website Profissional | [contexto] | Optimização SEO | Loja Online |
| `brandStrategy` | ✓ | Opcional | — | — | Opcional |
| `salesData` | Se existir | — | — | — | Se existir |
| `scores` | ✓ (audit) | Opcional | — | ✓ (audit) | Opcional |
| `service360` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `plans` | ✓ (3 opções) | ✓ | ✓ | ✓ | ✓ |
| `licenses` | Se aplicável | — | — | — | Se aplicável |
| `workDone` | Se existir | Se existir | ✓ | Se existir | Se existir |
| `roadmap` | ✓ | ✓ | ✓ | ✓ | ✓ |
| `conditions` | ✓ | ✓ | ✓ | ✓ | ✓ |
### Fase 2: Recolha de dados do CRM
```
mcp__desk-crm-v3__search_customers query="[nome]"
mcp__desk-crm-v3__get_customer customer_id=[id]
mcp__desk-crm-v3__get_estimates client_id=[id]
```
### Fase 3: Criar ficheiro JSON
**Localização:** `src/data/[slug].json`
**Gerar slug:** iniciais do cliente + tipo + hash curto. Ex: `ccv-bookeo-a3f7c1d2`
**Schema mínimo obrigatório:**
```json
{
"title": "Título da Proposta",
"client": {
"name": "Nome Legal Lda.",
"brand": "Nome Comercial",
"website": "exemplo.pt",
"contact": "Nome Contacto",
"email": "email@exemplo.pt",
"phone": "+351 900 000 000"
},
"company": {
"name": "Descomplicar, Lda.",
"brand": "Descomplicar",
"nif": "514 785 691",
"email": "info@descomplicar.pt",
"phone": "911 510 005",
"website": "descomplicar.pt"
},
"date": "2026-03-23",
"validDays": 30,
"context": {
"description": "Descrição da situação...",
"diagnosis": [],
"scores": [],
"brandStrategy": null
},
"service360": null,
"plans": [],
"licenses": null,
"workDone": [],
"roadmap": [],
"conditions": [],
"salesData": [],
"salesProjection": []
}
```
**Campos opcionais para planos com preço único:**
```json
{
"price": 750,
"priceLabel": "EUR + IVA",
"priceSubtitle": "Investimento único · prazo 1-2 semanas",
"monthly": null,
"hours": null
}
```
**Checklist PT-PT antes de guardar o JSON:**
- [ ] Todos os textos têm acentos correctos (ã, ç, ã, é, ê, í, ó, õ, ú)
- [ ] Zero brasileirismos
- [ ] Caractere → (seta) em vez de -> nos textos visíveis
- [ ] Monetário: "EUR" ou "€" (não "R$" nem "$")
### Fase 4: Registar no App.jsx
```jsx
import novaData from "./data/[slug].json"
const proposals = {
// existentes...
"[novo-slug]": novaData,
}
```
### Fase 5: Verificar antes do build
**Checklist pré-build:**
- [ ] JSON válido (sem trailing commas, sem campos undefined)
- [ ] Campos null/[] para secções que não se aplicam (NÃO omitir)
- [ ] `title` definido (não depender do fallback)
- [ ] `plans[].price` OU `plans[].monthly` definido (não ambos null)
- [ ] `plans[].priceLabel` definido se preço único
- [ ] Slug registado em App.jsx
- [ ] Nenhum `flexWrap` + `gap` nos componentes PDF
- [ ] Nenhum `borderColor` com `rgba()` nos componentes PDF
### Fase 6: Build e deploy
```bash
cd /media/ealmeida/Dados/Dev/Propostas
npm run build
# Limpar dist
cd dist
rm -rf assets/template-media assets/template-referencia.pptx assets/slide-referencia.svg
cd assets/brochura && ls *.{jpg,png} 2>/dev/null | grep -v image8.jpg | xargs rm -f 2>/dev/null
# Empacotar
cd /media/ealmeida/Dados/Dev/Propostas/dist
tar czf /tmp/propostas-dist.tar.gz .
# Upload + deploy
mcp__ssh-unified__sftp_upload server=easy localPath=/tmp/propostas-dist.tar.gz remotePath=/tmp/propostas-dist.tar.gz overwrite=true
mcp__ssh-unified__ssh_execute server=easy command="cd /opt/propostas && rm -rf assets/* index.html; tar xzf /tmp/propostas-dist.tar.gz && docker service update --force descomplicar_propostas && rm -f /tmp/propostas-dist.tar.gz"
# Verificar
curl -sI https://propostas.descomplicar.pt/[slug] | head -3
# Deve retornar HTTP/2 200
# Limpar
rm -f /tmp/propostas-dist.tar.gz
```
### Fase 7: Testar PDF
**OBRIGATÓRIO antes de entregar:**
1. Abrir `https://propostas.descomplicar.pt/[slug]` com Ctrl+Shift+R
2. Clicar "Exportar PDF"
3. Verificar que `href` do link não está vazio (PDF gerou)
4. Abrir PDF e verificar:
- [ ] Título correcto (não "Descomplicar 360°" hardcoded)
- [ ] Preços correctos (não "€/mês" se é preço único)
- [ ] Sem borders verdes (rgba renderiza verde no react-pdf)
- [ ] Sem secções que não se aplicam (360°, vendas, licenças, scores)
- [ ] Acentos PT-PT em todo o texto
- [ ] Condições comerciais numa página inteira (sem corte)
- [ ] Todas as 3 opções de preço com layout uniforme
**Se o PDF não gera (href vazio):**
1. Verificar consola do browser (F12)
2. Causa mais provável: import de componente SVG dos infographics
3. Verificar que PDFDocument não importa de `./infographics/`
4. Verificar que não há `gap` + `flexWrap` no PDF
5. Ctrl+Shift+R e tentar novamente (cache)
### Fase 8: Entrega e registo
1. Guardar em `Hub/03-Propostas/[Cliente]/`
2. Registar estimate no CRM (se não existe)
3. Comunicar URL ao utilizador
4. Comentar tarefa CRM
---
## Design system ACIDA 2.0
| Token | Valor |
|-------|-------|
| Dourado | #C88900 |
| Dourado claro | #EED59F |
| Dourado border PDF | #D4A020 (usar em vez de rgba no PDF) |
| Dark | #262626 |
| Background | #F8F8F8 |
| Fonte web | Inter (Google Fonts) |
| Fonte PDF | Helvetica / Helvetica-Bold |
| Logo escuro | `/assets/logo-descomplicar.png` |
| Logo claro | `/assets/logo-descomplicar-white.png` |
---
## Propostas existentes
| Slug | Cliente | Tipo | Data |
|------|---------|------|------|
| `ljm-360-61a8aecc` | A Loja da Maria | 360° (mensal) | 2026-03-20 |
| `ccv-bookeo-a3f7c1d2` | Carvoeiro Caves | Migração técnica (único) | 2026-03-23 |
---
## Skills relacionadas
- `/proposal-deck` — PPTX standalone (16 layouts, XML editing)
- `/orcamento` — Estimate no CRM (sem visual)
- `/lead-approach` — Estratégia de abordagem de lead
- `/crm` — Operações CRM genéricas
---
## Changelog
### v2.0.0 (2026-03-23)
- Regras críticas documentadas (7 regras)
- Renderização condicional obrigatória (ProposalView + PDFDocument)
- Título dinâmico via campo `title` no JSON
- Preços flexíveis (mensal vs único) com `price`/`priceLabel`/`priceSubtitle`
- Bugs react-pdf documentados com proibições explícitas
- Mapa de secções por tipo de proposta
- Checklist pré-build e teste PDF obrigatório
- Condições comerciais em página PDF separada
### v1.0.0 (2026-03-23)
- Versão inicial
---
**Versão:** 2.0.0 | **Data:** 2026-03-23
---
## 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.*
+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.*
+12
View File
@@ -169,3 +169,15 @@ Subject contem:
---
*Skill v1.0.0 | 04-03-2026 | Descomplicar®*
---
## 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.*
+12
View File
@@ -284,3 +284,15 @@ No checkup diário, mostrar tickets:
---
*Skill v1.0.0 | 2026-02-05 | Descomplicar®*
---
## 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.*
@@ -316,3 +316,15 @@ Hashtags/links: #2b6cb0
**Versao**: 1.0.0 | **Data**: 2026-03-10 | **Autor**: Descomplicar®
*Paletas detalhadas por contexto: `references/color-palettes.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.*
+104
View File
@@ -0,0 +1,104 @@
---
name: cinematic-site
category: design-media
description: "Constroi websites cinematograficos a partir de um site existente. Pipeline 4 passos: brand analysis, scene generation, build HTML/CSS, preview. Usar quando 'cinematic', 'website premium', 'site cinematografico', 'redesign site', 'nanobanana'."
version: "1.0.0"
created: 2026-04-07
tools: [Bash, Read, Write, mcp__claude-in-chrome__read_page, mcp__claude-in-chrome__tabs_create_mcp, mcp__chrome-devtools__take_screenshot]
---
# Skill: /cinematic-site
Constroi websites cinematograficos responsivos a partir de um site existente. Inspirado no Nanobanana 2 (#366 Jay E / RoboNuggets).
---
## Pipeline de 4 passos
### Passo 1 — Brand Analysis
Receber URL do site existente do utilizador.
1. Abrir URL via `mcp__claude-in-chrome__tabs_create_mcp` + `mcp__claude-in-chrome__read_page`
2. Extrair:
- Paleta de cores (hex codes das cores dominantes)
- Logo (URL ou descricao)
- Fontes usadas (font-family do CSS)
- Tom de voz (formal, casual, tecnico)
- Tipo de negocio e sector
- Conteudo principal (hero text, servicos, about)
3. Guardar analise em `/tmp/cinematic-site/brand-analysis.json`:
```json
{
"url": "https://...",
"business": "restaurante italiano",
"colors": {"primary": "#2C3E50", "secondary": "#E74C3C", "accent": "#F39C12"},
"fonts": {"heading": "Playfair Display", "body": "Inter"},
"tone": "acolhedor e premium",
"logo_description": "...",
"hero_text": "...",
"sections": ["sobre", "menu", "reservas", "contacto"]
}
```
### Passo 2 — Scene Generation
Com base na analise, definir o design cinematografico:
1. **Hero section:** escolher tipo de animacao:
- Parallax com imagem de fundo
- Scroll-reveal progressivo
- Video background concept (descricao, nao video real)
- Cursor-follow effect
2. **3-5 seccoes adicionais** com animacoes scroll-based:
- Referenciar `Hub/04-Stack/02.03-IA/biblioteca-animacoes-scroll.md` para patterns disponiveis
3. **Responsive breakpoints:** mobile-first, 3 breakpoints (mobile, tablet, desktop)
4. Guardar plano em `/tmp/cinematic-site/scene-plan.md`
### Passo 3 — Build
Gerar ficheiros HTML/CSS/JS:
1. Criar `/tmp/cinematic-site/output/`:
- `index.html` — single-page com todas as seccoes
- `styles.css` — Tailwind ou CSS puro
- `animations.js` — scroll observers + animacoes
2. Regras de qualidade:
- Referenciar `design.json` Descomplicar para standards
- Mobile-first
- Core Web Vitals: LCP <2.5s, CLS <0.1
- Sem dependencias externas pesadas (max framer-motion ou CSS puro)
- Acessibilidade basica (alt text, contraste, focus states)
3. Incluir comentarios no HTML com seccoes claras
### Passo 4 — Preview
1. Abrir `index.html` no browser local: `xdg-open /tmp/cinematic-site/output/index.html`
2. Tirar screenshot via `mcp__chrome-devtools__take_screenshot`
3. Mostrar comparacao ao utilizador:
- Site original (URL)
- Novo site (screenshot)
4. Pedir aprovacao antes de qualquer proximo passo
5. Se aprovado, sugerir opcoes:
- Copiar para pasta de projecto
- Ajustar cores/seccoes
- Exportar para Vercel/Netlify (manual)
---
## Regras
- **Nunca deploy automatico** — apenas preview local
- **Nunca inventar conteudo** — usar texto real do site original
- **Sempre referenciar design.json** para standards visuais
- **Output em /tmp/cinematic-site/** — nunca em pastas de projecto sem aprovacao
- **README.md incluido** com instrucoes de deploy manual
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+278
View File
@@ -0,0 +1,278 @@
---
name: clone-style
description: Clona o estilo visual de um site ou apresentação extraindo design tokens (cores, tipografia, espaçamento, raios, sombras) e gerando JSON compatível com Stitch, design-engine e pptx-generator. Usar quando "clonar estilo", "clone style", "extrair design", "copiar visual", "tokens design", "clone web", "clone slides", "design tokens".
---
# /clone-style — Extrair Design Tokens de Sites e Slides
## Princípio fundamental
**Não tentes recriar visualmente — extrai o sistema.** Captura os tokens (cores, fontes, espaçamentos, raios) e alimenta uma ferramenta generativa. A fidelidade vem do sistema, não da imitação pixel a pixel.
## Modos
| Comando | Fonte | Output |
|---|---|---|
| `/clone-style web <url>` | Site live (browser real, CSS computado) | `tokens.json` + screenshots componentes |
| `/clone-style slides <pptx_path>` | Ficheiro PPTX local | `tokens.json` (theme1.xml + slideMasters) |
| `/clone-style apply <tokens.json>` | Design tokens já extraídos | Aplicação no Stitch / design-engine / pptx-generator |
---
## Modo 1 — Web
### Workflow
1. **Abrir URL no Chrome real** via `mcp__claude-in-chrome__navigate` (preferido — captura sessões logged-in se necessário) ou `mcp__chrome-devtools__navigate_page`.
2. **Aguardar render completo** (`wait_for` "load" + 2s extra para JS).
3. **Injectar script de extracção** via `mcp__claude-in-chrome__javascript_tool` ou `mcp__chrome-devtools__evaluate_script`. O script está em `references/extract-web-tokens.js`. Cola-o dentro do tool call.
4. **O script devolve JSON estruturado** com:
- `colors`: paleta deduplicada + ranking por frequência (top 12)
- `fonts`: famílias únicas + tamanhos + pesos + line-heights
- `spacing`: gaps/paddings/margins agrupados (encontra grid base 4px/8px)
- `borderRadius`: pequeno/médio/grande/full (clusters)
- `shadows`: box-shadows únicas
- `componentes`: HTML+CSS de buttons, cards, nav, hero (capturados como referência)
5. **Capturar screenshots** dos componentes detectados via `mcp__chrome-devtools__take_screenshot` ou `mcp__claude-in-chrome__computer` (full + por componente).
6. **Mapear para Stitch** (ver secção "Mapeamento Stitch" abaixo) — cores → primary seed, fonte mais usada → enum match, raio dominante → ROUND_*.
7. **Guardar** em `~/.claude-work/clone-style/<dominio>-<timestamp>/tokens.json` + `screenshots/`.
### Comando exemplo
```
/clone-style web https://linear.app
```
Output esperado:
- `~/.claude-work/clone-style/linear-app-20260407/tokens.json`
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/full.png`
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/hero.png`
- `~/.claude-work/clone-style/linear-app-20260407/screenshots/buttons.png`
- Resumo no terminal: paleta + fontes + sugestão de aplicação
---
## Modo 2 — Slides (PPTX)
PPTX é um ZIP de XML. Toda a informação de tema está em `ppt/theme/theme1.xml` e `ppt/slideMasters/slideMaster1.xml`.
### Workflow
1. **Verificar input** existe e é PPTX válido (`unzip -l <file>` para listar entradas).
2. **Extrair em tmp**: `unzip -o <file> -d /tmp/clone-style-pptx-<ts>/`.
3. **Parsear `theme1.xml`** (Python ou xmllint):
```python
import xml.etree.ElementTree as ET
ns = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'}
tree = ET.parse('ppt/theme/theme1.xml')
root = tree.getroot()
# Cores tema (accent1-6, dark1, dark2, light1, light2, hyperlink, followedHyperlink)
colors = {}
for child in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}clrScheme'):
for color_node in child:
name = color_node.tag.split('}')[1]
srgb = color_node.find('a:srgbClr', ns)
sysclr = color_node.find('a:sysClr', ns)
if srgb is not None:
colors[name] = '#' + srgb.get('val')
elif sysclr is not None:
colors[name] = '#' + sysclr.get('lastClr', '000000')
# Fontes (major = headlines, minor = body)
fonts = {}
for fs in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}fontScheme'):
major = fs.find('a:majorFont/a:latin', ns)
minor = fs.find('a:minorFont/a:latin', ns)
if major is not None: fonts['headline'] = major.get('typeface')
if minor is not None: fonts['body'] = minor.get('typeface')
```
4. **Parsear `slideMaster1.xml`** para layouts dominantes (background, posições, sizes default).
5. **Output `tokens.json`** no mesmo formato do Modo 1 (para que `apply` seja unificado).
### Comando exemplo
```
/clone-style slides /home/ealmeida/Downloads/template-cliente.pptx
```
---
## Modo 3 — Apply
Recebe `tokens.json` e aplica numa das 3 ferramentas:
### A) Stitch (web/UI)
**Limitação importante:** Stitch só aceita um conjunto restrito de tokens (ver schema `mcp__stitch__create_design_system`):
- 1 `customColor` (seed) + opcionais `overridePrimaryColor`/`overrideSecondaryColor`/`overrideTertiaryColor`/`overrideNeutralColor`
- `headlineFont` / `bodyFont` / `labelFont` de **enum fixo** (29 Google Fonts: INTER, ROBOTO, MANROPE, GEIST, etc.)
- `roundness`: ROUND_4 / ROUND_8 / ROUND_12 / ROUND_FULL
- `colorMode`: LIGHT / DARK
- `designMd`: markdown livre para tudo o que não cabe nos campos acima
**Mapeamento Stitch:**
```
tokens.colors.dominant → customColor (seed)
tokens.colors.top[1..3] → overridePrimary/Secondary/Tertiary
tokens.colors.neutral → overrideNeutralColor
tokens.fonts.headline.family
→ match com enum Stitch (fuzzy: "Helvetica" → INTER, "Söhne" → INTER, etc.)
→ headlineFont
tokens.fonts.body.family
→ match enum → bodyFont
tokens.borderRadius.dominant
→ 4px → ROUND_4
→ 8-10px → ROUND_8
→ 12-14px → ROUND_12
→ ≥16px ou full → ROUND_FULL
tokens.background.dark? → colorMode: DARK, else LIGHT
# Tudo o resto vai para designMd:
designMd: |
## Estilo extraído de <fonte>
### Tipografia adicional
- Display: <font> <size> <weight>
- Caption: <font> <size> <weight>
### Espaçamento
Grid base: <Npx>
Escala: 4, 8, 16, 24, 32, 48, 64
### Sombras
- sm: <box-shadow>
- md: <box-shadow>
- lg: <box-shadow>
### Tom visual
<descrição em prosa: minimalista, denso, colorido, monocromático, etc.>
```
Depois chama `mcp__stitch__create_design_system` com este payload.
### B) design-engine (brand pack)
Cria um JSON brand pack em `/media/ealmeida/Dados/Hub/04-Recursos/Design/brands/<nome>.json` com formato:
```json
{
"name": "<nome>",
"source": "cloned from <url|pptx>",
"extracted_at": "2026-04-07",
"colors": { "primary": "#...", "secondary": "#...", "neutral": "#...", "accent": "#..." },
"fonts": { "headline": "Inter", "body": "Inter" },
"borderRadius": "8px",
"tone": "minimalista, profissional, denso"
}
```
Depois `mcp__design-engine__brand_load(<nome>)` para usar em `generate_image`.
### C) pptx-generator (slides)
Aplica os tokens via XML manipulation no template Descomplicar (ver `/pptx-generator`). Substitui:
- Cores accent1-6 do `theme1.xml` pelos extraídos
- Fontes major/minor pelas extraídas
- Mantém layouts/positioning do template Descomplicar (não copia layouts da fonte original — só estilo)
---
## Mapeamento de fontes (fuzzy → Stitch enum)
Quando `tokens.fonts.headline.family` não está no enum Stitch, mapear:
| Família detectada | Stitch enum |
|---|---|
| Helvetica, Helvetica Neue, Arial, sans-serif genérico | INTER |
| Söhne, Inter, system-ui | INTER |
| Roboto, Roboto Flex | (não existe — usar INTER) |
| SF Pro, -apple-system | INTER |
| GT Walsheim, Geist, Mona Sans | GEIST |
| Manrope | MANROPE |
| Plus Jakarta, Jakarta | PLUS_JAKARTA_SANS |
| DM Sans | DM_SANS |
| IBM Plex Sans | IBM_PLEX_SANS |
| Sora | SORA |
| Times, serif genérico | NEWSREADER |
| Garamond, EB Garamond | EB_GARAMOND |
| Playfair, Domine | DOMINE |
Se nenhum match óbvio, **default INTER** (mais neutro). Adicionar nota em `designMd` com a fonte original detectada.
---
## Anti-patterns
| Não fazer | Razão |
|---|---|
| Tentar reproduzir layout pixel a pixel | Impossível e gera "AI slop" |
| Usar `cssstats.com` ou scrapers HTML estáticos | Falham em sites JS-rendered (Next.js, React, etc.) |
| Importar HTML inteiro como Stitch screen | Stitch não importa HTML; gera de prompt+tokens |
| Aplicar Stitch design-system sem `customColor` válido | Validation error — `customColor` é obrigatório |
| Esquecer de usar `designMd` para tokens fora do enum | Perde-se 50% da informação extraída |
---
## Validação (critérios para "OK")
Antes de declarar a clonagem completa:
1. ✅ `tokens.json` existe e tem `colors`, `fonts`, `borderRadius` no mínimo
2. ✅ Pelo menos 1 screenshot guardado
3. ✅ Mapeamento Stitch produz `customColor` válido (hex format)
4. ✅ Pelo menos 1 fonte mapeada para enum Stitch
5. ✅ `designMd` tem ≥3 secções (tipografia, espaçamento, tom)
6. ✅ Se modo `apply`: validação visual pelo utilizador antes de marcar "concluído"
---
## Exemplos práticos
### Clonar Linear
```
/clone-style web https://linear.app
```
Esperado: paleta dominante azul/roxo, fontes Inter ou similar, raios 6-8px, dark mode default.
### Clonar template cliente
```
/clone-style slides ~/Downloads/cliente-deck.pptx
```
Esperado: cores accent do tema PPTX, fontes major/minor, proposta de paleta unificada.
### Aplicar a novo projecto Stitch
```
/clone-style apply ~/.claude-work/clone-style/linear-app-20260407/tokens.json
```
Cria design system Stitch + brand pack design-engine.
---
## Referências internas
- `references/extract-web-tokens.js` — script JS de extracção CSS computado
- `references/extract-pptx-theme.py` — script Python para parsear theme1.xml
- `~/.claude-work/clone-style/` — cache de extracções (timestamped)
---
**Versão:** 1.0.0 | **Data:** 2026-04-07 | **Autor:** Descomplicar (sessão 5)
**Origem:** Necessidade real — clonagem de estilos em propostas comerciais. Substitui tentativas falhadas com Penpot, scrapers HTML, screenshots+AI, Figma import.
@@ -0,0 +1,133 @@
#!/usr/bin/env python3
"""
extract-pptx-theme.py — extrai design tokens de um ficheiro PPTX
Uso:
python3 extract-pptx-theme.py <caminho.pptx> [--output tokens.json]
Devolve JSON no mesmo formato do extract-web-tokens.js para que /clone-style apply
seja unificado entre os 2 modos.
"""
import sys
import json
import zipfile
import xml.etree.ElementTree as ET
from pathlib import Path
from datetime import datetime, timezone
NS = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'}
def extract_theme(pptx_path: Path) -> dict:
if not pptx_path.exists():
raise FileNotFoundError(f"Não encontrado: {pptx_path}")
with zipfile.ZipFile(pptx_path) as z:
# Listar themes (pode haver múltiplos; usar o primeiro)
theme_files = sorted([n for n in z.namelist() if n.startswith('ppt/theme/theme') and n.endswith('.xml')])
if not theme_files:
raise ValueError("PPTX sem theme — formato inválido ou corrompido")
theme_xml = z.read(theme_files[0])
root = ET.fromstring(theme_xml)
# Extrair cores do clrScheme
colors = {}
for clr_scheme in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}clrScheme'):
for color_node in clr_scheme:
name = color_node.tag.split('}')[1] # ex: 'accent1', 'dk1', 'lt1'
srgb = color_node.find('a:srgbClr', NS)
sysclr = color_node.find('a:sysClr', NS)
if srgb is not None:
colors[name] = '#' + srgb.get('val')
elif sysclr is not None:
# sysClr usa o lastClr como fallback (cor resolvida)
colors[name] = '#' + sysclr.get('lastClr', '000000')
# Extrair fontes do fontScheme
fonts = {'headline': None, 'body': None}
for fs in root.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}fontScheme'):
major = fs.find('a:majorFont/a:latin', NS)
minor = fs.find('a:minorFont/a:latin', NS)
if major is not None:
fonts['headline'] = major.get('typeface')
if minor is not None:
fonts['body'] = minor.get('typeface')
# Mapear cores PPTX → estrutura unificada
accent_keys = ['accent1', 'accent2', 'accent3', 'accent4', 'accent5', 'accent6']
accents = [colors[k] for k in accent_keys if k in colors]
primary = colors.get('accent1') or accents[0] if accents else '#000000'
secondary = colors.get('accent2')
tertiary = colors.get('accent3')
neutral = colors.get('lt1') or colors.get('dk1') or '#ffffff'
background = colors.get('lt1') or colors.get('bg1') or '#ffffff'
is_dark = colors.get('lt1', '#ffffff').lstrip('#').upper() != 'FFFFFF'
return {
'url': str(pptx_path),
'title': pptx_path.stem,
'source': 'pptx',
'timestamp': datetime.now(timezone.utc).isoformat(),
'colors': {
'top': [{'value': v, 'count': 1} for v in accents],
'backgrounds': [{'value': background, 'count': 1}],
'dominant': primary,
'raw_scheme': colors,
},
'fonts': {
'families': [
{'value': fonts['headline'], 'count': 1, 'role': 'headline'},
{'value': fonts['body'], 'count': 1, 'role': 'body'},
],
'sizes': [],
'weights': [],
'lineHeights': [],
},
'borderRadius': [],
'shadows': [],
'spacing': {'gridBaseGuess': 8, 'top': []},
'components': {},
'meta': {
'colorMode': 'DARK' if is_dark else 'LIGHT',
'theme_file': theme_files[0],
'accent_count': len(accents),
},
'mapping_hint': {
'stitch_customColor': primary,
'stitch_overrideSecondary': secondary,
'stitch_overrideTertiary': tertiary,
'stitch_overrideNeutral': neutral,
'note': 'PPTX só fornece cores e fontes — borderRadius/shadows/spacing têm de ser definidos manualmente em designMd',
},
}
def main():
if len(sys.argv) < 2:
print(__doc__, file=sys.stderr)
sys.exit(1)
pptx = Path(sys.argv[1]).expanduser().resolve()
output_path = None
if '--output' in sys.argv:
idx = sys.argv.index('--output')
if idx + 1 < len(sys.argv):
output_path = Path(sys.argv[idx + 1]).expanduser().resolve()
tokens = extract_theme(pptx)
js = json.dumps(tokens, indent=2, ensure_ascii=False)
if output_path:
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(js, encoding='utf-8')
print(f"✅ Tokens guardados em {output_path}", file=sys.stderr)
else:
print(js)
if __name__ == '__main__':
main()
@@ -0,0 +1,122 @@
// extract-web-tokens.js
// Injectar via mcp__claude-in-chrome__javascript_tool ou mcp__chrome-devtools__evaluate_script
// Devolve JSON com cores, fontes, espaçamentos, raios, sombras e amostras de componentes.
// Funciona em qualquer site (incluindo JS-rendered) porque usa getComputedStyle().
(() => {
const all = document.querySelectorAll('*');
const colorCounts = {};
const fontFamilies = {};
const fontSizes = {};
const fontWeights = {};
const lineHeights = {};
const radii = {};
const shadows = {};
const spacings = {};
const bgColors = {};
const norm = (v) => (v || '').trim();
const inc = (obj, k) => { if (!k || k === 'none' || k === '0px') return; obj[k] = (obj[k] || 0) + 1; };
// Helper: rgb(a) → hex (ignora transparente)
const toHex = (rgb) => {
if (!rgb || rgb === 'transparent' || rgb === 'rgba(0, 0, 0, 0)') return null;
const m = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
if (!m) return null;
const a = m[4] !== undefined ? parseFloat(m[4]) : 1;
if (a < 0.1) return null;
const h = (n) => parseInt(n).toString(16).padStart(2, '0');
return '#' + h(m[1]) + h(m[2]) + h(m[3]);
};
for (const el of all) {
if (!(el instanceof Element)) continue;
const cs = getComputedStyle(el);
// Cores
inc(colorCounts, toHex(cs.color));
const bg = toHex(cs.backgroundColor);
if (bg) {
inc(bgColors, bg);
inc(colorCounts, bg);
}
inc(colorCounts, toHex(cs.borderColor));
// Fontes
inc(fontFamilies, norm(cs.fontFamily));
inc(fontSizes, norm(cs.fontSize));
inc(fontWeights, norm(cs.fontWeight));
inc(lineHeights, norm(cs.lineHeight));
// Raios
inc(radii, norm(cs.borderRadius));
// Sombras
if (cs.boxShadow && cs.boxShadow !== 'none') inc(shadows, cs.boxShadow);
// Espaçamentos (paddings + margins + gap)
['paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginLeft', 'gap', 'rowGap', 'columnGap'].forEach((p) => {
inc(spacings, norm(cs[p]));
});
}
// Top N por frequência
const topN = (obj, n) => Object.entries(obj).sort((a, b) => b[1] - a[1]).slice(0, n).map(([k, v]) => ({ value: k, count: v }));
// Detectar grid base (espaçamento mais comum)
const numericSpacings = Object.entries(spacings)
.map(([k, v]) => [parseFloat(k), v])
.filter(([n]) => !isNaN(n) && n > 0 && n < 200)
.sort((a, b) => b[1] - a[1]);
const gridBase = numericSpacings[0]?.[0] || 8;
// Capturar samples HTML de componentes-chave (pelo selector)
const sample = (sel) => {
const el = document.querySelector(sel);
if (!el) return null;
return {
html: el.outerHTML.substring(0, 800),
computed: {
bg: toHex(getComputedStyle(el).backgroundColor),
color: toHex(getComputedStyle(el).color),
radius: getComputedStyle(el).borderRadius,
padding: getComputedStyle(el).padding,
font: getComputedStyle(el).fontFamily,
}
};
};
return {
url: location.href,
title: document.title,
timestamp: new Date().toISOString(),
colors: {
top: topN(colorCounts, 12),
backgrounds: topN(bgColors, 6),
dominant: topN(colorCounts, 1)[0]?.value || null,
},
fonts: {
families: topN(fontFamilies, 5),
sizes: topN(fontSizes, 8),
weights: topN(fontWeights, 6),
lineHeights: topN(lineHeights, 6),
},
borderRadius: topN(radii, 6),
shadows: topN(shadows, 5),
spacing: {
gridBaseGuess: gridBase,
top: topN(spacings, 12),
},
components: {
button: sample('button, .btn, [class*="button" i]'),
card: sample('.card, [class*="card" i]'),
nav: sample('nav, header, [class*="nav" i]'),
hero: sample('main > section:first-child, .hero, [class*="hero" i]'),
},
meta: {
colorMode: getComputedStyle(document.body).backgroundColor.includes('255') ? 'LIGHT' : 'DARK',
lang: document.documentElement.lang || 'unknown',
viewport: document.querySelector('meta[name=viewport]')?.content || null,
}
};
})();
+66
View File
@@ -0,0 +1,66 @@
---
name: design-b2b
description: >
Design system para serviços B2B — agências, consultoria, SaaS, PMEs portuguesas.
Propostas visuais, landing pages, apresentações e materiais para decisores PT.
Usar quando: proposta comercial, landing page serviço B2B, apresentação cliente,
one-pager, ou qualquer material visual para audiência empresarial portuguesa.
---
# /design-b2b — Design System Serviços B2B
## Paleta
```css
--primary: #1e3a5f; /* Azul institucional — confiança, autoridade */
--accent: #f97316; /* Laranja acção — CTAs, destaques */
--neutral: #f8fafc; /* Fundo profissional */
--text: #1e293b; /* Texto principal */
--muted: #64748b; /* Texto secundário, legendas */
--border: #e2e8f0; /* Divisores subtis */
```
## Estrutura proposta comercial
### One-pager (1 A4 ou landing page equivalente)
1. **Header:** Logo cliente + logo Descomplicar + título proposta
2. **Problema:** 2-3 bullets do problema actual do cliente
3. **Solução:** O que entregamos (concreto, não vago)
4. **Resultados:** Métricas esperadas (%, EUR, tempo)
5. **Investimento:** Preço claro, sem asteriscos escondidos
6. **Próximo passo:** CTA único — "Agendar Reunião" ou "Aceitar Proposta"
### Landing page serviço B2B
1. Headline: benefício principal (não feature)
2. Sub-headline: para quem é + resultado esperado
3. Prova social: 3 logos de clientes ou 1 case study
4. Serviços: 3-5 cards com ícone + nome + 1 linha
5. Processo: 3-4 passos (simples e claro)
6. CTA: formulário simples (nome, email, empresa, mensagem)
## Tom e linguagem B2B PT
- **Usar:** "optimizar", "aumentar eficiência", "reduzir custos"
- **Evitar:** "disruptivo", "revolucionário", "próximo nível"
- **Tratamento:** "Você" (neutro) ou "A sua empresa" — nunca "tu" em contexto formal
- **Números:** sempre com fonte (ex: "30% redução de custos — caso Empresa X")
## Anti-slop checklist B2B
- [ ] Zero jargão sem explicação
- [ ] Preços ou "Solicitar orçamento" — nunca ambiguidade
- [ ] Casos reais, não hipotéticos
- [ ] Mobile: decisores usam telemóvel para primeiro contacto
- [ ] Social proof: logo real, não ilustração
## Referências visuais
Ver `~/.claude/design/referencias-visuais/servicos-b2b/`
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
@@ -0,0 +1,64 @@
---
name: design-ecommerce
description: >
Design system para e-commerce — lojas WooCommerce, páginas produto, checkout PT.
Optimização conversão, layouts loja, UX checkout e elementos de confiança.
Usar quando: criar ou optimizar loja WooCommerce, página produto, carrinho,
checkout, ou qualquer elemento visual de e-commerce para mercado português.
---
# /design-ecommerce — Design System E-commerce
## Paleta base (adaptar à marca do cliente)
```css
--cta: #dc2626; /* Vermelho urgência — "Comprar Agora" */
--trust: #16a34a; /* Verde confiança — "Pagamento Seguro" */
--price: #1e3a5f; /* Azul preço destacado */
--sale: #f59e0b; /* Âmbar promoção */
--neutral: #ffffff;
--text: #111827;
```
## Elementos conversão obrigatórios
### Página produto
1. Imagens: mínimo 4 ângulos, zoom, vídeo se possível
2. Preço: destacado, desconto visível, preço original riscado
3. Stock: urgência ("Últimas 3 unidades")
4. CTA: "Adicionar ao Carrinho" (vermelho, proeminente)
5. Confiança: selos Visa/MB/MBWay + devolução 30 dias
6. Avaliações: estrelas + número (social proof)
7. "Também pode gostar" + "Compraram juntos"
### Checkout PT
- Referência Multibanco visível
- MB Way como opção principal
- Campo NIF opcional (B2B)
- Morada: formato PT (Rua, nº, andar, código postal, localidade)
### Elementos de confiança PT
- Selos: MBWay, Visa, Mastercard, PayPal
- "Envio para Portugal Continental em 24-48h"
- "Devolução gratuita em 30 dias"
- "Suporte em português"
## Anti-slop checklist e-commerce
- [ ] Preços em EUR (não USD)
- [ ] CTAs em PT-PT: "Comprar" não "Buy", "Carrinho" não "Cart"
- [ ] Mobile: checkout testado em 375px (maioria compra no telemóvel)
- [ ] Tempo de carregamento: imagens optimizadas <100KB
- [ ] Trust badges visíveis acima do fold
## Referências visuais
Ver `~/.claude/design/referencias-visuais/ecommerce/`
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+62
View File
@@ -0,0 +1,62 @@
---
name: design-saude
description: >
Design system para sector saúde — clínicas, KiviCare, consultórios médicos.
Paleta, tipografia, CTAs e layouts optimizados para contexto clínico PT.
Usar quando: criar landing page de clínica, página de serviços médicos,
agendamento online, ou qualquer material visual para clientes saúde.
---
# /design-saude — Design System Saúde
## Paleta
```css
--primary: #0ea5e9; /* Azul confiança médica */
--secondary: #10b981; /* Verde saúde/cura */
--neutral: #f8fafc; /* Fundo limpo e asséptico */
--text: #1e293b; /* Texto principal */
--accent: #f59e0b; /* CTA urgência (marcar consulta) */
--danger: #ef4444; /* Alertas, urgências */
```
## Tipografia
- **Títulos:** Inter SemiBold — transmite profissionalismo sem frieza
- **Corpo:** Inter Regular 16px, line-height 1.7 — legibilidade para público 40+
- **Evitar:** fontes decorativas, cursivas, serifas antiquadas
## Layouts obrigatórios
### Landing page clínica
1. Hero: foto médico real + headline "Cuidamos de si" + CTA "Marcar Consulta"
2. Serviços: cards com ícone + nome + preço (se disponível)
3. Equipa: fotos reais + credenciais
4. Depoimentos: com nome e tratamento (anonimizado se necessário)
5. Localização + horários + contacto
6. CTA final: WhatsApp ou formulário
### CTAs saúde
- Principal: "Marcar Consulta" (verde, proeminente)
- Secundário: "Saber Mais" ou "Ver Serviços"
- Urgência: "Consulta Hoje" (âmbar)
## Anti-slop checklist saúde
- [ ] Fotos de pessoas reais (não stock de médicos brancos genéricos)
- [ ] RGPD: sem dados de pacientes visíveis em mockups
- [ ] Cores acessíveis: contraste WCAG AA mínimo
- [ ] Mobile: formulário agendamento testado em 375px
- [ ] PT-PT: "consulta" não "appointment", "médico" não "doctor"
## Referências visuais
Ver `~/.claude/design/referencias-visuais/saude/`
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+60
View File
@@ -0,0 +1,60 @@
---
name: design-solar
description: >
Design system para sector solar/fotovoltaico — SolarFV, instaladores, B2B energia.
Paleta, calculadoras, propostas visuais e layouts para sector energias renováveis PT.
Usar quando: landing page solar, proposta instalação FV, calculadora poupança,
ou material visual para clientes energia solar.
---
# /design-solar — Design System Solar/FV
## Paleta
```css
--primary: #f59e0b; /* Amarelo solar — energia, optimismo */
--secondary: #1e3a5f; /* Azul escuro — confiança, profissionalismo B2B */
--green: #16a34a; /* Verde sustentabilidade */
--neutral: #f9fafb; /* Fundo limpo */
--text: #111827; /* Texto principal */
```
## Elementos distintivos sector solar
### Calculadora de poupança (elemento central)
- Input: consumo mensal kWh + factura actual
- Output: poupança anual estimada + payback em anos
- Visual: comparação antes/depois com gráfico simples
### Proposta instalação
1. Sumário executivo (1 página): consumo actual → produção estimada → ROI
2. Especificações técnicas: painéis, inversor, capacidade
3. Financiamento: opções (compra, leasing, PPA)
4. Garantias e certificações
5. CTA: "Solicitar Visita Técnica"
## Tipografia
- **Títulos:** Poppins Bold — moderno, energético
- **Dados/métricas:** Inter Mono — leiturabilidade para números
- **Corpo:** Inter Regular
## Anti-slop checklist solar
- [ ] Números reais de produção (não inventar kWh)
- [ ] Certificações visíveis (DGEG, SCE)
- [ ] Mobile: calculadora funcional em 375px
- [ ] B2B: tom técnico e sóbrio (não "salve o planeta")
- [ ] PT: "fotovoltaico" não "fotovoltaica" (painel fotovoltaico)
## Referências visuais
Ver `~/.claude/design/referencias-visuais/solar/`
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
+30 -16
View File
@@ -44,11 +44,11 @@ Integrar insights do NotebookLM nas recomendações e decisões.
|---------|--------|-------|
| `/design [descricao]` | Routing automatico | Auto |
| `/design presentation [tema]` | Apresentacao PPTX/PDF | Presenton |
| `/design infographic [tema]` | Infografico PNG/PDF | Penpot + AI |
| `/design social [plataforma] [tema]` | Post redes sociais | Penpot |
| `/design web [descricao]` | Landing page / web component | Stitch |
| `/design logo [nome]` | Logo SVG + variacoes | Penpot + Fibo |
| `/design brand [empresa]` | Identidade visual completa | Todos |
| `/design infographic [tema]` | Infografico PNG/PDF | design-engine (Fibo/Gemini) |
| `/design social [plataforma] [tema]` | Post redes sociais | design-engine |
| `/design web [descricao]` | Landing page / web component | **Stitch (motor principal)** |
| `/design logo [nome]` | Logo SVG + variacoes | design-engine + Fibo |
| `/design brand [empresa]` | Identidade visual completa | Stitch + design-engine |
| `/design from-reference [url]` | Analisa e recria adaptado | Auto |
## Parametros Opcionais
@@ -66,11 +66,11 @@ Integrar insights do NotebookLM nas recomendações e decisões.
1. PARSE comando e parametros
2. IDENTIFICAR tipo de output
- "presentation" / "slides" / "proposta" -> Presenton
- "infographic" / "poster" / "flyer" -> Penpot
- "social" / "instagram" / "linkedin" -> Penpot (dimensoes)
- "infographic" / "poster" / "flyer" -> design-engine (Fibo/Gemini)
- "social" / "instagram" / "linkedin" -> design-engine (com dimensões)
- "web" / "landing" / "page" / "ui" -> Stitch
- "logo" / "icone" / "marca" -> Penpot + Fibo
- "brand" / "identidade" -> Pipeline completo
- "logo" / "icone" / "marca" -> design-engine + Fibo
- "brand" / "identidade" -> Stitch (web) + design-engine (assets)
- "from-reference" -> Researcher primeiro
3. SE --brand especificado:
- Carregar brand pack via design-engine MCP: brand_load(nome)
@@ -91,7 +91,7 @@ Resultado: PPTX profissional via Presenton com cores dourado/preto, logo Descomp
```
/design social instagram "Promocao Black Friday -30%"
```
Resultado: Imagem 1080x1080 composta no Penpot com texto, cores e layout profissional.
Resultado: Imagem 1080x1080 gerada via design-engine (Fibo/Gemini) com texto, cores e layout profissional.
### Landing page
```
@@ -103,7 +103,7 @@ Resultado: HTML/CSS via Stitch com Design DNA da marca.
```
/design infographic "Top 10 tendencias AI 2026"
```
Resultado: PNG/PDF vertical composto no Penpot com icones, dados e hierarquia visual.
Resultado: PNG/PDF vertical gerado via design-engine com icones, dados e hierarquia visual.
### Identidade visual completa
```
@@ -117,16 +117,17 @@ Resultado: Logo + paleta + tipografia + templates social + template apresentacao
```
Resultado: Analisa design Figma, extrai estilo, recria adaptado.
## 5 MCPs de Design
## MCPs de Design (4)
| MCP | Funcao |
|-----|--------|
| **design-engine** | Imagens AI (Fibo/Gemini) + brand packs + rembg |
| **design-engine** | Imagens AI (Fibo/Gemini) + brand packs + rembg + composição |
| **presenton** | Apresentacoes AI (slide.descomplicar.pt) |
| **penpot** | Compositor visual (pen.descomplicar.pt) |
| **stitch** | Web design AI (Google) |
| **stitch** | Web design AI text→UI (Google Labs) — motor principal para web/ui/landing |
| **figma** | Analise referencias (read-only) |
> **Penpot suspenso 07-04-2026 sessão 5** — substituído por Stitch (text→UI generation). MCP penpot removido. Se Stitch for descontinuado, reavaliar.
## Brand Packs Disponiveis
Verificar com: `brand_list()` via design-engine MCP.
@@ -153,4 +154,17 @@ fidelidade, concisao visual, legibilidade, profissionalismo, brand compliance.
---
**Versao**: 2.0.0 | **Data**: 2026-02-12 | **Autor**: Descomplicar
**Versao**: 2.1.0 | **Data**: 2026-04-07 | **Autor**: Descomplicar
**v2.1.0:** Penpot removido como motor activo (substituído por Stitch para web/ui e design-engine para imagens/social/infográficos). Workflow simplificado.
---
## 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.*
+124
View File
@@ -0,0 +1,124 @@
---
name: benchmark
description: >
Mede Core Web Vitals e performance antes/depois de alterações. Detecta regressões.
Usar antes e depois de qualquer alteração a WP, WooCommerce, Next.js ou infra.
Baseado no gstack /benchmark. Eixo 2B.
---
# /benchmark — Performance Antes/Depois
Medir o impacto real de alterações. Nunca fazer deploy sem benchmark.
---
## Quando Usar
- Antes de qualquer optimização de performance
- Antes de deploy de plugins/temas WordPress
- Antes de alterações ao servidor ou cache
- Antes de implementar nova feature em produção
- Como baseline mensal de cada site
---
## Métricas Alvo (Core Web Vitals 2024)
| Métrica | Bom | Precisa Melhorar | Mau |
|---------|-----|-----------------|-----|
| LCP (Largest Contentful Paint) | ≤2.5s | 2.5-4.0s | >4.0s |
| FID / INP (Interaction to Next Paint) | ≤200ms | 200-500ms | >500ms |
| CLS (Cumulative Layout Shift) | ≤0.1 | 0.1-0.25 | >0.25 |
| TTFB (Time to First Byte) | ≤800ms | 800-1800ms | >1800ms |
| FCP (First Contentful Paint) | ≤1.8s | 1.8-3.0s | >3.0s |
---
## Protocolo
### Passo 1 — Baseline (ANTES)
```bash
# Via MCP Lighthouse (se disponível)
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
mcp__lighthouse__run_audit({ url: "<URL>", categories: ["performance"] })
# Ou via Lighthouse CLI no servidor
ssh server "lighthouse <URL> --output=json --output-path=/tmp/before.json --chrome-flags='--headless'"
# Ou via PageSpeed Insights API
curl "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=<URL>&strategy=mobile" | jq '.lighthouseResult.categories.performance.score'
```
**Guardar baseline:**
```bash
BEFORE_LCP=<valor>
BEFORE_CLS=<valor>
BEFORE_FCP=<valor>
BEFORE_SCORE=<valor>
```
### Passo 2 — Executar Alteração
Fazer a alteração (deploy, optimização, plugin, etc.)
### Passo 3 — Depois
```bash
# Repetir as mesmas medições
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
AFTER_LCP=<valor>
AFTER_CLS=<valor>
AFTER_FCP=<valor>
AFTER_SCORE=<valor>
```
### Passo 4 — Comparação
```markdown
## Benchmark — [Site] — [Data]
| Métrica | Antes | Depois | Delta | Estado |
|---------|-------|--------|-------|--------|
| LCP | Xs | Ys | ±Zs | ✅/⚠️/❌ |
| CLS | X | Y | ±Z | ✅/⚠️/❌ |
| FCP | Xs | Ys | ±Zs | ✅/⚠️/❌ |
| Score | X% | Y% | ±Z% | ✅/⚠️/❌ |
**Veredicto:** MELHOROU / NEUTRO / REGREDIU
**Acção:** Manter deploy / Reverter / Investigar
```
---
## Regras de Decisão
```
SE qualquer métrica piorou >10% → REVERTER imediatamente
SE Score global piorou >5 pontos → investigar antes de continuar
SE CLS aumentou >0.05 → bloquear — UX crítica
SE LCP piorou >500ms em mobile → reverter
```
---
## Sites Descomplicar a Monitorizar
| Site | URL | Frequência |
|------|-----|-----------|
| Descomplicar main | descomplicar.pt | Mensal |
| Clip | clip.descomplicar.pt | Após cada deploy |
| Outros clientes | variável | Após alterações WP |
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
---
*Skill /benchmark v1.0 | 06-04-2026 | Eixo 2B — gstack pattern*
+155
View File
@@ -0,0 +1,155 @@
---
name: canary
description: >
Monitorização pós-deploy — detecta regressões em produção. Verifica que o deploy
não quebrou nada crítico nos 15min seguintes. Baseado no gstack /canary. Eixo 2B.
Usar após qualquer deploy em produção.
---
# /canary — Monitorização Pós-Deploy
Os primeiros 15 minutos após um deploy são os mais críticos. Esta skill verifica que tudo está OK.
---
## Quando Usar (SEMPRE após deploy produção)
- Após deploy de código em produção
- Após actualização de WordPress (core, plugins, temas)
- Após alterações de servidor (PHP, Nginx, MySQL)
- Após mudanças de DNS ou SSL
- Após activação de nova funcionalidade
---
## Protocolo (15 minutos)
### Minuto 0-2 — Status Checks
```bash
# 1. Site responde?
curl -s -o /dev/null -w "%{http_code}" <URL>/
# Esperado: 200
# 2. Admin WP responde?
curl -s -o /dev/null -w "%{http_code}" <URL>/wp-admin/
# Esperado: 200 ou 302
# 3. SSL válido?
curl -vI <URL> 2>&1 | grep "SSL certificate verify"
# Esperado: SSL certificate verify ok
# 4. Tempo de resposta aceitável?
curl -s -o /dev/null -w "%{time_total}\n" <URL>/
# Esperado: < 3.0 segundos
```
### Minuto 2-5 — Funcionalidades Críticas
**Para WordPress:**
```bash
# Página principal carrega sem erros
curl -s <URL>/ | grep -c "wp-content"
# Esperado: > 0
# Sem erro crítico PHP
curl -s <URL>/ | grep -i "fatal error\|parse error\|warning"
# Esperado: sem output
# WP-CLI status
wp --path=/var/www/html core verify-checksums 2>&1 | tail -1
# Esperado: "WordPress installation verifies against checksums."
```
**Para aplicações:**
```bash
# Health endpoint
curl -s <URL>/api/health | jq '.status'
# Esperado: "ok"
# Database conecta?
curl -s <URL>/api/health | jq '.database'
# Esperado: "connected"
```
### Minuto 5-10 — Métricas de Performance
```javascript
// Via Lighthouse MCP
mcp__lighthouse__get_performance_score({ url: "<URL>" })
// Esperado: >= baseline (ver /benchmark)
mcp__lighthouse__get_core_web_vitals({ url: "<URL>" })
// Comparar com baseline guardado
```
### Minuto 10-15 — Logs e Erros
```bash
# Erros PHP nas últimas 15 min
ssh server "tail -100 /var/log/php/error.log | grep '$(date -d '15 minutes ago' +%H:%M)'"
# Erros Nginx/Apache
ssh server "tail -50 /var/log/nginx/error.log"
# WooCommerce (se aplicável)
wp --path=/var/www/html wc log list 2>&1 | head -20
```
---
## Output — Relatório Canary
```markdown
## Canary Check — [Site] — [Data] [Hora]
**Deploy:** [O que foi alterado]
| Check | Estado | Detalhe |
|-------|--------|---------|
| HTTP 200 | ✅/❌ | |
| SSL | ✅/❌ | |
| Tempo resposta | ✅/❌ | Xs |
| Sem erros PHP | ✅/❌ | |
| Performance score | ✅/❌ | X% (base: Y%) |
| Logs limpos | ✅/❌ | |
**Resultado:** ✅ DEPLOY ESTÁVEL | ⚠️ INVESTIGAR | ❌ REVERTER
```
---
## Critérios de Reversão Imediata
```
❌ HTTP response != 200 → REVERTER
❌ SSL falha → REVERTER
❌ "Fatal error" em qualquer página → REVERTER
❌ Tempo resposta > 10s → INVESTIGAR
❌ Performance score caiu >15 pontos → INVESTIGAR
❌ Logs com erros críticos → INVESTIGAR
```
---
## Escalada Automática
Se algum check falha:
```
1. NOTIFICAR: criar issue no Desk CRM com urgência P1
2. REVERTER: se erro crítico, reverter imediatamente
3. DOCUMENTAR: o que falhou e quando
4. ANALISAR: root cause antes de re-deploy
```
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
---
*Skill /canary v1.0 | 06-04-2026 | Eixo 2B — gstack pattern*
+12
View File
@@ -301,3 +301,15 @@ Activar Chrome por defeito **aumenta consumo de context window** porque as ferra
1. Desactivar default: `/chrome` -> desactivar
2. Usar `claude --chrome` apenas quando necessario
3. Preferir WebFetch para leituras simples de paginas publicas
---
## 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.*
+12
View File
@@ -241,3 +241,15 @@ Output: [resultado esperado]
Input: [caso complexo]
Output: [resultado detalhado]
```
---
## 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.*
+12
View File
@@ -461,3 +461,15 @@ git commit
**Skill v1.1** | 12-03-2026 | Descomplicar® | Renomeado de /security-check para /dep-audit
**Security First** - Zero vulnerabilities ou documentadas
---
## 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.*
+267
View File
@@ -0,0 +1,267 @@
---
name: diagrama
category: dev-tools
description: "Gera diagramas de arquitectura, fluxo, ER e sequência em três formatos: draw.io (.drawio), Excalidraw e Mermaid. Usar quando 'diagrama', 'arquitectura', 'draw.io', 'fluxo', 'ER', 'sequência', 'infra', 'componentes'."
version: "1.0.0"
created: 2026-04-04
tools: [mcp__claude_ai_Excalidraw__export_to_excalidraw, mcp__mcp-mermaid__generate, Write, Bash]
---
# Skill: /diagrama
Gera diagramas técnicos em três formatos consoante o caso de uso. Suporta arquitectura de sistemas, fluxogramas, diagramas ER, sequência, infra-estrutura e redes.
---
## Quando usar cada formato
| Formato | Quando usar | Output |
|---------|------------|--------|
| **draw.io** | Diagramas formais para documentação, propostas, clientes | `.drawio` (editável) |
| **Excalidraw** | Esboços rápidos, brainstorming visual, estilo whiteboard | `.excalidraw` / MCP |
| **Mermaid** | Diagramas como código, versionáveis em Git, embeds Markdown | `.svg` / `.png` |
---
## Processo de execução
### 1. Identificar pedido
Quando o utilizador pede um diagrama, detectar:
- **Tipo:** arquitectura | fluxo | ER | sequência | rede | organograma | classe
- **Formato pretendido:** draw.io (default para doc. formal) | excalidraw | mermaid
- **Contexto:** sistemas envolvidos, entidades, actores
Se não especificado, perguntar apenas: "draw.io (formal) ou Excalidraw (esboço)?"
### 2. Gerar conteúdo
---
## Geração draw.io (.drawio)
O formato draw.io é mxGraph XML. Gerar o XML e guardar como `.drawio`.
### Estrutura base
```xml
<mxfile host="Claude Code" modified="YYYY-MM-DDTHH:MM:SS" agent="Claude" version="21.0">
<diagram name="Diagrama" id="diagram-1">
<mxGraphModel dx="1422" dy="762" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<!-- elementos aqui -->
</root>
</mxGraphModel>
</diagram>
</mxfile>
```
### Templates de elementos mxGraph
**Rectângulo (componente/serviço):**
```xml
<mxCell id="2" value="Nome" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="160" y="160" width="120" height="60" as="geometry"/>
</mxCell>
```
**Seta/ligação:**
```xml
<mxCell id="10" edge="1" source="2" target="3" parent="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
```
**Cilindro (base de dados):**
```xml
<mxCell id="5" value="PostgreSQL" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;" vertex="1" parent="1">
<mxGeometry x="320" y="160" width="80" height="80" as="geometry"/>
</mxCell>
```
**Cloud (serviço externo):**
```xml
<mxCell id="6" value="Cloudflare" style="shape=mxgraph.cisco.sites.generic_building;sketch=0;html=1;pointerEvents=1;dashed=0;fillColor=#036897;strokeColor=#ffffff;strokeWidth=2;verticalLabelPosition=bottom;verticalAlign=top;align=center;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="480" y="160" width="60" height="60" as="geometry"/>
</mxCell>
```
**Actor (pessoa/utilizador):**
```xml
<mxCell id="7" value="Utilizador" style="shape=mxgraph.flowchart.start_2;fillColor=#00BEF2;strokeColor=#006EAF;fontColor=#ffffff;fontStyle=1;fontSize=12;" vertex="1" parent="1">
<mxGeometry x="40" y="170" width="60" height="40" as="geometry"/>
</mxCell>
```
**Swimlane (grupo/camada):**
```xml
<mxCell id="8" value="Camada Frontend" style="swimlane;startSize=20;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="0" y="0" width="400" height="200" as="geometry"/>
</mxCell>
```
### Paleta de cores Descomplicar
| Componente | fillColor | strokeColor |
|-----------|-----------|-------------|
| Serviço/App | `#dae8fc` | `#6c8ebf` |
| Base de dados | `#f8cecc` | `#b85450` |
| Fila/Queue | `#d5e8d4` | `#82b366` |
| Externo/Cloud | `#fff2cc` | `#d6b656` |
| Infra/Servidor | `#e1d5e7` | `#9673a6` |
| Claude/IA | `#f0f4ff` | `#4a6cf7` |
### Guardar ficheiro
Guardar em `/media/ealmeida/Dados/Hub/tmp/diagramas/` com nome descritivo:
```
YYYY-MM-DD-nome-diagrama.drawio
```
Abrir com:
```bash
drawio "/media/ealmeida/Dados/Hub/tmp/diagramas/NOME.drawio" &
```
(ou abrir manualmente com draw.io desktop / draw.io no browser)
---
## Geração Excalidraw
Usar o MCP `mcp__claude_ai_Excalidraw__export_to_excalidraw` para diagramas no estilo whiteboard.
### Fluxo
1. Chamar `mcp__claude_ai_Excalidraw__create_view` para iniciar sessão
2. Chamar `mcp__claude_ai_Excalidraw__export_to_excalidraw` com o conteúdo estruturado
3. Informar o utilizador do link/path gerado
### Casos de uso preferidos
- Brainstorming e exploração rápida
- Diagramas de fluxo com estilo manual
- Esboços para reuniões
- Arquitecturas de alto nível para comunicação interna
---
## Geração Mermaid
Usar o MCP `mcp__mcp-mermaid__generate` para diagramas como código.
### Tipos suportados
**Fluxograma:**
```
flowchart TD
A[Início] --> B{Condição}
B -->|Sim| C[Acção]
B -->|Não| D[Fim]
```
**Sequência:**
```
sequenceDiagram
participant U as Utilizador
participant A as Claude Code
participant N as n8n
U->>A: Pedido
A->>N: Trigger workflow
N-->>A: Resultado
A-->>U: Resposta
```
**ER:**
```
erDiagram
CLIENTE ||--o{ PROJECTO : tem
PROJECTO ||--o{ TAREFA : contém
TAREFA {
int id
string nome
string estado
}
```
**Arquitectura de componentes (C4):**
```
C4Context
title Stack Descomplicar
Person(eal, "Emanuel", "Utilizador principal")
System(cc, "Claude Code", "Interface interactiva")
System(clip, "Paperclip", "Agentes autónomos")
System(n8n, "n8n", "Automação determinística")
Rel(eal, cc, "usa directamente")
Rel(cc, clip, "delega tarefas complexas")
Rel(cc, n8n, "activa workflows")
```
### Guardar output
Guardar o código Mermaid em `/media/ealmeida/Dados/Hub/tmp/diagramas/NOME.mmd` e renderizar para SVG/PNG via MCP.
---
## Templates prontos por contexto
### Arquitectura StackDescomplicar
Gerar diagrama com as três camadas do stack:
- **Camada 1:** Claude Code (trabalho interactivo)
- **Camada 2:** n8n (automação determinística)
- **Camada 3:** Paperclip (raciocínio autónomo)
### Proposta comercial
Diagrama da solução para o cliente com:
- Infra-estrutura actual (antes)
- Solução proposta (depois)
- Componentes e integrações
### Pipeline de dados
Diagrama de fluxo com:
- Fonte → Processamento → Destino
- Triggers, transformações, outputs
### Diagrama ER Desk CRM
Entidades principais: Lead → Customer → Estimate → Invoice → Payment
---
## Boas práticas
- **Máx. 10-15 elementos** por diagrama (mais → dividir em sub-diagramas)
- **Labels curtos:** 2-4 palavras por elemento
- **Setas com label** quando o fluxo não é óbvio
- **Cor consistente** por tipo de componente (seguir paleta Descomplicar)
- **Nome descritivo** no ficheiro (não "diagrama1.drawio")
- **Guardar em Hub/tmp/diagramas/** para fácil acesso
---
## Instalar draw.io MCP (opcional, para funcionalidades avançadas)
O vídeo #210 do Stack_Pesquisa_Videos.md demonstra um MCP draw.io com geração automática a partir de análise de código. Para instalar:
```bash
# Verificar se há MCP draw.io disponível no gateway
# Ver: Hub/04-Stack/claude-code-context-hygiene.md → secção MCPs
```
Alternativa: usar draw.io via browser em https://app.diagrams.net (gratuito, sem instalação) e importar o `.drawio` gerado.
---
## 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.*
+159
View File
@@ -0,0 +1,159 @@
---
name: docx
description: "Criação, edição e análise de documentos Word (.docx). Versão light para heartbeats."
---
# DOCX — Referência Rápida
## Referência rápida
| Tarefa | Abordagem |
|--------|-----------|
| Ler conteúdo | `pandoc` ou descompactar XML |
| Criar novo | `docx-js` (npm install -g docx) |
| Editar existente | Descompactar → editar XML → recompactar |
| Converter .doc | `python scripts/office/soffice.py --headless --convert-to docx doc.doc` |
## Criar novos documentos (docx-js)
### Setup básico
```javascript
const { Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell, ImageRun,
Header, Footer, AlignmentType, PageOrientation, LevelFormat, HeadingLevel,
BorderStyle, WidthType, ShadingType, PageNumber, PageBreak } = require('docx');
const doc = new Document({ sections: [{ children: [/* conteúdo */] }] });
Packer.toBuffer(doc).then(buffer => fs.writeFileSync("doc.docx", buffer));
```
### Tamanho de página (A4)
```javascript
sections: [{
properties: {
page: {
size: { width: 11906, height: 16838 }, // A4 em DXA
margin: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
}
},
children: [/* conteúdo */]
}]
```
Largura de conteúdo A4 com margens 1": `11906 - 2880 = 9026 DXA`
**Paisagem:** Passar dimensões retrato + `orientation: PageOrientation.LANDSCAPE` (docx-js troca internamente).
### Listas
```javascript
numbering: { config: [
{ reference: "bullets", levels: [{ level: 0, format: LevelFormat.BULLET, text: "\u2022",
alignment: AlignmentType.LEFT, style: { paragraph: { indent: { left: 720, hanging: 360 } } } }] }
] }
// Usar: new Paragraph({ numbering: { reference: "bullets", level: 0 }, children: [...] })
```
### Tabelas
```javascript
// Largura tabela = soma columnWidths. Usar SEMPRE WidthType.DXA (nunca PERCENTAGE).
new Table({
width: { size: 9026, type: WidthType.DXA },
columnWidths: [4513, 4513],
rows: [new TableRow({ children: [
new TableCell({
borders: { top: b, bottom: b, left: b, right: b },
width: { size: 4513, type: WidthType.DXA },
shading: { fill: "D5E8F0", type: ShadingType.CLEAR }, // CLEAR, nunca SOLID
margins: { top: 80, bottom: 80, left: 120, right: 120 },
children: [new Paragraph({ children: [new TextRun("Célula")] })]
})
] })]
})
```
### Imagens
```javascript
new ImageRun({
type: "png", // Obrigatório
data: fs.readFileSync("image.png"),
transformation: { width: 200, height: 150 },
altText: { title: "T", description: "D", name: "N" } // Três obrigatórios
})
```
### Cabeçalhos/rodapés
```javascript
headers: { default: new Header({ children: [new Paragraph({ children: [new TextRun("Cabeçalho")] })] }) },
footers: { default: new Footer({ children: [new Paragraph({
children: [new TextRun("Página "), new TextRun({ children: [PageNumber.CURRENT] })]
})] }) }
```
### Regras críticas docx-js
- Nunca usar `\n` — usar Paragraphs separados
- Nunca usar bullets unicode — usar `LevelFormat.BULLET`
- PageBreak dentro de Paragraph: `new Paragraph({ children: [new PageBreak()] })`
- ImageRun requer `type`
- Tabelas: `columnWidths` E `width` na célula, ambos devem corresponder
- Usar `ShadingType.CLEAR`, nunca SOLID
- TOC requer `HeadingLevel` apenas, sem estilos custom
- Override estilos: IDs exactos "Heading1", "Heading2" + `outlineLevel`
## Editar documentos existentes
### Passo 1: Descompactar
```bash
python scripts/office/unpack.py document.docx unpacked/
```
### Passo 2: Editar XML
Editar ficheiros em `unpacked/word/`. Usar ferramenta Edit directamente (não scripts Python).
**Tracked changes:**
```xml
<!-- Inserção -->
<w:ins w:id="1" w:author="Claude" w:date="2025-01-01T00:00:00Z">
<w:r><w:t>texto inserido</w:t></w:r>
</w:ins>
<!-- Eliminação -->
<w:del w:id="2" w:author="Claude" w:date="2025-01-01T00:00:00Z">
<w:r><w:delText>texto eliminado</w:delText></w:r>
</w:del>
```
**Comentários:**
```bash
python scripts/comment.py unpacked/ 0 "Texto do comentário"
python scripts/comment.py unpacked/ 1 "Resposta" --parent 0
```
**Smart quotes:** `&#x2018;` `&#x2019;` `&#x201C;` `&#x201D;`
### Passo 3: Recompactar
```bash
python scripts/office/pack.py unpacked/ output.docx --original document.docx
```
Validação: `python scripts/office/validate.py doc.docx`
## Convenções Descomplicar
- Data: DD-MM-YYYY
- Monetário: 1.234,56 EUR
- Fonte: Arial 12pt
- Página: A4 (11906 x 16838 DXA)
- Autor tracked changes: "Claude"
- Idioma: PT-PT
---
**Versão**: 1.0.0-light | **Base**: 1.0.0
+12
View File
@@ -510,3 +510,15 @@ Apos executar `comment.py` (ver Passo 2), adicionar marcadores ao document.xml.
---
**Versao**: 1.0.0 | **Autor**: Descomplicar®
---
## 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.*
+12
View File
@@ -218,3 +218,15 @@ CMD ["npm", "start"]
---
*Versão 1.0.0 | Descomplicar®*
---
## 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.*
+160
View File
@@ -0,0 +1,160 @@
---
name: pdf
description: Processamento de ficheiros PDF — leitura, extracção, merge, split, OCR, formulários. Versão light para heartbeats.
---
# PDF — Referência Rápida
## Bibliotecas Python
### pypdf — operações básicas
```python
from pypdf import PdfReader, PdfWriter
# Ler e extrair texto
reader = PdfReader("documento.pdf")
for page in reader.pages:
text = page.extract_text()
# Merge
writer = PdfWriter()
for pdf in ["doc1.pdf", "doc2.pdf"]:
for page in PdfReader(pdf).pages:
writer.add_page(page)
with open("merged.pdf", "wb") as f:
writer.write(f)
# Split (uma página por ficheiro)
for i, page in enumerate(reader.pages):
w = PdfWriter()
w.add_page(page)
with open(f"page_{i+1}.pdf", "wb") as f:
w.write(f)
# Rotate
page = reader.pages[0]
page.rotate(90)
# Password
writer.encrypt("userpass", "ownerpass")
```
### pdfplumber — tabelas e texto com layout
```python
import pdfplumber
with pdfplumber.open("doc.pdf") as pdf:
for page in pdf.pages:
text = page.extract_text()
tables = page.extract_tables()
```
### reportlab — criação de PDFs
```python
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table, TableStyle, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
doc = SimpleDocTemplate("report.pdf")
styles = getSampleStyleSheet()
elements = [Paragraph("Título", styles['Title'])]
doc.build(elements)
```
**Subscripts/superscripts:** Nunca usar caracteres Unicode. Usar tags XML: `<sub>2</sub>`, `<super>2</super>`.
## CLI
```bash
# Extrair texto (poppler-utils)
pdftotext input.pdf output.txt
pdftotext -layout input.pdf output.txt
# Merge/split (qpdf)
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
# Encriptar
qpdf --encrypt user_pass owner_pass 256 -- input.pdf encrypted.pdf
# Reparar
qpdf --check input.pdf
# Extrair imagens
pdfimages -j input.pdf output_prefix
# Render para PNG
pdftoppm -png -r 300 document.pdf output_prefix
```
## OCR (PDFs digitalizados)
```python
import pytesseract
from pdf2image import convert_from_path
images = convert_from_path('scanned.pdf')
text = ""
for image in images:
text += pytesseract.image_to_string(image)
```
## Formulários
### Verificar campos preenchíveis
```bash
python scripts/check_fillable_fields.py <file.pdf>
```
### Campos preenchíveis (nativos)
1. `python scripts/extract_form_field_info.py <input.pdf> <field_info.json>`
2. `python scripts/convert_pdf_to_images.py <file.pdf> <output_dir>`
3. Criar `field_values.json` com `field_id`, `page`, `value`
4. `python scripts/fill_fillable_fields.py <input.pdf> <field_values.json> <output.pdf>`
### Campos não preenchíveis (anotações)
1. `python scripts/extract_form_structure.py <input.pdf> form_structure.json`
2. **Abordagem A (estrutura):** Analisar JSON, criar `fields.json` com `pdf_width`/`pdf_height` e bounding boxes
3. **Abordagem B (visual):** Converter para imagens, identificar campos, refinar com crop
4. `python scripts/check_bounding_boxes.py fields.json`
5. `python scripts/fill_pdf_form_with_annotations.py <input.pdf> fields.json <output.pdf>`
6. `python scripts/create_validation_image.py <page> <fields.json> <input_img> <output_img>`
## Referência rápida
| Tarefa | Ferramenta | Comando |
|--------|-----------|---------|
| Merge | pypdf/qpdf | `writer.add_page()` / `qpdf --pages` |
| Split | pypdf/qpdf | Uma página por ficheiro |
| Texto | pdfplumber | `page.extract_text()` |
| Tabelas | pdfplumber | `page.extract_tables()` |
| Criar | reportlab | Canvas ou Platypus |
| OCR | pytesseract | Converter para imagem primeiro |
| Formulários | pypdf/scripts | Ver secção acima |
## Caminhos Descomplicar
| Local | Caminho |
|-------|---------|
| Documentos empresa | `/media/ealmeida/Dados/GDrive/Cloud/Descomplicar/` |
| Propostas | `/media/ealmeida/Dados/Hub/03-Propostas/` |
| Arquivo clientes | `/media/ealmeida/Dados/GDrive/Arquivo_de_Clientes/` |
| Knowledge Base | `/media/ealmeida/Dados/Hub/06-Operacoes/Knowledge-Base/PDFs/` |
| Temporários | `~/.claude-work/` (limpar ao concluir) |
## Workflow
1. Localizar PDF (filesystem ou Google Drive)
2. Descarregar para `~/.claude-work/` se necessário
3. Processar
4. Guardar no destino final
5. Limpar temporários
---
**Versão**: 1.0.0-light | **Base**: 1.0.0
+12
View File
@@ -794,3 +794,15 @@ def extract_text_with_ocr(pdf_path):
---
**Versao**: 1.0.0 | **Autor**: Descomplicar®
---
## 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.*
+12
View File
@@ -392,3 +392,15 @@ mcp__dify-kb__dify_kb_retrieve_segments({
---
**Versão**: 1.0.0 | **Autor**: Descomplicar®
---
## 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.*
+144
View File
@@ -0,0 +1,144 @@
---
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
---
## 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.*
+12
View File
@@ -189,3 +189,15 @@ hooks/
- `references/composition-patterns.md` - Compound components, providers, dependency injection (Vercel Engineering)
- `references/custom-hooks.md` - useDebounce, useLocalStorage, useFetch com codigo completo
---
## 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.*
+12
View File
@@ -186,3 +186,15 @@ description: >
Ver `references/anthropic-patterns.md` para exemplos detalhados de progressive disclosure.
Ver `references/descomplicar-standards.md` para exemplos de skills Descomplicar bem estruturadas.
---
## 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.*
+12
View File
@@ -144,3 +144,15 @@ No servidor dev, Playwright ja esta disponivel em `/root/Dev`.
---
**Versao**: 1.0.0 | **Autor**: Descomplicar®
---
## 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.*
+12
View File
@@ -372,3 +372,15 @@ O ficheiro de referencia de precos esta em:
---
**Versao**: 1.0.0 | **Autor**: Descomplicar®
---
## 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.*
+154
View File
@@ -0,0 +1,154 @@
---
name: youtube-extract
category: dev-tools
description: "Extrai transcrições e metadados de vídeos, playlists e canais YouTube para o ficheiro de pesquisa Stack_Pesquisa_Videos.md. Usar quando 'youtube', 'vídeo', 'playlist', 'canal', 'transcrição', 'extrair vídeo', 'pesquisa vídeos'."
version: "1.0.0"
created: 2026-04-04
tools: [Bash]
---
# Skill: /youtube-extract
Extrai transcrições e metadados de vídeos, playlists e canais YouTube usando o script `youtube-pesquisa-videos.py`. Adiciona automaticamente ao ficheiro de pesquisa do StackDescomplicar.
---
## Ficheiros relevantes
| Ficheiro | Caminho |
|----------|---------|
| **Script** | `/media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py` |
| **Destino padrão** | `/media/ealmeida/Dados/Hub/04-Stack/Stack_Pesquisa_Videos.md` |
---
## Processo de execução
### 1. Identificar o pedido
Detectar na mensagem do utilizador:
- **URLs** — vídeos individuais, playlists (`?list=`), canais (`@canal`, `/c/`, `/channel/`)
- **Limite** — "primeiros 10", "máx 5", etc. → usar `--max N`
- **Destino** — ficheiro alternativo? → usar `--output caminho`
- **Modo** — adicionar ao ficheiro (`--append`) vs mostrar no terminal (sem flag)
### 2. Construir o comando
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
URL1 URL2 ... \
[--max N] \
[--append] \
[--output /caminho/alternativo.md] \
[--file lista.txt]
```
### 3. Exemplos por tipo de URL
**Vídeo individual:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtu.be/dQw4w9WgXcQ" --append
```
**Playlist completa:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtube.com/playlist?list=PLxxx" --append
```
**Playlist com limite:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtube.com/playlist?list=PLxxx" --max 10 --append
```
**Canal completo (máx. 20):**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtube.com/@NomeCanal" --max 20 --append
```
**Mix de URLs:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtu.be/ID1" \
"https://youtube.com/playlist?list=PLxxx" \
--max 5 --append
```
**Ficheiro de lista:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
--file /caminho/lista.txt --append
```
**Pré-visualizar sem gravar:**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtu.be/ID1"
```
---
## Comportamento padrão
| Situação | Acção |
|----------|-------|
| URL única de vídeo | Extrair e perguntar se adiciona ao ficheiro |
| Múltiplos vídeos | Extrair todos e adicionar com `--append` |
| Playlist/canal sem limite | Alertar o utilizador — perguntar limite antes de executar |
| Ficheiro de destino não especificado | Usar `Stack_Pesquisa_Videos.md` |
> **Aviso obrigatório para playlists/canais sem `--max`:** Informar o utilizador do número de vídeos antes de processar — canais podem ter centenas.
---
## Após a extracção
1. Informar quantos vídeos foram adicionados e os números `#N` atribuídos
2. Sugerir ao utilizador que complete os campos `*(a completar)*` no ficheiro
3. Se houver erros (transcrição indisponível), mencionar quais os vídeos afectados
4. Opcional: abrir o ficheiro no editor — `xdg-open "Stack_Pesquisa_Videos.md"`
---
## Pré-requisitos
- `yt-dlp` instalado: `pip install yt-dlp` ou `brew install yt-dlp`
- Python 3.8+
- Acesso à internet
Verificar disponibilidade:
```bash
yt-dlp --version && python3 --version
```
---
## Casos especiais
**ID curto do YouTube (11 chars):**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py dQw4w9WgXcQ --append
```
**Destino alternativo (outro projecto):**
```bash
python3 /media/ealmeida/Dados/Dev/ClaudeDev/youtube-pesquisa-videos.py \
"https://youtu.be/ID1" \
--output "/media/ealmeida/Dados/Hub/05-Projectos/MeuProjecto/videos.md" \
--append
```
---
## 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.*
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "gestao",
"description": "Project management, time tracking, daily checkups, worklogs, reflections, knowledge management, archiving and compliance auditing. Backed by NotebookLM notebooks.",
"version": "1.3.0",
"version": "1.4.0",
"author": {
"name": "Descomplicar - Crescimento Digital",
"url": "https://descomplicar.pt"
+30
View File
@@ -0,0 +1,30 @@
# Changelog — Plugin gestao
Todas as alterações relevantes a este plugin. Segue [Semantic Versioning](https://semver.org/).
---
## [1.4.0] — 2026-04-07
### Adicionado
- **Nova skill `/clip-instructions`** — gerir AGENTS.md de agentes Paperclip por nome: ver, editar, criar, rever histórico de versões e rollback via API config revisions
### Corrigido
- **`/clip-health`** — check 1 reescrito: `systemctl` substituído por `ps aux` (Paperclip não usa systemd); check 6 reescrito: `npx paperclipai doctor` substituído por `curl http://localhost:3100/health`; adicionado check de memória partilhada POSIX (`/dev/shm/PostgreSQL.*`) — causa raiz do bug pós-reboot; score actualizado 21→22; 2 entradas no Healing Log
- **`/clip-agent`** — curl de atribuição de skills corrigido: adicionado `-H "Authorization: Bearer $PAPERCLIP_API_KEY"` (sem header dava 401); documentadas notas sobre agentes analyst (`process` adapter, `claude-sonnet-4-6`, heartbeat desactivado); checklist "Criar agente novo" actualizada com `instructionsBundleMode: "external"`, `instructionsRootPath`, `instructionsEntryFile`; 3 entradas no Healing Log
- **`/clip-issue`** — `author_user_id` corrigido: `'board'``'v1N5OccPn9DGq6iog7qW9nEvnXYFT3iO'` (ID real de Emanuel); adicionado modo checkout/release com endpoints API e fallback SQL; entrada no Healing Log
- **`/clip-skill`** — modelo mental corrigido: "ephemeral/symlinks" → "injecção de contexto em runtime a cada heartbeat"; adicionado `-H "Authorization: Bearer $PAPERCLIP_API_KEY"` aos dois curls de API (`/skills/import` e `/skills/sync`); nota sobre adapter `process` para agentes analyst; entrada no Healing Log
### Notas técnicas
- Todas as correcções baseadas em aprendizagens dos vídeos Paperclip (sessão 07-04-2026)
- Chave de autenticação Paperclip: `Authorization: Bearer $PAPERCLIP_API_KEY` obrigatória em todos os endpoints da API local
- Agentes criados via SQL directamente (fora do fluxo OpenClaw) **não** recebem `company_memberships` automaticamente — inserção manual obrigatória
---
## [1.3.0] — anterior
- Versão base (sem changelog registado)
+1 -1
View File
@@ -4,7 +4,7 @@ description: Auto-reflexão e melhoria contínua do sistema. Analisa sessões, i
padrões, sugere optimizações. Auto-trigger >20 tool calls.
role: Auto-reflexão e melhoria contínua do sistema
domain: Dev
model: sonnet
model: haiku
tools: Read, Write, Edit, Glob, ToolSearch
# Dependencies
+12
View File
@@ -132,3 +132,15 @@ exit $EXIT_CODE
---
*Skill v1.0.0 | 04-03-2026 | Descomplicar®*
---
## 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.*
+12
View File
@@ -221,3 +221,15 @@ Output: [resultado esperado]
Input: [caso complexo]
Output: [resultado detalhado]
```
---
## 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.*
+12
View File
@@ -175,3 +175,15 @@ mcp__google_workspace__create_event({
- **Workflows detalhados:** `references/workflows-detalhados.md`
- **MCP tools e constantes:** `references/mcp-tools-referencia.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.*
+12 -1
View File
@@ -1,7 +1,6 @@
---
name: cleanup-downloads
description: Limpeza e triagem da pasta Transferências (Downloads). Verifica cada ficheiro individualmente, apaga descartáveis, classifica o restante por categoria. Usar quando "transferências", "downloads", "limpar downloads", "cleanup", "limpeza pasta".
disable-model-invocation: true
---
# Cleanup Downloads
@@ -105,3 +104,15 @@ Após mover documentos financeiros (regra 3), lançar despesas via `/expense`:
## Integração /today
Incluir contagem de ficheiros na pasta quando >10 ficheiros.
---
## 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.*
+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_without_skip_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.*
+13 -1
View File
@@ -1,6 +1,6 @@
---
name: daily-digest
description: Resumo diário do estado operacional - timer activo, tickets abertos, facturas vencidas, leads novos, propostas pendentes e agenda do dia. Usar quando "resumo", "digest", "estado do dia", "dashboard", "métricas dia".
description: Sub-rotina chamada por /today para snapshot CRM (timer activo, tickets, facturas vencidas, leads, propostas, agenda). Pode ser invocada isoladamente quando só precisas dos números CRM sem o checkup completo. Usar quando "resumo", "digest", "estado do dia", "métricas dia". Para dashboard diário completo usar /today.
context: fork
---
@@ -122,3 +122,15 @@ Gerar alertas se:
---
*Skill v1.0.0 | 04-03-2026 | Descomplicar®*
---
## 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.*
+124
View File
@@ -0,0 +1,124 @@
---
name: deep-research
description: >
Pesquisa profunda em 3 layers: Hub Obsidian (Layer 1) + NotebookLM análise (Layer 2) +
Web externo (Layer 3). Para questões complexas que requerem síntese de múltiplas fontes.
Usar quando: análise competitiva profunda, pesquisa mercado, due diligence, relatório estratégico.
---
# /deep-research — Pesquisa Profunda com RAG Trinity
Pesquisa em 3 camadas com síntese final. Mais profundo que `/research`, mais estruturado que `/hub-search`.
---
## Quando Usar
| Situação | Skill Correcta |
|---------|----------------|
| "Onde está X no Hub?" | `/hub-search` |
| "Analisa este documento" | `/research` |
| "Pesquisa profunda + síntese de múltiplas fontes" | `/deep-research` ← este |
| "Análise competitiva completa" | `/deep-research` + `/research competitive` |
---
## Protocolo (3 Layers)
### Layer 1 — Hub Obsidian (conhecimento interno)
```bash
# 1a. Busca full-text no Hub
obsidian search query="<TERMO>" format=json limit=10
# 1b. Se Obsidian não responde (offline), fallback via Grep
grep -r "<TERMO>" /media/ealmeida/Dados/Hub/ --include="*.md" -l | head -20
```
**Critério de suficiência Layer 1:** Encontrou 3+ documentos relevantes com contexto concreto.
- SE suficiente para questão simples → responder + registar fonte
- SE questão requer análise profunda → continuar para Layer 2
### Layer 2 — NotebookLM (análise profunda)
Seleccionar notebook relevante com base no domínio:
| Domínio | Notebook ID |
|---------|-------------|
| Estratégia e Empreendedorismo | 79d43410-0e29-4be1-881d-84db6bdc239a |
| Stack Tecnológico | [consultar mcp__notebooklm__ lista] |
| Marketing e Vendas | [consultar mcp__notebooklm__ lista] |
```javascript
// Consultar notebook relevante
mcp__notebooklm__notebook_query({
notebook_id: "<ID>",
query: "<QUESTÃO ESPECÍFICA — mais precisa que a geral>"
})
```
**Critério de suficiência Layer 2:** NotebookLM retornou análise com citações específicas.
- SE suficiente → sintetizar com Layer 1 + responder
- SE requer dados externos → continuar para Layer 3
### Layer 3 — Web (conhecimento externo)
```javascript
// Web search para dados actuais
mcp__web-search__search({
query: "<QUESTÃO> site:scholar.google.com OR filetype:pdf",
num_results: 10
})
```
---
## Síntese Final
Após recolher de 2+ layers, sintetizar:
```markdown
## Síntese — [Tópico]
**Fontes consultadas:** Layer 1 (Hub), Layer 2 (NotebookLM [Notebook X]), Layer 3 (Web)
### O que sabemos (interno)
[Resumo Layer 1 — conhecimento já documentado]
### Análise profunda
[Resumo Layer 2 — análise NotebookLM com citações]
### Contexto externo
[Resumo Layer 3 — se consultado]
### Síntese e Recomendação
[Cruzamento das layers — resposta directa à questão]
### Próximos Passos
- [ ] Acção 1 derivada da pesquisa
- [ ] Acção 2
```
---
## Self-Improving Loop
Após cada execução, registar preferências para melhorar futuras pesquisas:
```bash
# Guardar aprendizagem em Hub
echo "$(date '+%Y-%m-%d') — deep-research — [TÓPICO] — [O QUE FUNCIONOU/NÃO FUNCIONOU]" \
>> /media/ealmeida/Dados/Hub/00-Inbox/research-preferences.md
```
---
## Healing Log
```jsonl
{"date":"","issue":"","fix":"","source":"user|auto"}
```
---
*Skill /deep-research v1.1.0 | 13-04-2026 | LightRAG removido — Layer 3 passa a Web apenas*
+12
View File
@@ -339,3 +339,15 @@ Output: [resultado esperado]
Input: [caso complexo]
Output: [resultado detalhado]
```
---
## 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.*
+12
View File
@@ -440,3 +440,15 @@ Após concluir o documento:
---
**Versão**: 1.0.0 | **Data**: 2026-03-06 | **Autor**: Descomplicar®
---
## 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®*
+137
View File
@@ -0,0 +1,137 @@
---
name: hub-search
description: >
Pesquisa no vault Hub Obsidian com relevance scoring e backlinks.
Layer 1 da arquitectura de pesquisa (CLI → NotebookLM).
Usar quando: (1) pesquisar conteúdo no Hub por termo ou conceito,
(2) encontrar notas relacionadas via backlinks, (3) localizar PROCs/QR/docs
antes de executar tarefas, (4) verificar se existe documentação antes de criar.
---
# /hub-search — Pesquisa no Hub (Layer 1 RAG)
Pesquisa rápida no vault Hub via Obsidian CLI. Requer Obsidian aberto.
Fallback automático para Grep se Obsidian não estiver a correr.
---
## Uso
```
/hub-search "termo"
/hub-search "LightRAG configuração" --backlinks
/hub-search "PROC-MCP" --files
```
---
## Workflow
### Passo 1 — Tentar via Obsidian CLI
```bash
# Pesquisa básica
obsidian search query="TERMO" format=json
# Com backlinks (recomendado para conceitos)
obsidian search query="TERMO" format=json
obsidian backlinks file="NOTA"
# Limitar resultados
obsidian search query="TERMO" limit=10 format=json
```
**Indicador de sucesso:** saída JSON com `results` array.
**Indicador de falha:** mensagem `unable to find Obsidian` → ir para fallback.
### Passo 2 — Fallback: Grep no Hub
Se CLI falhar (Obsidian fechado):
```
Grep "TERMO" /media/ealmeida/Dados/Hub/ --type md
```
Adicionar contexto ao utilizador: "Obsidian não está a correr — usando busca directa nos ficheiros."
### Passo 3 — Apresentar resultados
**Formato de output:**
```markdown
## Resultados: "[termo]"
**Fonte:** Obsidian CLI v1.12.7 | **Backlinks:** Sim/Não
### Encontrado em N notas
| Nota | Path | Relevância |
|------|------|-----------|
| [título] | `path/relativo.md` | Alta/Média/Baixa |
### Notas com backlinks para este termo
- `nota-a.md` → referencia `nota-b.md`
### Relacionados sugeridos
- [links relevantes encontrados nos resultados]
```
---
## Regras
1. **Sempre tentar CLI primeiro** — é mais preciso (scoring semântico)
2. **--include-backlinks por defeito** quando o termo é um conceito (não um comando)
3. **Fallback silencioso** — não perguntar, só mencionar que usou Grep
4. **Max 10 resultados** — se mais, mostrar top 10 por relevância
5. **Paths relativos** na apresentação (ex: `04-Stack/02.03-IA/` não path absoluto)
---
## Integração com outras skills
```
/hub-search "termo" → Layer 1: Obsidian CLI (este skill)
/knowledge "termo" → Layer 2: NotebookLM (65 notebooks)
```
**Quando escalar para Layer 2:**
- Resultado CLI score < 50% ou 0 resultados → sugerir `/knowledge`
- Conteúdo conceptual/externo → sugerir `/knowledge` directamente
---
## Referência CLI
```bash
# Sintaxe correcta: parâmetros com = (não flags com --)
obsidian search query="TERMO" format=json
obsidian search query="TERMO" limit=10 format=json
obsidian backlinks file="NOTA"
obsidian tags sort=count counts
obsidian tasks daily todo
obsidian version
obsidian help # lista todos os comandos disponíveis
```
**Nota:** A skill oficial kepano (`obsidian-cli`) tem referência completa de todos os comandos.
**Requer:** Obsidian aberto + CLI activado em Settings → General → Advanced
**Wrapper:** `~/.local/bin/obsidian` (define XDG_RUNTIME_DIR Flatpak)
**Docs:** `04-Stack/02.03-IA/Obsidian-CLI.md`
---
*Skill v1.0.0 | 06-04-2026 | Descomplicar®*
---
## 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.*
+12
View File
@@ -234,3 +234,15 @@ Quando invocado directamente (sem /today):
---
*Skill v1.0.0 | 04-03-2026 | Descomplicar®*
---
## 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.*

Some files were not shown because too many files have changed in this diff Show More