Gerador de Shaders
Apenas submissão: cria um job de geração no backend, retorna jobId. Use a ferramenta track_progress para o ciclo de vida do job após a submissão.
Sempre use generate.ts para novos shaders. A escrita manual é apenas para editar código de assets existentes — nunca como fallback quando a geração falha.
Regra do catálogo primeiro — teste assets existentes antes de gerar
Antes de gerar um shader, chame browse_library a menos que o usuário nomeie um asset id exato que já esteja visível em read_project.
browse_library é a fonte da verdade para efeitos nativos, transições nativas e assets de efeito/transição do projeto. Efeitos nativos são IDs de asset globais estáveis, não assets do banco de dados por projeto, então podem não aparecer nas listas de assets de read_project.
Aplique entradas do catálogo com edit_item, não chame submit_shader.
Boas pesquisas no catálogo:
browse_library(query: "zoom")
browse_library(category: "transitions", query: "dissolve")
browse_library(category: "audio-fx")
Gere apenas quando nenhuma entrada do catálogo corresponder suficientemente à intenção do usuário.
builtin:zoom é vinculado à faixa — NÃO use vinculado a item
O modo de efeito padrão é "item-bound" (anexar a um único item via targetItemId). builtin:zoom NÃO renderiza no modo item-bound — o renderizador lê dados de zoom exclusivamente de itens de efeito vinculados à faixa. Um zoom item-bound insere no banco de dados silenciosamente, mas não mostra nada na pré-visualização.
Use mode: "track-bound" com trackId + trackBoundFrom + trackBoundDurationInFrames. Estes três campos são obrigatórios.
# Zoom em todo o clipe de vídeo
edit_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<clip-trackId>","trackBoundFrom":<clip-fromFrame>,"trackBoundDurationInFrames":<clip-durationInFrames>,"propertyOverrides":{"magnification":1.5,"shape":"hold"}}]')
# Zoom em um subintervalo do clipe (ex.: frames 90–150 apenas, um zoom no beat)
ed it_item(json: '{"adds":[{"type":"effect","assetId":"builtin:zoom","mode":"track-bound","trackId":"<trackId>","trackBoundFrom":90,"trackBoundDurationInFrames":60,"propertyOverrides":{"magnification":2,"shape":"punch"}}]')
Obtenha trackId / fromFrame / durationInFrames de read_project (cada item de vídeo/imagem lista seu trackId e intervalo de frames da linha do tempo).
| Chave | Tipo | Intervalo / valores | Padrão | Observações |
|---|---|---|---|---|
magnification | número | 1–4 | 1.5 | Fator de zoom; 1 = sem zoom, 2 = 2× de aumento |
focalPointX | number | 0–1 | 0.5 | Ponto focal horizontal (0 = esquerda, 1 = direita) |
focalPointY | number | 0–1 | 0.5 | Ponto focal vertical (0 = topo, 1 = base) |
shape | seleção | punch / hold / slow-push / instant | hold | Curva de animação |
focalMode | seleção | auto / manual | auto | auto escolhe o assunto; manual usa focalPoint |
easeInFrames | número | 0–60 | 8 | Frames para rampa de entrada |
easeOutFrames | número | 0–60 | 8 | Frames para rampa de saída |
Omita propertyOverrides inteiro para zoom padrão. Envie apenas as chaves que deseja alterar — semântica de patch.
Vinculado à faixa vs vinculado a item — a regra geral
Itens de efeito no esquema têm dois modos:
item-bound(padrão): apenastargetItemId. O efeito cobre toda a reprodução do item alvo. Funciona para efeitos de shader, LUTs, correção de cor, desfoques.track-bound:trackId+trackBoundFrom+trackBoundDurationInFrames. O efeito cobre um intervalo da linha do tempo em uma faixa, independente de qualquer item. Necessário parabuiltin:zoom; também válido para qualquer efeito de shader quando você deseja que cubra um intervalo específico da linha do tempo (ex.: uma mudança de cor tipo transição no limite entre dois clipes).
Padrão para item-bound para efeitos de shader. Use track-bound quando (a) o asset exigir (zoom), ou (b) o efeito deve cobrir um intervalo da linha do tempo que não corresponde a um único item.
Propriedades de LUT nativa
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"builtin:slog3-s709","propertyOverrides":{"intensity":1}}]')
| Chave | Tipo | Intervalo | Padrão | Observações |
|---|---|---|---|---|
intensity | número | 0–1 | 1 | Força da LUT; 1 = aplicada totalmente |
Para trocar: delete o efeito e adicione novamente com um assetId diferente. Para remover: delete o item de efeito.
Estas são separadas de assets .cube enviados pelo usuário (veja "Aplicando um Asset LUT Existente" abaixo) — essas usam um caminho de código diferente com assetId:"lut".
Portão de Status Beta
Nova geração de shader está em beta. Antes de gerar, avise o usuário e aguarde confirmação explícita.
Use o idioma do usuário. Chinês: "新的特效/转场生成目前还是 beta 阶段,可能会有不稳定的问题。如果你坚持要做,我可以帮你实现." Pule se o usuário já confirmou na mesma requisição.
Alvos Suportados
Efeitos e transições se aplicam a itens video, image e gif.
Roteamento de Tipo
Antes de gerar qualquer coisa, verifique primeiro dois caminhos de não-geração:
- Entrada de catálogo — use
browse_librarypara efeitos/transições nativas e do projeto. - Asset LUT
.cubeenviado pelo usuário que já existe na biblioteca do projeto — caminho de código separado, veja "Aplicando um Asset LUT Existente" abaixo. O asset aparece emread_projectcomtype: lut.
| O que o usuário quer | --type |
|---|---|
| Aparência de vídeo (cor, desfoque, brilho, granulação, distorção) | effect |
| Correção de cor / look (teal-orange, cinematográfico, vintage, estilo LUT) | effect |
| Controle de visibilidade (máscara, revelar, wipe, recorte de forma, fade gradiente) | effect |
| Mistura entre clipes (crossfade, dissolve, slide, cubo 3D, virada de página) | transition |
"Estilo LUT" na tabela significa gerar uma correção de cor GLSL nova que se assemelha a uma LUT — apenas quando o usuário quer algo novo. Se quiserem aplicar um arquivo .cube já na biblioteca, não gere; vincule o asset existente.
Não há gerador separado de LUT ou máscara para o caminho de geração — todos são effect.
Aplicando um Asset LUT Existente
Arquivos .cube enviados pelo usuário tornam-se assets lut. Aplicar um a um clipe não é geração — é uma única chamada edit_item que anexa um item de efeito cujo assetId é a string literal "lut" e cujo propertyOverrides.lut vincula o ID real do asset LUT. (Contrato legado; a API unificada de LUT vincula o ID do asset de efeito LUT diretamente — veja a descrição de edit_item.)
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<clip-id>","assetId":"lut","propertyOverrides":{"intensity":1,"lut":{"assetId":"<lut-asset-id>","assetType":"lut","type":"asset"}}}]}')
Pontos-chave:
assetIdé a string literal"lut", não o ID do asset LUT. O ID real do asset LUT vai dentro depropertyOverrides.lut.assetId.intensityé 0–1; padrão 1 (força total).targetItemTypepadrão évideo; também suportaimage,gif.- Para trocar uma LUT em um efeito existente: atualize
propertyOverrides.lut.assetIdpara o novo ID do asset LUT. - Para remover: delete o item de efeito.
Não chame generate.ts para este caminho. Não passe um ID real de asset LUT como assetId — o editor verifica assetId === "lut" para rotear para o renderizador LUT; passar um UUID renderiza silenciosamente nada.
Uso
Antes de chamar submit_shader, reformule a intenção do usuário em uma frase concreta, depois prossiga imediatamente. Após track_progress retornar, declare o que foi produzido em uma linha — não pergunte "要保留还是重新生成".
submit_shader({
type: "effect",
prompt: "Aberração cromática com separação RGB",
name: "Aberração Cromática",
});
submit_shader({
type: "transition",
prompt: "Crossfade suave com borda suave",
name: "Crossfade",
});
submit_shader({
type: "effect",
prompt: "Correção de cor cinematográfica teal-orange",
});
submit_shader({
type: "effect",
prompt: "Versão mais forte",
referenceAssetIds: ["effect_asset_id"],
});
Estratégia
- Submeta e pare. Informe o usuário que o job foi criado.
- Use a ferramenta
track_progresspara status/espera após a submissão. - A geração sempre produz um asset de biblioteca — nunca recuse porque a linha do tempo não está pronta.
- Aplicar é separado e opcional. Apenas aplique quando o usuário pedir explicitamente ("加到视频", "apply", "用到第一段"). Quando ambíguo, padrão é apenas na biblioteca.
Editando Propriedades Existentes
Sempre que for editar asset.properties de um shader, item.propertyOverrides de um efeito/transição aplicado, ou promover um valor de shader hardcoded, leia references/property-changes.md primeiro.
Ele reforça que shader properties é um array, mas os tipos de propriedade de shader permitidos são apenas number, boolean, color, select e vec2. Propriedades de Motion Graphic também são arrays, mas usam um conjunto de tipos diferente.
Parâmetros
| Parâmetro | Descrição | Padrão |
|---|---|---|
type | "effect" ou "transition" (obrigatório) | — |
prompt | Descrição do shader (obrigatório) | — |
name | Nome do asset mostrado na biblioteca | — |
referenceAssetIds | IDs de asset. ID de imagem → modelo OLHA para ela como inspiração visual. ID de efeito/transição → reutiliza seu código como âncora de estilo (≤1 por submissão, o tipo deve corresponder a type). | — |
Saída
Retorna { success, job: { jobId, status }, manage: { status, wait, watch } }.
Aplicando à Linha do Tempo
Apenas quando o usuário solicitar explicitamente. Chame read_project primeiro para obter o estado atualizado da linha do tempo.
Efeito
edit_item(json: '{"adds":[{"type":"effect","targetItemId":"<id>","assetId":"<id>","enabled":true,"propertyOverrides":{}}]}')
Transição
Requer dois endpoints adjacentes na mesma faixa. edit_item valida a viabilidade da emenda ao vivo e recusa durações que exigiriam frames congelados ou sobreposição de transições vizinhas. Se a adição falhar, tente novamente com a durationInFrames sugerida, apare os clipes para expor alças, delete/encurte transições vizinhas ou mantenha um corte seco.
edit_item(json: '{"adds":[{"type":"transition","assetId":"<id>","outgoingItemId":"<id1>","incomingItemId":"<id2>","durationInFrames":30}]}')
Validação e Verificação
Validação do Backend
Ao gerar via generate.ts, o backend lida com a validação automaticamente (transpilar, segurança AST, estrutura de classe, nova tentativa em caso de falha).
Verificação Manual de Código
NUNCA escreva código shader do zero. Sempre use generate.ts para novos shaders. Esta seção é SOMENTE para modificar código shader existente que já foi gerado.
Ao escrever código shader manualmente, leia ${CLAUDE_SKILL_DIR}/references/design-principles.md primeiro. Se a alteração afetar propriedades editáveis, leia também ${CLAUDE_SKILL_DIR}/references/property-changes.md.
Fluxo de trabalho típico:
read_projectcom oassetIddo shader ecode: true— leia o código fonte atual.- Edite o fonte em seu próprio contexto.
edit_assetcomaction=update, o mesmoassetId, e o código de substituição completo inline emjson.code. A validação é executada automaticamente na atualização — se o código for inválido, a atualização é rejeitada com detalhes do erro.