Fase 0 do roteiro de reestruturação (Engine/docs/10_MAPA_REESTRUTURACAO.md): move code/WHISPERX (2,6 GB de backups órfãos, sem uso ativo, sem .gitmodules) para ~/Archives/G-ART-WHISPERX-backup fora do workspace git; traz admin/ para o gate de lint de run_after_fix.sh; corrige fcpxml/writer/adjustment.py, que gerava um wrapper <adjustment> inexistente no DTD 1.13 (filtros agora vão direto no <clip>, na ordem exigida), com teste de regressão novo. Achado à parte: .gitignore tinha uma regra solta "models/" (pensada só para o cache do Whisper em code/models/) que também escondia do git todo o pacote fcpxml/models/ — nunca commitado, sem proteção nenhuma. Corrigida para /code/models/, ancorada na raiz. Docs atualizados no mesmo commit (02_MODULES, 09_MANUTENCAO, 10_MAPA_REESTRUTURACAO, 05_EXPERIENCIAS #34 e #36), conforme a regra do CLAUDE.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
G-ART — Engine Overview
Este documento descreve a arquitetura interna do G-ART / fcp-mcp-server
(repositório G-ART), uma aplicação MCP (Model Context Protocol) server em
Python que lê, analisa e reescreve arquivos FCPXML do Final Cut Pro —
a ponte entre o Final Cut Pro e IA.
Diferente do CommandPost (automação de GUI via Lua/Hammerspoon), este projeto opera fora do Final Cut Pro: você exporta o XML, o servidor processa o documento como dados estruturados e devolve um XML modificado para importação. Nada é patcheado, nenhuma API privada é usada.
Toda a análise foi feita a partir do código-fonte. Este README é a visão
geral; o detalhe módulo a módulo mora em docs/02_MODULES.md, que é o
documento a manter atualizado quando a estrutura mudar.
Começando agora? Leia 01 Arquitetura e depois 09 Manutenção — o primeiro diz como o sistema é dividido, o segundo diz por onde começar a mexer e o que está em aberto.
Guia completo: 01 Arquitetura · 02 Módulos · 03 Server/Tools · 04 Testes & Workflow · 05 Experiências · 06 Boas Práticas · 07 Projeto Ativo no FCP · 08 App macOS · 09 Manutenção
1. O que o programa faz
-
Um motor de parse/serialização FCPXML — transforma timelines do Final Cut Pro (XML v1.8–v1.14, flat
.fcpxmle bundles.fcpxmld) em objetos Python, e reescreve de volta sem perda de sidecars (object tracking, Cinematic). -
Uma camada MCP de 74 ferramentas — expõe análise, edição em lote, QC, geração, exportação cross-NLE, inteligência de mídia (silêncio/beats) e edição baseada em transcrição, tudo acessível por um cliente MCP (Claude).
-
Modo Live (macOS) — faz push de um FCPXML direto para o Final Cut Pro em execução via Apple events oficiais (Open Document), sem re-importação manual. Leitura de bibliotecas abertas via dicionário AppleScript read-only.
2. Pilha tecnológica
| Camada | Tecnologia |
|---|---|
| Linguagem | Python 3.10+ (~13k linhas em server.py, server_tools/ e fcpxml/) |
| Protocolo MCP | mcp (mcp SDK), servidor por stdio |
| Parsing XML | defusedxml em todos os 4 entry points + lxml/ElementTree |
| Tempo racional | frações numerador/denominador no formato "600/2400s" |
| Análise de mídia | ffmpeg silencedetect (opcional) e librosa (extra [intelligence]) |
| Transcrição | Whisper local (extra [transcribe]) |
| Controle Live | osascript / Apple events para o bundle com.apple.FinalCut |
| Validação | xmllint contra os DTDs oficiais do bundle do Final Cut Pro |
| Licença | MIT |
3. Estrutura geral do repositório
G-ART/
├── CLAUDE.md # Regras do projeto para o agente
├── admin/ # Ponte com o app (fora de code/)
│ ├── models_api.py # Entry point: docstring dos comandos + dispatch
│ └── api/ # Os 37 comandos, um módulo por assunto
└── code/
├── server.py # MCP entry point — só dispatch
├── server_tools/ # Handlers das 74 tools + _shared/
├── fcpxml/ # "Engine" — biblioteca Python de núcleo
│ ├── writer/ # PACOTE: edição/escrita (mixins por assunto)
│ ├── models/ # PACOTE: dados por família (timing, timeline…)
│ ├── parser.py # FCPXML → objetos Python
│ ├── rough_cut.py # Gera timelines novas
│ ├── voice_*.py # Pipeline de voz (features → timeline → actions)
│ ├── phrase_review.py # Revisão de frases da etapa 5
│ ├── text_layout.py # Diagramação das legendas
│ ├── live.py # Modo Live — push_to_fcp
│ ├── safe_xml.py # defusedxml + serialize_xml()
│ └── dtd.py # Validação contra DTDs da Apple
├── MacApp/Sources/ # App SwiftUI (compilado por swiftc)
├── Engine/ # Esta documentação
├── docs/ # WORKFLOWS, CAPABILITY-AUDIT, specs
├── examples/ # Fixture de teste (sample.fcpxml)
└── tests/ # 1.466 testes / 42 suítes
4. O "Engine": a biblioteca fcpxml/
É o núcleo desacoplado do MCP. Não conhece o protocolo MCP nem os argumentos
das ferramentas — trabalha apenas com objetos Python e XML. server.py atua
como camada de transporte/adaptação que chama este núcleo.
4.1 Fundamentos de tempo — models.TimeValue
Toda hora é uma fração racional, nunca float. Isso elimina erro de arredondamento em trim/split/speed em qualquer frame rate:
TimeValue(600, 2400) # "600/2400s" == 0.25s
- Comparações por multiplicação cruzada (
a/b < c/d→a*d < c*b), permanecendo sempre em inteiros. - Denominadores normalizados para positivos na construção — o sinal vive no numerador.
- Soma/subtração compartilham um único caminho
_binop()(fast-path de mesmo denominador + alinhamento por LCM).
4.2 Modelos principais — models/
| Classe | Função |
|---|---|
TimeValue, Timecode |
Tempo racional e formatação/parse de timecode |
Clip, VideoClip, AudioClip |
Clips da timeline (offset, start, duration, markers) |
ConnectedClip |
Clips com atributo lane (acima/abaixo da espinha) |
CompoundClip |
Clips compostos |
Timeline, Project |
Contêineres de espinha + connected clips |
Marker, MarkerType, MarkerColor |
Marcadores; INCOMPLETE é canônico, TODO é alias |
SilenceCandidate, FlashFrame, GapInfo, DuplicateGroup |
Resultados de QC |
ValidationIssue, ValidationResult |
Resultados de validação |
SegmentSpec, PacingConfig, MontageConfig |
Parâmetros de geração |
Single source of truth: MarkerType enum é dono da serialização —
from_string() para entrada, from_xml_element() para parse, xml_attrs para
escrita. from_xml_element faz match estrito do atributo completed
('0'/'1' apenas), rejeitando valores com padding de espaço.
4.3 Subsistemas
| Subsistema | Módulo | Função |
|---|---|---|
| Parser | parser.py |
FCPXML → objetos Python: espinha, connected clips, secondary storylines, roles |
| Modifier | writer/ (FCPXMLModifier) |
Edição index-based (clips/resources/formats dicts) do documento existente |
| Writer | writer/generator.py |
Gera FCPXML novo a partir de objetos Python |
| Rough cut | rough_cut.py |
Gera timelines (rough cuts, montages, A/B roll) |
| Diff | diff.py |
Compara timelines — detecta added/removed/moved/trimmed |
| Export | export.py |
DaVinci Resolve v1.9 + FCP7 XMEML v5 |
| Media intel | media_intel.py |
Detecção real de silêncio (ffmpeg) e beats (librosa, lazy) |
| Transcript | transcribe.py |
Whisper local + edição por transcrição |
| Templates | templates.py |
Estruturas pré-prontas (intro/outro, lower thirds, music video) |
| Live | live.py |
push_to_fcp (Apple event) e list_fcp_libraries (AppleScript) |
| Segurança XML | safe_xml.py |
Wrappers defusedxml centralizados + serialize_xml() |
| DTD | dtd.py |
Valida output contra DTDs oficiais no bundle do FCP |
5. A camada MCP — server.py
5.1 Padrão de dispatch
Não há cadeias gigantes de if/elif. Um dicionário mapeia nome → handler
assíncrono:
TOOL_HANDLERS = {
"analyze_timeline": handle_analyze_timeline,
"list_clips": handle_list_clips,
# ... 74 tools, todos em server_tools/
}
Cada ferramenta tem seu async def handle_<name>(arguments: dict). Todas
retornam via _text_result(text), que envolve strings no TextContent MCP.
5.2 Helpers centrais
| Helper | Linha | Função |
|---|---|---|
_parse_project() |
server.py:319 |
Parseia FCPXML → (tree, timeline, project); a maioria dos handlers começa aqui |
_resolve_io_paths() |
server.py:357 |
Consolida validação de caminho de entrada/saída |
_setup_modifier() / _setup_generator() |
server.py:390 / :414 |
Preparam modifier/generator com validação |
_format_clip_table() / _markdown_table() |
server.py:245 / :259 |
Renderização de tabelas |
_parse_timestamp_parts() |
server.py:433 |
Parse de timestamps (min:seg, H:MM:SS, SMPTE) |
_detect_flash_frames() / _detect_gaps() / _detect_duplicate_groups() |
server.py:1667+ |
Detectores de QC |
_validate_filepath() / _validate_output_path() |
server.py:103 / :149 |
Sandbox de I/O |
_check_json_depth() |
server.py:83 |
Rejeita payloads aninhados além de 50 níveis |
5.3 Modo Live — fcpxml/live.py
Rode apenas as superfícies sancionadas da Apple — sem patch de binário, sem APIs privadas, sem acessibilidade:
- push_to_fcp — import FCPXML via Apple event Open Document. Injeta um
<import-options>no documento (local da biblioteca, copy/link assets, suprimir avisos). Requer um caminho.fcpbundlepara zero-click de verdade; sem ele, o FCP abre um modal "Open Library" que bloqueia até resposta humana. - list_fcp_libraries — enumera bibliotecas → eventos → projetos via o
dicionário AppleScript read-only (suite
com.apple.FinalCut.library.inspection).
A assimetria estrutural: import é scriptable, mas a Apple não oferece export
programático — para puxar a timeline atual de volta, você ainda roda
File > Export XML. O modo Live empurra; round-trips voltam pelas ferramentas
XML.
6. Fluxo de um pedido
Cliente MCP (Claude)
│ JSON-RPC (stdio)
▼
server.py ── dispatcher (TOOL_HANDLERS)
│
├── handle_* (valida caminho, _parse_project, opera)
│
├── fcpxml/parser.py (XML → objetos)
├── fcpxml/writer.py (edita / grava)
├── fcpxml/rough_cut.py (gera novas timelines)
├── fcpxml/export.py (cross-NLE)
│
▼
output_<suffix>.fcpxml (original nunca é sobrescrito)
│
▼
Final Cut Pro: File → Import → XML (ou push_to_fcp, sem cliques)
7. Validação padrão pós-correção (é obrigatório)
Regra do padrão do sistema: sempre após concluir qualquer correção de código, o sistema é automaticamente executado/validado.
O gatilho é o script [Engine/run_after_fix.sh](run_after_fix.sh). Toda vez
que você terminar uma correção, acione-o:
./Engine/run_after_fix.sh
Ele roda (a partir de qualquer diretório) e falha (set -e) se algo não
passar:
uv run ruff check . --exclude docs/— lint com zero erros.uv run pytest tests/ -v— toda a suíte de testes passa.
Se falhar, corrija antes de prosseguir. Esta validação é o mesmo critério já
descrito em CLAUDE.md (Pre-Commit) — a diferença é que agora há um comando
único padronizado que garante a execução automática do sistema após cada
correção, sem depender de lembrar dos dois comandos no pre-commit.
8. Como navegar a documentação
Esta pasta
Engine/é o hub da documentação. Comece por aqui.
Documentação padrão (leia nesta ordem)
- docs/01_ARCHITECTURE.md — como o sistema é dividido (camadas: admin → server → fcpxml/) e como se conectam. Leia antes de qualquer mudança.
- docs/02_MODULES.md — guia módulo a módulo do
fcpxml/(responsabilidade, tamanho, APIs públicas). - docs/03_SERVER_TOOLS.md — a camada MCP
server.py, 74 ferramentas, helpers e o padrão de handler. - docs/04_TESTS_AND_WORKFLOW.md — suíte de testes, fluxo de trabalho (lint + pytest), execução e estado atual do sistema.
- docs/05_EXPERIENCIAS.md — memória de projeto: registro cumulativo de problemas estruturais, erros recorrentes e decisões. Atualize sempre que um problema for detectado/corrigido.
- docs/06_BOAS_PRATICAS.md — boas práticas de programação a aplicar em toda alteração/correção; inclui checklist final.
Outros documentos
- ../CLAUDE.md — visão geral, key patterns, execução e pre-commit.
- ../docs/CAPABILITY-AUDIT-2026-06.md — auditoria do ecossistema e roadmap dual-mode (XML + Live).
- ../docs/WORKFLOWS.md — 8 receitas de workflow de produção.
- ../docs/specs/ — schemas de tools, estrutura FCPXML, pseudocódigo do writer, algoritmo de rough cut, implementação do server, roadmap, modelos.
- ../admin/graphify.md — pipeline de graphify do código.