docs: skill mcp-happyfiles — MCP HappyFiles Pro (pastas media library)
Documenta a taxonomia happyfiles_category (hierárquica, attachments), o gotcha include_children=true por omissão no WP_Query (corrigido no MCP), query_var=false na taxonomia (wp post list --happyfiles_category não funciona), e confirma no código-fonte que apagar pasta nunca apaga ficheiros. 9 tools, verificação ponta-a-ponta contra descomplicar.pt (produção) e starter.descomplicar.pt documentada.
This commit is contained in:
@@ -0,0 +1,108 @@
|
|||||||
|
---
|
||||||
|
name: mcp-happyfiles
|
||||||
|
description: MCP dedicado multi-site (node stdio, ligação `happyfiles` em ~/.omp/agent/mcp.json) para gerir as pastas da media library organizadas pelo HappyFiles Pro em qualquer site do bundle Descomplicar® onde o plugin esteja activo — listar pastas com contagem e hierarquia, criar/renomear/apagar pastas, listar ficheiros de uma pasta ou sem pasta, mover ficheiros entre pastas. Apagar uma pasta NUNCA apaga ficheiros. Site é um parâmetro em cada tool, não uma ligação fixa. Usar quando "happyfiles mcp", "pastas media library", "organizar biblioteca de media", "mover ficheiros de pasta wordpress", "criar pasta happyfiles", "apagar pasta happyfiles", "ficheiros sem pasta", "uncategorized happyfiles".
|
||||||
|
layer: wiki
|
||||||
|
---
|
||||||
|
|
||||||
|
# /mcp-happyfiles — MCP dedicado multi-site ao HappyFiles Pro
|
||||||
|
|
||||||
|
Projecto em `/media/ealmeida/Dados/Dev/mcp-happyfiles/` (TypeScript, SDK MCP oficial, stdio). Sem
|
||||||
|
código PHP novo no WordPress — cada tool corre `wp eval` via `ssh server` sobre a **API nativa de
|
||||||
|
taxonomias do WordPress** (`get_terms`, `wp_insert_term`, `wp_update_term`, `wp_delete_term`,
|
||||||
|
`wp_set_object_terms`, `wp_delete_object_term_relationships`), nunca SQL directo. `site` é um
|
||||||
|
parâmetro em cada tool, não uma ligação fixa por site.
|
||||||
|
|
||||||
|
## Arquitectura de dados (confirmada no código-fonte do plugin em 19-08-2026)
|
||||||
|
|
||||||
|
O HappyFiles Pro **não tem tabelas próprias** para pastas de media library. Cada "pasta" é um termo
|
||||||
|
da taxonomia custom `happyfiles_category` (constante `HAPPYFILES_TAXONOMY`), registada só para o
|
||||||
|
post type `attachment`, **hierárquica** (usa `parent`/`term_id` nativos do WordPress). Cada
|
||||||
|
ficheiro (attachment) pertence a uma pasta através de uma relação normal
|
||||||
|
`wp_term_relationships` — exactamente como categorias/tags em posts.
|
||||||
|
|
||||||
|
- **Contagem de ficheiros por pasta** = `WP_Term->count`, mantida automaticamente pelo WordPress via
|
||||||
|
`_update_generic_term_count` (callback registado pelo próprio plugin) sempre que
|
||||||
|
`wp_set_object_terms`/`wp_delete_term` corre. Nunca precisa de ser recalculada manualmente.
|
||||||
|
- **Metadados extra por pasta** (termmeta, opcionais): `happyfiles_position` (inteiro, ordenação
|
||||||
|
manual na UI) e `happyfiles_folder_color` (cor custom). Ambos ausentes por omissão.
|
||||||
|
- **"Sem pasta" (Uncategorized)** não é um termo real — é `tax_query` com `operator => NOT EXISTS`
|
||||||
|
sobre `happyfiles_category`. O próprio `Data::get_folders()` do plugin usa a convenção
|
||||||
|
`term_id = -1` para esta pseudo-pasta e `-2` para "Todos os ficheiros"; este MCP replica a mesma
|
||||||
|
convenção internamente (`folderId: -1` nas tools de listagem de ficheiros).
|
||||||
|
- **Gotcha WP_Query confirmado ao vivo:** `tax_query` por omissão tem `include_children => true`
|
||||||
|
(taxonomia hierárquica) — listar ficheiros de uma pasta-pai sem `include_children: false` devolve
|
||||||
|
também os ficheiros de todas as subpastas (reproduzido: pasta "Clientes" mostrava 120 ficheiros em
|
||||||
|
vez dos 7 directamente associados). Este MCP força sempre `include_children => false`, replicando
|
||||||
|
o mesmo padrão que o próprio `Actions::delete_folder()` do plugin usa para não apagar relações de
|
||||||
|
subpastas por engano.
|
||||||
|
- **`query_var` da taxonomia é `false`** (`public => false` na chamada `register_taxonomy`, confirmado
|
||||||
|
via `get_taxonomy('happyfiles_category')->query_var`) — `wp post list --happyfiles_category=X`
|
||||||
|
**não funciona**, nem via WP-CLI nem em pedidos normais; o próprio plugin nunca depende disto,
|
||||||
|
constrói sempre `tax_query` explícito em PHP. Por isso este MCP também nunca usa esse atalho.
|
||||||
|
- **Apagar pasta nunca apaga ficheiros:** `Actions::delete_folder()` (e o `wp_delete_term()` nativo
|
||||||
|
que ele chama) só remove a linha da taxonomia e as relações `wp_term_relationships` — os posts
|
||||||
|
`attachment` continuam a existir, só passam a "Sem pasta". Confirmado no código-fonte
|
||||||
|
(`includes/actions.php`) e testado ao vivo neste MCP (ver secção Verificação).
|
||||||
|
- **Uma pasta por ficheiro por omissão:** `wp_set_object_terms($id, [$folderId], $taxonomy, false)`
|
||||||
|
com `append=false` **substitui** a pasta anterior — é o comportamento por omissão do HappyFiles
|
||||||
|
Pro (`happyfiles_multiple_folders` = false). Este MCP replica exactamente essa semântica em
|
||||||
|
`happyfiles_move_files`.
|
||||||
|
|
||||||
|
## Sites conhecidos
|
||||||
|
|
||||||
|
Chamar `happyfiles_list_sites` para a lista actual. Confirmados HappyFiles Pro 1.8.3 activo ao vivo
|
||||||
|
em 19-08-2026: `descomplicar` (produção, `/home/ealmeida/public_html` — 66 pastas reais em uso,
|
||||||
|
1218 attachments, 893 sem pasta), `emanuelalmeida` (`emanuelalmeida.pt`), `starter`
|
||||||
|
(`starter.descomplicar.pt`). Também aceita um path absoluto directamente
|
||||||
|
(`/home/ealmeida/<site>`) para sites fora desta lista, sem exigir rebuild do MCP.
|
||||||
|
|
||||||
|
## Tools (9)
|
||||||
|
|
||||||
|
| Tool | Read-only | Uso |
|
||||||
|
|---|---|---|
|
||||||
|
| `happyfiles_list_sites` | sim | Aliases conhecidos, path WP, nota de estado |
|
||||||
|
| `happyfiles_get_status` | sim | Plugin instalado/activo + versão |
|
||||||
|
| `happyfiles_list_folders` | sim | Todas as pastas: id, nome, slug, `parent`, `count`, `position`, `color`, mais `all_files_count`/`uncategorized_count` |
|
||||||
|
| `happyfiles_create_folder` | não | Nova pasta, `parentId` opcional para subpasta |
|
||||||
|
| `happyfiles_rename_folder` | não | Novo nome + slug recalculado |
|
||||||
|
| `happyfiles_delete_folder` | não | **Nunca apaga ficheiros.** `deleteSubfolders:true` apaga em cascata; por omissão as subpastas sobem para o pai (comportamento nativo `wp_delete_term`) |
|
||||||
|
| `happyfiles_list_files_in_folder` | sim | Ficheiros **directamente** numa pasta (não inclui subpastas), paginado |
|
||||||
|
| `happyfiles_list_uncategorized_files` | sim | Ficheiros sem nenhuma pasta atribuída, paginado |
|
||||||
|
| `happyfiles_move_files` | não | 1+ ficheiros para uma pasta (substitui a pasta anterior) ou `folderId: null` para desassociar (Sem pasta) |
|
||||||
|
|
||||||
|
Todas as tools exigem `site` como primeiro parâmetro.
|
||||||
|
|
||||||
|
## Segurança
|
||||||
|
|
||||||
|
Nenhuma escrita usa SQL directo nem classes internas do plugin (não são autoload-seguras fora do
|
||||||
|
wp-admin) — só as funções nativas de taxonomia do WordPress, as mesmas que os handlers AJAX do
|
||||||
|
próprio HappyFiles Pro chamam (`includes/actions.php`, `includes/ajax.php`), pelo que os hooks
|
||||||
|
(`created_term`, `edited_term`, `delete_term`, `set_object_terms`) disparam sempre. O corpo PHP
|
||||||
|
corrido por `wp eval` é sempre um template estático sem texto do utilizador interpolado; nomes de
|
||||||
|
pasta e IDs de ficheiros viajam em JSON codificado em base64 pelo **STDIN** do processo remoto
|
||||||
|
(`php://stdin` dentro do PHP, `stream_get_contents(STDIN)`), nunca na linha de comando — evita por
|
||||||
|
completo ter de escapar aspas/unicode num nome de pasta para a shell remota.
|
||||||
|
|
||||||
|
## Verificação
|
||||||
|
|
||||||
|
Construído e testado ponta-a-ponta contra produção e staging em 19-08-2026:
|
||||||
|
|
||||||
|
- **Leituras cruzadas independentes** (`descomplicar`, produção): `happyfiles_list_folders` devolveu
|
||||||
|
66 pastas, `all_files_count: 1218` e `uncategorized_count: 893` — confirmados byte-a-byte via
|
||||||
|
`wp eval`/`wp post list --format=count` directos fora do MCP. `happyfiles_list_files_in_folder`
|
||||||
|
na pasta "Clientes" (id 42) devolveu `total: 7` depois de corrigido o gotcha `include_children`
|
||||||
|
(tinha devolvido 120 antes da correcção); confirmado via `wp post term list <id>
|
||||||
|
happyfiles_category` em vários ficheiros individuais devolvidos.
|
||||||
|
- **Ciclo de escrita completo em `starter`** (site vazio de pastas, 7 attachments — sandbox seguro):
|
||||||
|
`happyfiles_create_folder` → `happyfiles_rename_folder` → `happyfiles_move_files` (ficheiro 19
|
||||||
|
para a pasta nova, confirmado via `wp post term list` directo) → `happyfiles_list_files_in_folder`
|
||||||
|
(1 item) / `happyfiles_list_uncategorized_files` (6 itens, confirmado) → `happyfiles_move_files`
|
||||||
|
de volta a `null` (confirmado `wp post term list` vazio de novo) → `happyfiles_delete_folder` →
|
||||||
|
estado final confirmado idêntico ao inicial (`wp term list` vazio, `wp post list --format=count`
|
||||||
|
ainda 7, `wp post get 19` com o título original intacto).
|
||||||
|
|
||||||
|
## Skills relacionadas
|
||||||
|
|
||||||
|
Nenhuma skill de conhecimento dedicada ao HappyFiles Pro existe neste bundle — esta skill é a única
|
||||||
|
documentação (arquitectura de dados + tools). Ver `wp-cli` para o padrão geral de gestão via
|
||||||
|
WP-CLI no servidor CWP.
|
||||||
Reference in New Issue
Block a user