Criar extensões nativas para o GNOME Shell ou construir interfaces em GTK4/Libadwaita costuma exigir bastante trabalho braçal: aprender as APIs do GJS (JavaScript bindings para GNOME), manipular esquemas XML do GSettings, lidar com rotinas do C/GObject e reiniciar o ambiente (Wayland/X11) a cada alteração.

Para resolver uma necessidade do meu dia a dia no Zorin OS, decidi criar um indicador no painel do sistema para controlar o ponto diário, projetar o horário estimado de saída (considerando o tempo de almoço) e gerenciar o saldo acumulado de banco de horas.

Extensão do Zorin OS para controle de ponto

Em vez de escrever todo o boilerplate manualmente, utilizei o Antigravity CLI em um modelo de pair programming.

Abaixo está a timeline técnica dos prompts utilizados para conceber, implementar, depurar e refatorar a extensão.


Linha do Tempo de Desenvolvimento

1. Bootstrap e Arquitetura Inicial

Para iniciar a estrutura do projeto, utilizei o modo orientado a objetivos do Antigravity (/goal):

Prompt 1:
"/goal quero criar um plugin que fique no menu de notificacao do zorin os, para me ajudar a controlar o horario que eu bati o ponto hoje, e quando preciso bater para fechar 8 horas de trabalho, e me avise quando for essa hora. podes me ajudar?"

Resultado da geração:
O agente estruturou os arquivos e a lógica inicial do projeto:

  • extension.js: Indicador de painel e loop de atualização do GNOME Shell.
  • timeCalculator.js: Regras de cálculo de jornada, projeção de saída e saldo.
  • storage.js e XML de esquema: Persistência nativa via GSettings (org.gnome.shell.extensions.ponto).
  • notifier.js: Integração com notificações e alarmes do sistema.
  • Makefile e install.sh: Scripts de compilação de esquemas e instalação em ~/.local/share/gnome-shell/extensions/.
  • Suíte de 66 testes unitários executados diretamente no runtime GJS.

Painel de Configurações Gerais


2. Integração com GSettings e Resolução de Build

Na primeira instalação, a extensão não inicializou na barra superior.

Prompt 2:
“rodei o necessario, encerrando a sessao e recarregando, mas meu plugin nao carregou”

Diagnóstico e correção:
O agente analisou o ambiente e identificou que o schema XML do GSettings precisava ser compilado não apenas no diretório do projeto, mas também na pasta do usuário em ~/.local/share/glib-2.0/schemas/. O script install.sh foi atualizado para executar glib-compile-schemas no caminho global antes de reiniciar a extensão.

Prompt 3:
“Carregou sim, agora eu vi.”
“/commit”

Com a confirmação da carga, o agente rodou a suíte de testes e registrou o primeiro commit.


3. Persistência e Cálculo de Banco de Horas

Com o registro do dia atual funcional, o passo seguinte foi expandir a persistência para cobrir o ciclo semestral de banco de horas:

Prompt 4:
“O plugin armazena um historico dos dias trabalhados anteriormente?”

(Após confirmação da estrutura de dados)

Prompt 5:
“Eu preciso aumentar esse historico para mais de 60 dias. Pois o meu banco de horas é calculated a cada 6 meses, entao preciso de 1 ano de histórico. Pode trabalhar nisso, e ajustar o historico visual também.”

Implementação:

  • Ampliação do limite de armazenamento no GSettings para 400 dias.
  • Cálculo de saldo acumulado (crédito/débito de horas).
  • Aba Banco de Horas & Histórico nas configurações em Libadwaita com badges de saldo diário e exportação em formato .csv.

Aba Banco de Horas & Histórico


4. Input Parser e Entrada Retroativa (0800 ➔ 08:00)

Para permitir a digitação rápida de batidas passadas sem atrito visual:

Prompt 6:
“Onde fica o history.json, se eu quiser adicionar alguns dias de historico?”

