Files
gart/code/Engine/README.md
T
João HenriqueandClaude Opus 5 dcdd73edb5 docs: varredura geral, documentação por função e regra de atualização
A documentação descrevia um sistema que não existe mais: 62/73 ferramentas
(são 74), writer.py e models.py como arquivos (viraram pacotes), 1032 testes
(são 1454), models_api.py descrito como "API FastAPI" (é ponte JSON) e o app
SwiftUI ausente por completo — 5.500 linhas que o usuário opera todo dia sem
uma linha de documentação.

Cada arquivo passa a ter uma função específica, com cabeçalho de escopo
dizendo o que cobre e o que NÃO cobre (com a seta para quem cobre). O objetivo
é ler só o necessário: doc fora do assunto custa tempo e processamento sem
entregar nada.

    01 arquitetura   camadas, duas portas de entrada, regras transversais
    02 módulos       mapa do engine, incluindo o pipeline de voz
    03 server/tools  as 74 tools, helpers e como criar uma nova
    08 app macOS     NOVO — build por swiftc, telas, ponte, etapa 5
    09 manutenção    NOVO — por onde começar, o que está aberto, sintoma→arquivo

CLAUDE.md ganha a seção "Documentação (MANDATORY)": tabela de roteamento
(qual arquivo abrir para cada tarefa) e a regra de que toda alteração de
código atualiza a doc no mesmo commit, com o mapa de o-que-mexeu → o-que-
atualizar. Doc velha engana mais que doc ausente.

O índice do 05_EXPERIENCIAS subiu para o topo: consultar "isso já quebrou
antes?" custava carregar 1.281 linhas antes de chegar na tabela.

Dívidas levantadas na varredura e registradas em 09 §2: etapa 6 ainda ignora
o phrase_review.json, offset de ~400ms do Whisper, MacApp sem teste, admin/
fora do lint, confirmações visuais pendentes no FCP, submódulo WHISPERX sujo.

Também corrigidos dois links quebrados no Engine/README que apontavam um
nível acima do certo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 22:51:33 -04:00

280 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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](docs/01_ARCHITECTURE.md) e depois
> [09 Manutenção](docs/09_MANUTENCAO.md) — 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](docs/01_ARCHITECTURE.md) ·
> [02 Módulos](docs/02_MODULES.md) · [03 Server/Tools](docs/03_SERVER_TOOLS.md) ·
> [04 Testes & Workflow](docs/04_TESTS_AND_WORKFLOW.md) ·
> [05 Experiências](docs/05_EXPERIENCIAS.md) · [06 Boas Práticas](docs/06_BOAS_PRATICAS.md) ·
> [07 Projeto Ativo no FCP](docs/07_ESTUDO_PROJETO_ATIVO_FCP.md) ·
> [08 App macOS](docs/08_APP_MACOS.md) · [09 Manutenção](docs/09_MANUTENCAO.md)
---
## 1. O que o programa faz
1. **Um motor de parse/serialização FCPXML** — transforma timelines do Final
Cut Pro (XML v1.8–v1.14, flat `.fcpxml` e bundles `.fcpxmld`) em objetos
Python, e reescreve de volta sem perda de sidecars (object tracking,
Cinematic).
2. **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).
3. **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.454 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:
```python
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:
```python
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 `.fcpbundle` para *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:
```bash
./Engine/run_after_fix.sh
```
Ele roda (a partir de qualquer diretório) e falha (`set -e`) se algo não
passar:
1. **`uv run ruff check . --exclude docs/`** — lint com zero erros.
2. **`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](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](docs/02_MODULES.md) — guia módulo a módulo do `fcpxml/`
(responsabilidade, tamanho, APIs públicas).
- [docs/03_SERVER_TOOLS.md](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](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](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](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](../../CLAUDE.md) — visão geral, key patterns, execução e pre-commit.
- [../docs/CAPABILITY-AUDIT-2026-06.md](../docs/CAPABILITY-AUDIT-2026-06.md) —
auditoria do ecossistema e roadmap dual-mode (XML + Live).
- [../docs/WORKFLOWS.md](../docs/WORKFLOWS.md) — 8 receitas de workflow de produção.
- [../docs/specs/](../docs/specs/) — schemas de tools, estrutura FCPXML, pseudocódigo
do writer, algoritmo de rough cut, implementação do server, roadmap, modelos.
- [../admin/graphify.md](../../admin/graphify.md) — pipeline de graphify do código.