Plugins
Plugins adicionam novas fontes de automação (tipos de trigger) sem alterar o Curupira. Um plugin é uma distribuição Python comum, instalada junto com o Curupira, que declara um entry point por trigger. As automações do plugin ficam no mesmo arquivo TOML, são validadas quando a configuração é carregada e passam pelo mesmo agendamento, checkout e execução do coding agent que os triggers embutidos.
O código de um plugin roda dentro do processo do Curupira assim que ele é descoberto. Instale apenas distribuições em que você confia.
Usando um plugin
Instale o plugin no mesmo ambiente do Curupira e confira se ele foi carregado:
uv tool install curupira --with curupira-tickets
curu plugins list
curu plugins list mostra cada tipo de trigger, a distribuição que o fornece e os
placeholders de prompt que ele adiciona. Configure a automação com esse trigger_type e
as opções documentadas pelo plugin:
[coding_agents.automations.ops-tickets]
trigger_type = "ticket"
repo = "acme/api"
project = "OPS"
prompt = "Corrija ${ticket_key} (${ticket_priority}) em ${repo}"
curu validate verifica as opções e os placeholders do plugin do mesmo jeito que faz com
os embutidos. Se um plugin não puder ser importado, todo comando que carrega a
configuração para com um Configuration error que informa o entry point e a distribuição.
Escrevendo um plugin
Um plugin fornece três peças, todas importadas de curupira.plugins:
- Um modelo de configuração que estende
AutomationConfigurationBasee define o padrão detrigger_typeigual ao tipo do plugin. Ele herdarepo,path,setup_script,checkout,prompteprofile, e acrescenta as opções do plugin como campos e validadores Pydantic. - Um
TaskSource, que transforma uma consulta em objetosTask. UsePollingTaskFeedem volta dele para ganhar deduplicação e backoff sem esforço. - Um
Trigger, que liga o modelo de configuração, os placeholders de prompt e o feed.
O exemplo completo de código está na página em inglês; os nomes de classes e campos são os mesmos.
Registre o trigger no pyproject.toml do plugin. O entry point pode apontar para a
subclasse de Trigger (instanciada sem argumentos) ou para uma instância pronta:
[project]
name = "curupira-tickets"
dependencies = ["curupira"]
[project.entry-points."curupira.triggers"]
ticket = "curupira_tickets:TicketTrigger"
Contrato
| Membro | Obrigatório | Função |
|---|---|---|
trigger_type |
Sim | Valor usado em trigger_type; precisa ser único entre embutidos e plugins. |
configuration_model |
Sim | Modelo Pydantic da tabela da automação. |
prompt_fields() |
Sim | Placeholders que o trigger adiciona aos comuns. |
prompt_context(task) |
Sim | Valores desses placeholders. |
build_feed(automation, dependencies) |
Sim | Feed que descobre as tarefas. |
validate_task(task) |
Não | Rejeita snapshots de tarefa que o trigger não poderia ter gerado. |
create_version_control(runner) |
Não | Mecanismo de clone dos repositórios; None mantém o gh repo clone. |
on_task_started(task, state) |
Não | Roda logo antes de o coding agent começar. |
on_task_finished(task, state) |
Não | Libera estado depois que o agente termina; o padrão apaga a sessão retomável, então chame super() ao sobrescrever. |
api_version |
Não | Versão da API de plugins que o plugin usa; o padrão é o PLUGIN_API_VERSION do Curupira em execução. Defina explicitamente para falhar cedo em uma versão incompatível. |
FeedDependencies expõe polling, state_db_path e runner. Inicie processos externos
somente pelo runner (um AsyncProcessRunner que recebe um CommandRequest), nunca por um
shell. Guarde valores específicos da fonte em Task.attributes, um mapeamento de strings
persistido com a tarefa, para que o prompt continue sendo renderizado quando uma tarefa
interrompida for retomada.
O Curupira rejeita um plugin cujo api_version seja diferente de PLUGIN_API_VERSION, cujo
trigger_type já esteja registrado ou cujo configuration_model não use o tipo registrado
como padrão de trigger_type.
Testando um plugin
Dá para testar o plugin sem instalá-lo: registre o trigger com
curupira.tasks.registry.register, valide uma configuração com
ApplicationSettings.model_validate e chame o trigger diretamente. A suíte do Curupira tem
um plugin de exemplo completo em tests/plugins/ticket_plugin.py e os testes
correspondentes em tests/plugins/test_plugins.py.
A referência gerada dos modelos fica na página em inglês.