Prompt 7:
“Quero criar um painel adicional agora nas configurações, para adicionar o historico dos dias anteriores. Me ajude a criar uma maneira facil de inserir o historico.”

Prompt 8:
“Quando eu selecionar o dia na marcacao do ponto historico, já carregue os horarios que esse dia tem cadastrado, se nao tiver, já deixe zerado. E me permita digitar tambem apenas os numeros, sem precisar digitar os 2 pontos. 0800 vira 08:00, 1234 vira 12:34, etc…”

Ajustes de UX:

  • Reatividade na seleção da data: preenchimento automático caso existam registros salvos.
  • Parser de entrada: conversão de strings numéricas puras (080008:00, 1717:00) atualizando dinamicamente a prévia de horas trabalhadas.

Aba Lançar Histórico


5. Implementação da Visão em Tabela (Planilha Mensal)

Para visualizar o mês cheio em uma única tela:

Prompt 9:
“Tem como adicionar uma tela parecida com uma planilha, onde a gente pode ver mais de um dia por vez?”

Estrutura criada:

  • Aba Visão em Planilha com Gtk.TreeView / Adw.PreferencesGroup cobrindo as 10 colunas da folha (Data, Entrada 1, Saída Almoço, Retorno, Saída Final, Total, Saldo, etc.).
  • Navegação entre meses (◀ Anterior, Próximo ▶, Mês Atual).
  • Exportação de relatório mensal em CSV.

Aba Visão em Planilha


6. Diagnóstico de Layout no Libadwaita (Adw.Clamp)

Ao maximizar a janela de configurações, a tabela da planilha ficava travada em uma largura estreita, ocultando colunas à direita. Enviei um print da tela no chat para análise visual:

Prompt 10:
“Quando eu aumento a tela da config, a planilha nao aumenta a largura, e ficam alguns campos escondidos.” (+ upload da imagem)

Causa raiz e solução:
No Libadwaita, o widget Adw.PreferencesPage encapsula os grupos dentro de um Adw.Clamp, restringindo a largura máxima do conteúdo a 600px por padrão.

A solução implementada foi percorrer a hierarquia de widgets da janela e ajustar a propriedade maximum-size do Adw.Clamp para 2400px especificamente na aba da planilha, habilitando hexpand: true na tabela.


7. Polimento Visual e Finalização

Ajustes finais de hierarquia de widgets e navegação:

Prompt 11:
“Ajuste os atalhos de data para nao serem ONTEM e ANTEONTEM, e sim DIA ANTERIOR E PROXIMO DIA, com base no dia selecionado. Ajuste para o preenchimento rapido e a previa do dia ficarem no topo da pagina também.”

Prompt 12:
“/commit”

Commit final gerado pelo agente após execução da suíte de testes unitários:

feat(history): add monthly spreadsheet view, bank of hours, and quick entry tools

Observações Técnicas sobre o Uso de IA no Desenvolvimento Desktop

  1. Geração de Arquitetura Inicial: O modo de execução autônoma (/goal) foi útil principalmente para evitar o trabalho braçal de montar a estrutura básica do GJS, esquemas GSettings e scripts de build.
  2. Resolução de Nuances de Plataforma: A IA facilitou a identificação de comportamentos específicos do ambiente GNOME (como o local de compilação de esquemas glib-compile-schemas e a restrição de largura do Adw.Clamp).
  3. Uso de Imagens na Depuração Visual: O envio de screenshots ajudou a identificar problemas de layout em componentes do GTK4/Libadwaita que seriam mais difíceis de descrever apenas em texto.
  4. Manutenção de Testes Unitários: Manter os testes cobrindo a lógica de cálculo de horários garantiu que as refatorações da interface não quebrassem as regras de negócio de saldo de horas.

Conclusão

Desenvolver extensões nativas para o Linux via GJS e GTK costuma ter uma curva de aprendizado chata por conta da documentação fragmentada. O uso do Antigravity CLI serviu como um acelerador para passar da ideia ao código funcional, mantendo o controle das decisões de arquitetura e UX durante todo o processo.