Files
gart/CLAUDE.md
T
João HenriqueandClaude Sonnet 5 7b5aed79ee feat(voz): legenda por ênfase, forced align, IA local e correções de zoom/revisão
Trabalho da branch feat/revisao-enfases: pipeline de edição por voz ganha
alinhamento forçado (whisperx), roteirização por LLM local (Ollama), e a
etapa 5 (revisão de frases) passa a refletir de verdade o que é aplicado.

- generate_subtitles_by_emphasis: legenda comum cobre o clipe inteiro,
  legenda dinâmica só nas frases de ênfase, e a comum é desativada
  (enabled="0") onde a dinâmica cobre, em vez de nunca ser gerada ali.
- validate_subtitle_layout ignora títulos com enabled="0" — corrige falso
  positivo de colisão contra o que está desativado no lugar dele.
- Corrige zoom/marcador sendo descartado quando a borda encosta exatamente
  no início de um corte.
- Etapa 5 do Assistente: recarrega quando as decisões da IA mudam (com
  fresh=true, ignorando a revisão salva antiga) — resolve a dessincronia
  entre "ativa" na tela e o que já foi cortado no FCPXML.
- Etapa "Processar" reaplica as decisões da revisão (_phrase_actions.json)
  antes da cadeia de remoção de silêncio/legendas — antes, desativar uma
  frase na etapa 5 não tinha efeito nenhum no vídeo final.
- Etapa "Concluído" fundida em "Processar" — abrir no Final Cut/Finder
  aparece assim que termina, sem slide extra.
- Palavra clicável na etapa 5 agora funciona como toggle (clique de novo
  desfaz) e mostra a própria ênfase (sublinhado colorido + peso da fonte).
- fcpxml/forced_align.py, fcpxml/llm_local.py, ai_edit.py: alinhamento
  fonético via whisperx e roteirização local via Ollama/Gemma.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-21 18:26:04 -04:00

9.7 KiB
Executable File
Raw Blame History

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_<name>(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 <storyline> 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

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:

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 — é:

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:

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 (<asset-clip>) are different from timeline clips (<clip>)
  • Markers are children of clips, not siblings
  • The <spine> 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