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

175 lines
9.7 KiB
Markdown
Executable File
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.
# 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
```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 (`<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