O terminal virou painel de status.
my-dev-clock é um relógio de terminal para Windows com timer,
cronômetro, contagem regressiva e fileira de painéis. Escrito em Rust, nativo no Windows:
não depende de sh, de script bash nem de utilitário do Linux.
É um executável único, sem instalador e sem nada mais para instalar.
Demonstração viva
Troque tema, fonte e animação abaixo — no app, as teclas
Shift+T, Shift+F e Shift+A fazem o mesmo.
Interpretação web do app real: hora da sua máquina em dígitos grandes,
data em português, fusos extras como o world e três painéis de exemplo.
Quatro modos
O modo inicial vem de mode na configuração, ou do subcomando na linha de comando. As teclas c, w e t alternam entre relógio, cronômetro e timer.
# hora atual, data em português e fuso opcional. É o padrão.
my-dev-clock clock --timezone America/Sao_Paulo
Timer. Aceita várias durações e corre em sequência (--duration, depois a chave durations, por fim 5 minutos). Durante a corrida: n pula o intervalo, + e - somam ou tiram um minuto, r volta ao começo, espaço pausa. Quando acaba, a tela pisca e o comando de execute roda, se houver.
my-dev-clock timer -d 25m 5m -T Foco Pausa
Cronômetro. l marca uma volta, e o rodapé mostra a volta em andamento. Ao sair, cada volta aparece na tela — e o arquivo de laps_csv recebe tudo em CSV:
my-dev-clock stopwatch --no-millis
# voltas.csv
volta,volta_s,total_s
1,12.480,12.480
2,11.901,24.381
Contagem regressiva. time aceita 2026-01-01, 20:00, 2026-12-25 20:00:00 ou horário RFC3339. continue_on_zero segue contando depois do alvo e reverse conta para cima.
my-dev-clock countdown -t 2026-01-01 -T 'Ano novo'
Aviso quando o tempo acaba
bell = true em [timer] ou [countdown] toca a campainha do terminal, além do flash na tela. Para algo mais forte, execute roda um comando — duas receitas verificadas:
# um bipe curto, sem depender de arquivo nenhum
execute = ["powershell", "-NoProfile", "-Command", "[console]::beep(880,300)"]
# um som de verdade, do próprio Windows
# execute = ["powershell", "-NoProfile", "-Command", "(New-Object Media.SoundPlayer 'C:\Windows\Media\Alarm01.wav').PlaySync()"]
Teclas
? mostra a lista completa dentro do próprio app (Esc fecha). Todo atalho de aparência confirma no rodapé o que mudou.
| Tecla | O que faz | Onde |
|---|---|---|
| q | Sai | sempre |
| espaço | Pausa e retoma | timer e cronômetro |
| c / w / t | Vai para relógio / cronômetro / timer | sempre |
| Shift+T | Próximo tema | sempre |
| Shift+F | Próximo estilo de dígitos | sempre |
| Shift+A | Próxima animação | sempre |
| Shift+L | Relógio na tela toda, sim/não | modo relógio |
| z | Esconde ou mostra todos os widgets | modo relógio |
| s | Digita o tamanho dos dígitos (1–12, Enter confirma) | sempre |
| l / n / + − / r | Volta · próximo intervalo · ±1 min · reinicia | cronômetro / timer |
| Home / End · PageUp / PageDown · roda do mouse | Rola o widget em foco ou sob o cursor | modo relógio |
Aparência de verdade
Quatro estilos de dígitos, cinco animações de fundo desenhadas atrás dos dígitos com o estilo escurecido, seis temas — mais a paleta própria custom. Salvar o config.toml recarrega tudo na hora, sem reiniciar.
bricks · slim · slant · flip
Blocos maciços, traço fino e leve, blocos inclinados como itálica, e dígitos em cartões coloridos com linha de dobradiça. A face flip liga sozinha a virada dos dígitos — metade de baixo cai primeiro, como painel de aeroporto — e flip = true liga em qualquer face.
# quadro real do renderizador, estilo bricks
████████ ████████████ ████████████ ████████████
████████ ████████████ ████████████ ████████████
████ ████ ████ ████ ████ ████
████ ████████████ ████ ████ ████████████
████████████ ████████████ ████████████ ████████████
matrix · plasma · waves · stars
Colunas caindo com cabeça clara, campos senoidais somados, anéis concêntricos do centro, estrelas piscando no lugar. O tempo avança em passos inteiros de quadro (animation_fps, 12 por padrão): movimento picotado de terminal, e o mesmo instante sempre desenha o mesmo quadro — animação testável, não só olhável.
[clock]
font = "flip"
animation = "matrix"
animation_fps = 10
fill = true # relógio na área toda (Shift+L alterna)
| Tema | Cara |
|---|---|
| default | Usa a cor de --color, ou verde. |
| matrix | Verde fósforo. |
| neon | Magenta e ciano, alto contraste. |
| system | As cores do próprio terminal, sem impor paleta. |
| fire | Laranja e vermelho. |
| ice | Azuis claros. |
Onze painéis, zero script
Declarados em [[clock.widgets]], aparecem embaixo do relógio em 2, 4 ou 6 colunas conforme a largura (teto em max_columns). Todo widget aceita title, refresh_secs (padrão 900) e timeout_secs (padrão 30). Dividir a janela não esconde nada: menos largura vira menos colunas e mais linhas, e o que não couber ganha a faixa +N painel(ns) sem espaço em vez de sumir em silêncio. Só widgets visíveis rodam.
git
Branch, sujeira, à frente e atrás do remoto, stash — tudo numa chamada só. Olha o repositório atual, ou o de path.
Estar num repositório, ou path.
cpu · mem · disk · net
Uso do processador com barra, RAM usada e total, espaço em disco com barra, tráfego desde o boot mais a taxa desde a leitura anterior. Nativos, sem configuração — disco aceita mount, rede aceita interface.
Não precisam de nada.
commits
Seus últimos commits em todos os projetos varridos: projeto · quando · assunto. roots varre pastas até depth; paths lista repositórios avulsos.
roots ou paths.
http
Status e um valor tirado do JSON de um endereço — para vigiar um dev server. Caminho com pontos (.items.0.name), expect opcional diz se o valor bate. Um 4xx/5xx é informação, não erro do widget.
url.
weather
Agora e os próximos dias: temperatura, sensação, umidade, vento. Usa a Open-Meteo, que não pede chave de API.
city ou lat/lon.
gh
O que está pendente para você: revisões, seus PRs (com rascunho, aprovado, mudanças pedidas), issues. Tudo numa única chamada GraphQL — ~1,2 s contra 4,4 s das três REST anteriores.
gh auth login.
actions
Últimas execuções de CI marcadas com ✓ ✗ … ×. Usa o repositório atual, ou o de repo.
gh auth login.
command
Qualquer comando que imprima algo e termine. String só passa pelo shell (cmd /C); lista executa direto, sem shell. Recebe o tema atual em MY_DEV_CLOCK_THEME. Estoura o tempo? Morre junto com tudo que iniciou, via Job Object — fechar o app não deixa processo pendurado.
command.
Receitas prontas
Copie, cole no config.toml, ajuste os caminhos. Crie a base com my-dev-clock --init.
[default]
mode = "timer"
color = "lightred"
[timer]
durations = ["25m", "5m"]
titles = ["Foco", "Pausa"]
bell = true
repeat = true
[[clock.widgets]]
kind = "gh"
title = "Pendências"
[clock]
font = "flip"
max_columns = 5
[[clock.widgets]]
kind = "git" # Repo · refresh_secs = 15
[[clock.widgets]]
kind = "commits" # Meus commits · roots = ["~/dev"]
[[clock.widgets]]
kind = "gh" # Pendências · refresh_secs = 600
[[clock.widgets]]
kind = "actions" # CI · refresh_secs = 120
[[clock.widgets]]
kind = "cpu" # CPU · refresh_secs = 3
[clock]
max_columns = 4
[[clock.widgets]]
kind = "http" # API · url = "http://localhost:3000/health" · path = ".status" · expect = "ok"
[[clock.widgets]]
kind = "cpu" # refresh_secs = 3
[[clock.widgets]]
kind = "mem" # refresh_secs = 5
[[clock.widgets]]
kind = "disk" # refresh_secs = 60
[[clock.widgets]]
kind = "net" # refresh_secs = 10
[default]
mode = "clock"
size = 6
show_seconds = false
[clock]
fill = true
animation = "matrix"
animation_fps = 10
# combine com --theme matrix, ou themes = ["matrix"]
Configuração e linha de comando
O app lê o primeiro arquivo que existir: --config, %XDG_CONFIG_HOME%\my-dev-clock\config.toml, %APPDATA%\my-dev-clock\config.toml, %USERPROFILE%\.config\my-dev-clock\config.toml. Precedência de exibição: flag, seção do modo, [default], padrão embutido.
Diagnóstico: --check
Mostra de onde veio a configuração, a aparência resolvida e roda cada widget uma vez. Primeiro lugar para olhar quando um painel não aparece.
my-dev-clock --check
configuração: …\AppData\Roaming\my-dev-clock\config.toml
tema inicial: default
fonte: bricks · animação: none (12 fps)
Scripts: --print
Imprime uma linha e sai, sem abrir a tela alternativa — para tmux, prompt ou barra de status. Marcador desconhecido fica como está, para o erro aparecer.
my-dev-clock --print "{time} · {git} · cpu {cpu} · ram {mem} · {host}"
14:09:15 · main * · cpu 15% · ram 68% · DESKTOP-8KQ2M4
Por dentro
Nunca trava o desenho
Cada widget roda numa thread própria e devolve o texto por um canal; o laço de desenho nunca espera por um comando.
Geometria corrigida
Animações corrigem a proporção da célula — duas vezes mais alta que larga — senão todo círculo sai esticado na vertical.
Determinismo
Tempo injetado e aleatoriedade de semente fixa: o mesmo instante sempre desenha o mesmo quadro. Testes de renderização conferem fontes e animações sem ninguém olhar.
Processos que morrem juntos
Widgets de comando rodam em Job Object com kill-on-close: o processo e tudo que ele iniciou morrem junto.
Instalação
Binário pronto
Baixe o my-dev-clock.exe na página de releases e rode. Na primeira execução o Windows mostra “O Windows protegeu o seu PC” (binário sem assinatura): Mais informações → Executar assim mesmo; o aviso não volta. Para chamar de qualquer pasta, ponha o .exe numa pasta do PATH.
.\my-dev-clock.exe
my-dev-clock --init # grava o config.toml comentado
Compilar do código
Precisa de Rust estável e do toolset C++ do Visual Studio (o linker do Windows). Se o cargo reclamar de link.exe, use o build.cmd — ele repassa qualquer comando do cargo.
cargo build --release
.\target\release\my-dev-clock.exe
.\build.cmd test
.\build.cmd clippy --all-targets -- -D warnings