my-dev-clock · relógio de terminal

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.

--:--:--

CPU

███░░░░░░░
21%
8 núcleos

Git

main * ↑2 ↓1 stash 3
4 arquivos pendentes

Clima

22.4°C · parcialmente nublado
sensação 21.8° · umidade 78%
Tema (Shift+T)
Fonte (Shift+F)
Animação (Shift+A)
Tamanho — arraste (tecla s no app, 1–12)
tamanho: auto · 0 = auto

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
25:00Foco· teste aqui

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.

TeclaO que fazOnde
qSaisempre
espaçoPausa e retomatimer e cronômetro
c / w / tVai para relógio / cronômetro / timersempre
Shift+TPróximo temasempre
Shift+FPróximo estilo de dígitossempre
Shift+APróxima animaçãosempre
Shift+LRelógio na tela toda, sim/nãomodo relógio
zEsconde ou mostra todos os widgetsmodo relógio
sDigita o tamanho dos dígitos (1–12, Enter confirma)sempre
l / n / + − / rVolta · próximo intervalo · ±1 min · reiniciacronômetro / timer
Home / End · PageUp / PageDown · roda do mouseRola o widget em foco ou sob o cursormodo 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)
TemaCara
defaultUsa a cor de --color, ou verde.
matrixVerde fósforo.
neonMagenta e ciano, alto contraste.
systemAs cores do próprio terminal, sem impor paleta.
fireLaranja e vermelho.
iceAzuis 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