# CLAUDE.md — fcp-mcp-server ## Idioma (MANDATORY) Responder **sempre em português** ao usuário, sem exceção. Nunca responder em inglês nas mensagens de chat/prompt — inclusive resumos, atualizações de progresso e confirmações. Comentários e nomes de código continuam em inglês normalmente; a regra é sobre a comunicação com o usuário. ## What This Is MCP server that reads/writes Final Cut Pro XML (FCPXML) files. 77 tools for timeline analysis, batch editing, QC, generation, multi-track support, media relink, NLE export, transcript-based editing (local Whisper), LIVE FCP control (push_to_fcp / list_fcp_libraries via Apple events), and local-LLM voice scripting (editar-por-voz against Ollama/Gemma 3). Reads FCPXML 1.8–1.14 (incl. `.fcpxmld` bundles with sidecar preservation), writes 1.13 by default. Dual-mode (XML + Live) direction: `code/docs/CAPABILITY-AUDIT-2026-06.md`. ## Architecture Toda a estrutura do projeto fica em `code/`. A pasta `admin/` fica na raiz (fora de `code/`). Há **duas portas de entrada** para o mesmo engine: o MCP (Claude decide a edição) e a ponte JSON (o app macOS opera). Nenhuma das duas tem lógica de timeline — as duas delegam a `fcpxml/`. ``` code/server.py — MCP entry point (592 linhas). Só dispatch: TOOL_HANDLERS. code/server_tools/ — Os handlers das 77 tools, um módulo por categoria. code/server_tools/_shared/ — Helpers compartilhados (paths, project, formatting, captions, detection, media). code/fcpxml/parser.py — Reads FCPXML → Python objects (Timeline, Clip, Marker…) code/fcpxml/writer/ — PACOTE. Edição/escrita de FCPXML. FCPXMLModifier é montado por mixins, um por assunto (markers, trim, speed, titles, cut, silence…). Ver writer/modifier.py. code/fcpxml/models/ — PACOTE. Data classes por família: timing, timeline, enums, subtitles, qc, planning. code/fcpxml/rough_cut.py — Generates new timelines (rough cuts, montages, A/B rolls). code/fcpxml/diff.py — Timeline comparison engine. code/fcpxml/export.py — DaVinci Resolve v1.9 + FCP7 XMEML v5 export. code/fcpxml/media_intel.py — Silence detection + beat detection. code/fcpxml/dtd.py — Validates output against Apple's official DTDs. code/fcpxml/voice_*.py — Pipeline de voz: features → emphasis → voice_timeline → voice_actions → phrase_review. Ver Engine/docs/02. admin/models_api.py — Ponte JSON com o app: docstring de comandos + dispatch. admin/api/ — Os 37 comandos, um módulo por assunto. code/MacApp/Sources/ — App SwiftUI. Compilado por swiftc (sem Xcode/SPM). ``` Os dois `__init__.py` de pacote (`writer/`, `models/`) reexportam tudo, então `from .writer import FCPXMLModifier` e `from .models import TimeValue` seguem valendo em todo o projeto. ## Documentação (MANDATORY) A documentação viva fica em `code/Engine/docs/`. Cada arquivo tem **uma função específica** — leia só o que a tarefa exige, não o conjunto. Carregar documentação que não é do assunto custa tempo e processamento sem entregar nada. ### Qual arquivo abrir | Sua tarefa | Abra | Não precisa de | |-----------|------|----------------| | Entender como o sistema é dividido | `01_ARCHITECTURE.md` | o resto | | Achar onde mora uma função do engine | `02_MODULES.md` | 01, 03 | | Criar/alterar uma ferramenta MCP | `03_SERVER_TOOLS.md` | 08 | | Entender ou rodar os testes | `04_TESTS_AND_WORKFLOW.md` | — | | "Isso já quebrou antes?" | `05_EXPERIENCIAS.md` — **só o índice no topo** | as entradas que não são a sua | | Checklist antes de fechar | `06_BOAS_PRATICAS.md` | — | | Mexer no app / no Assistente | `08_APP_MACOS.md` | 02, 03 | | Escolher o que fazer, ver o que está aberto | `09_MANUTENCAO.md` | — | Quando não souber por onde começar: `09_MANUTENCAO.md`. Ele roteia para o resto. ### Regra de atualização (obrigatória) **Toda alteração de código atualiza a documentação no mesmo commit.** Doc velha engana mais do que doc ausente — quem lê confia nela e erra com confiança. | Você alterou | Atualize | |--------------|----------| | Estrutura de pastas, camadas ou dependências | `01_ARCHITECTURE.md` | | Criou/moveu/dividiu módulo em `fcpxml/` | `02_MODULES.md` (tabela + linhas) | | Criou/removeu ferramenta MCP | `03_SERVER_TOOLS.md` + contagem no `CLAUDE.md` | | Comando da ponte | docstring de `admin/models_api.py` + `08_APP_MACOS.md` | | Tela ou fluxo do app | `08_APP_MACOS.md` | | Resolveu ou abriu uma dívida | `09_MANUTENCAO.md` §2 | | Bateu num problema estrutural ou erro recorrente | `05_EXPERIENCIAS.md` + **índice no topo** | Se um número (tools, testes, linhas) mudou, corrija onde ele aparece. Se um documento divergir do código, **o código está certo** — conserte o documento. ### Ao escrever documentação - **Um assunto por arquivo.** Se um doc começar a cobrir dois, divida. - **Diga o que não está ali** e para onde ir — economiza a leitura seguinte. - **Fatos verificados**, não suposições: rode o comando e use o número real. - **Registre o porquê**, não só o quê. O "o quê" está no código; o "por quê" se perde, e é o que evita alguém desfazer uma decisão por engano. ## Key Patterns - **TimeValue**: All times are rational fractions (numerator/denominator) matching FCPXML's `"600/2400s"` format. Never use floats for time math. - **_parse_project()**: Helper that parses FCPXML and returns `(tree, timeline, project)` tuple. Most handlers start with this. - **generate_output_path()**: Creates `_modified`, `_chapters`, etc. suffixed output paths so originals aren't overwritten. - **Tool handlers**: Each tool has its own `async def handle_(arguments: dict)` function. All return via `_text_result(text)` which wraps strings in the MCP `TextContent` list. - **Connected clips**: Clips with `lane` attribute hang off spine clips. Positive lane = above (video), negative = below (audio). Secondary `` elements also contain connected clips. - **XMEML export**: Converts spine-based model to track-based model. Primary storyline → Track 0, connected clip lanes → higher tracks. ## Running ```bash cd code && uv run server.py # Start MCP server cd code && uv run --extra dev pytest tests/ -v # Run tests ``` ## Registro de Experiências e Boas Práticas (MANDATORY) Sempre que um problema de estrutura ou um erro recorrente for detectado e corrigido, **registre-o** em `code/Engine/docs/05_EXPERIENCIAS.md` (template já presente no arquivo). Antes de concluir qualquer alteração/correção, aplique e verifique as boas práticas e o checklist final em `code/Engine/docs/06_BOAS_PRATICAS.md`. ## Pre-Commit (MANDATORY) Padrão do sistema: **sempre após concluir uma correção, o sistema é automaticamente executado/validado.** Acione o script único a cada correção: ```bash cd code && ./Engine/run_after_fix.sh ``` Ele roda o lint (zero erros) e toda a suíte de testes, e falha se qualquer um não passar. Equivalente a rodar manualmente os dois comandos abaixo. ## Executar o App Localmente (MANDATORY) Sempre que uma alteração for feita no app (MacApp/) durante o período de implementação, **compile e rode o programa localmente no computador** para validar visualmente a alteração, além de rodar os testes. O comando padrão para isso — que fecha a instância anterior, recompila e abre o app para conferência — é: ```bash admin/run_app.command # compila e abre o app localmente (padrão de revisão) ``` Equivalente a `cd code && ./MacApp/build_app.sh --run`, mas desacoplado do Terminal. **Toda vez que uma alteração for concluída, rode este arquivo automaticamente** para já conseguirmos revisar o que foi feito antes de fechar a tarefa. Regra geral: após qualquer alteração, o app deve ser executado localmente antes de concluir a tarefa. Se houver erro de compilação, corrija antes de seguir. Before committing ANY changes, run both: ```bash cd code && ruff check . --exclude docs/ # Lint — must pass with zero errors cd code && pytest tests/ -v # Tests — all must pass ``` CI runs both on every push to main. If either fails, the commit gets an X on GitHub. Fix lint errors before committing, not after. ## Testing 1498 tests across 43 files, all under `code/tests/`. Um teste fora dessa pasta não roda (`testpaths = ["tests"]`) — se você criar um em outro lugar, confirme que a contagem total subiu. Cobertura por área: `test_models.py` (TimeValue/Timecode/Clip/Timeline), `test_writer.py` (insert/marker/trim/delete/split/speed), `test_server.py` (handlers e dispatch), `test_rough_cut.py`, `test_features_v05.py` (connected clips, roles, diff, reformat, silêncio, export), `test_marker_pipeline.py`, `test_refactored_helpers.py`, `test_transcribe.py`, `test_media_intel.py` (pula sem ffmpeg; o CI instala), `test_phrase_review.py` (revisão de frases da etapa 5) e `test_models_api.py` (comandos da ponte). Fixtures: `examples/sample.fcpxml` e XML inline. Os testes criam temporários e limpam depois. ## FCPXML Gotchas - FCPXML uses rational time everywhere: `"3600/2400s"` = 1.5 seconds - `offset` in clips is the timeline position, `start` is the source media in-point - Library clips (``) are different from timeline clips (``) - Markers are children of clips, not siblings - The `` element is the primary storyline — clips go here - `.fcpxmld` bundles are DIRECTORIES wrapping `Info.fcpxml` + sidecar data files — sidecars must be copied on save or object-tracking/Cinematic data is destroyed - `code/examples/sample.fcpxml` is NOT DTD-conformant (pre-`media-rep` assets, sequence-level chapter markers) — don't use it as a DTD-validity fixture