npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

remotepad

v0.1.0

Published

Seu celular como superfície de controle programável para o PC — deck de botões que muda sozinho com o programa em foco e mostra a saída dos comandos

Readme

remotepad

CI

Seu celular como superfície de controle programável para o PC — sem app de loja, sem conta, sem nuvem. Um comando no terminal, um QR code, e a tela do celular vira um deck de botões que muda sozinho conforme o programa que está em foco e mostra a saída dos comandos em tempo real.

Sim, é uma alternativa ao Stream Deck. E é bem mais que isso: o celular não é só entrada, é também tela.


Começando

Precisa de Node 22 ou mais novo. Windows é a plataforma suportada nesta versão — o pacote declara os: win32, então em macOS ou Linux o npm install recusa na hora, em vez de instalar algo que só falharia no primeiro toque.

npx remotepad init

Isso cria um deck.yaml de exemplo no diretório atual. Depois:

npx remotepad

O terminal mostra um QR code. Aponte a câmera do celular, abra o link e confira se o número de dez dígitos que aparece no celular é o mesmo que está no terminal — é essa conferência que garante que você pareou com o seu PC, e não com outra pessoa na rede.

O navegador vai avisar sobre o certificado. Isso é esperado: o remotepad gera um certificado próprio no primeiro boot. A confiança de verdade não vem dele, vem das chaves trocadas no pareamento.


Montando os botões

Há dois caminhos, e os dois escrevem o mesmo arquivo.

Pelo navegador do PC

Com o remotepad rodando, abra:

https://127.0.0.1:3000/config

Clique num botão para editar, em + botão para criar. Salvar grava o deck.yaml e o celular muda na hora.

Não é preciso saber atalho nenhum. A ação sai de uma lista de mais de 90 prontas, com busca:

| Categoria | O que tem | |---|---| | Mídia | mudo, volume, play/pause, faixa anterior e próxima | | Edição | copiar, colar, recortar, desfazer, refazer, salvar, localizar, imprimir… | | Tela | print, recorte, print da janela, gravar tela, projetar | | Janelas | alternar janela, áreas de trabalho virtuais, encaixar, maximizar | | Sistema | bloquear, explorador, gerenciador de tarefas, emoji, histórico de cópia | | Navegador | abas, voltar/avançar, zoom, favoritos, downloads, ferramentas do dev | | Código | paleta de comandos, terminal, buscar no projeto, depurar, Git | | Reunião | microfone, câmera, mão levantada e compartilhar tela no Teams |

Quem já sabe o atalho continua podendo digitá-lo direto, junto com comando de shell e requisição HTTP.

Botões que abrem programas

Escolha Abrir um programa em Ação e o editor lista o que está instalado na máquina — lido do Menu Iniciar, com o ícone real de cada programa. Buscar "spot" acha o Spotify; escolher já preenche o nome e o ícone do botão.

Funciona com programas comuns e com aplicativos da Microsoft Store. O botão abre e responde na hora — o remotepad não fica esperando você fechar o programa, e encerrar o remotepad não fecha o que ele abriu.

As ferramentas do próprio Windows (Editor do Registro, Prompt de Comando, consoles administrativos) aparecem numa seção separada, no fim: são programas legítimos, mas são dezenas, e não devem disputar espaço com o que você instalou.

Instalou um programa com o remotepad aberto? O botão ↻ ao lado da busca procura de novo.

No deck.yaml isso vira:

- type: key
  label: Spotify
  icon: 'app:spotify'
  action: { open: 'C:\Users\você\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Spotify.lnk' }

O alvo é o atalho, e não o executável, de propósito: o .lnk carrega argumentos e diretório de trabalho, e resolve caminhos que mudam a cada atualização — o Discord instala em app-1.0.9253, e esse número muda sozinho.

+ página oferece páginas inteiras montadas — Mídia, Reunião, Edição, Janelas, Captura, Navegador, Editor de código, Sistema — em vez de uma grade vazia. A de Editor de código já vem com a regra de foco: ela assume sozinha quando o VS Code está na frente.

Cada botão tem um ícone, escolhido numa grade de mais de 60. É ele que faz o deck ser lido de relance no celular: numa tela de 6", a forma é reconhecida antes de a palavra ser lida.

O editor só abre no computador que roda o remotepad. Nem da rede, nem do celular pareado, nem de outra aba do navegador: quem escreve o deck.yaml escolhe que comandos esta máquina executa, e parear autoriza mandar as ações que o deck declara — não reescrever a lista delas.

Salvar pelo editor reescreve o arquivo a partir da estrutura, então comentários se perdem. Se o seu deck.yaml tem comentários que importam, edite-o à mão.

Pelo editor de texto

O deck.yaml é a fonte da verdade. Editar e salvar recarrega no celular sem reiniciar nada, e o arquivo continua versionável, revisável em PR e compartilhável — o que nenhum concorrente com editor gráfico e banco local oferece.


O deck.yaml

version: 1

settings:
  port: 3000
  theme: dark
  haptics: true

pages:
  # Página padrão: vale quando nenhuma regra de foco casa.
  - id: home
    grid: [3, 2]
    widgets:
      - type: key
        label: Bloquear
        action: { keys: meta+l }

  # Assume sozinha quando o VS Code está em foco.
  - id: dev
    when: { process: [Code.exe, cursor.exe] }
    grid: [3, 2]
    widgets:
      - type: key
        label: Testes
        action: { run: npm test }
        output: stream          # a saída aparece na tela do celular

      - type: toggle
        label: Mic
        action: { keys: ctrl+shift+m }
        color: { on: "#22c55e", off: "#ef4444" }

      - type: key
        label: Salvar tudo
        # o host traz a janela para frente antes de mandar a tecla
        action: { keys: ctrl+k, target: Code.exe }

Editar e salvar o arquivo recarrega no celular na hora — não precisa reiniciar. Se o arquivo tiver erro de sintaxe, o deck que está no ar continua funcionando e o erro aparece no terminal com a linha e o que fazer.

Widgets

| Tipo | O que faz | |---|---| | key | Botão. Toca e executa a ação. | | toggle | Botão com estado ligado/desligado, sincronizado com o host. | | slider | Valor contínuo de 0 a 1. Sem fonte de valor nesta versão — ver limitações. | | text | Só saída: mostra um valor que o host empurra. Idem. |

Ações

| Ação | Exemplo | |---|---| | keys | action: { keys: ctrl+shift+p } — atalho de teclado | | run | action: { run: npm test } — comando de shell | | http | action: { http: { url: "http://localhost:4455/cena", method: POST } } | | open | action: { open: "C:\...\Spotify.lnk" } — abre um programa instalado |

Cada ação carrega exatamente um mecanismo. Some output: stream a um run para ver a saída rolando no celular, cwd a um run para escolher o diretório, e target: <processo> a um keys para o host focar a janela certa antes de enviar a tecla.

Cada modificador só vale junto do mecanismo dele. No lugar errado ele sai, com um aviso no terminal apontando a linha — um target ao lado de um run prometia uma janela em foco que nunca aconteceria, e um output: stream numa tecla marcava na tela do celular um painel que nunca abriria. O resto do botão continua funcionando, e o deck sobe.

Já o que o remotepad não reconhece é erro, e o deck não sobe: atalho que não existe, ou campo escrito errado como key no lugar de keys. A diferença é que aqui não há correção óbvia — adivinhar seria pior do que recusar dizendo a linha.

Nos dois casos o objetivo é o mesmo: nada vira um botão que aparece na tela e não faz nada.

Teclas

Além de letras, números, f1f24 e as teclas nomeadas usuais (enter, escape, tab, setas, printscreen…), o remotepad entende as teclas de mídia, que quase nenhum teclado tem:

| Escreva | Faz | |---|---| | mute | Liga e desliga o som do sistema | | volup / volumeup | Aumenta o volume | | voldown / volumedown | Diminui o volume | | play / playpause | Toca ou pausa | | next / prev | Próxima faixa / anterior | | stop | Para a reprodução |

Modificadores: ctrl, alt, shift, meta (também aceita win, cmd, super).


Comandos

| Comando | Para quê | |---|---| | remotepad | Sobe o servidor e mostra o QR | | remotepad init | Cria um deck.yaml de exemplo | | remotepad qr | Mostra um QR novo, para parear outro aparelho (pede ao remotepad que já estiver no ar) | | remotepad devices | Lista os aparelhos pareados | | remotepad revoke <id> | Corta o acesso de um aparelho |


Como funciona a segurança

  • O QR carrega a chave pública do host e um segredo de uso único que vale 2 minutos.
  • O celular gera o próprio par de chaves e faz um handshake Noise_IK com o host — o mesmo padrão que o WireGuard usa.
  • O número de dez dígitos que aparece nas duas telas é derivado das duas chaves. Se ele bate, o handshake foi com quem você acha que foi.
  • Depois disso, o tráfego vai cifrado com chaves de sessão próprias, por cima do TLS. Mesmo que alguém consiga fazer você aceitar um certificado que não devia, não consegue ler nem forjar comando.
  • Aparelho revogado não volta por handshake. Só parear de novo, de propósito, o traz de volta.

O raciocínio por trás de cada escolha está nos comentários do código, junto do código que ele explica — src/core/identity/ para o handshake, src/core/pairing/ para o QR e o fingerprint.


Limitações conhecidas

Coisas que não funcionam nesta versão, ditas na cara em vez de descobertas no uso:

  • Só Windows. A troca de página por foco usa a API de janelas do Windows. macOS e Linux/X11 precisam de um adapter próprio (a porta já existe, a implementação não).
  • Um deck, um computador. Não há multi-host nem sincronização entre aparelhos.
  • Sem denylist de anti-cheat. O plano é desabilitar keys quando um anti-cheat kernel-level está rodando. Isso exige enumerar os processos da máquina, não só o em foco — fazer pela metade daria falsa sensação de proteção. Se você joga com anti-cheat, não use ações keys com o jogo aberto.
  • Sem deck.config.ts. Só YAML por enquanto.
  • slider e text não têm de onde tirar valor. Os dois existem no protocolo e o host sabe empurrar estado, mas nada nesta versão produz esse estado — não há leitura de CPU, de volume nem de mic. Na prática: um text aparece no celular mostrando um travessão, para sempre. O editor avisa isso na hora de escolher o tipo. O toggle funciona: ele acende quando a ação dá certo.
  • Comentários somem ao salvar pelo editor visual. O arquivo é reescrito a partir da estrutura. Quem depende de comentários deve editar o deck.yaml à mão.
  • Sem sensores. Giroscópio, câmera, microfone e NFC estão fora desta versão.
  • iOS apaga o pareamento depois de 7 dias sem uso. É o comportamento do Safari com sites não instalados. Instalar como PWA ajuda; se acontecer, remotepad qr e parear de novo resolve.
  • AP isolation. Em muitas redes de hotel e algumas de empresa, dispositivos não se enxergam. Nesse caso, use o hotspot do celular: o PC entra na rede do celular e o problema some.

Rodando a partir do repositório

Para trabalhar no código — ou rodar uma versão que ainda não foi publicada — compile e aponte o comando para esta pasta.

npm install
npm run build && npm run build:web
npm link

O npm link deixa remotepad disponível como comando global, apontando para esta pasta. A partir daí, em qualquer diretório:

remotepad init
remotepad

O comando rpad faz exatamente o mesmo, para quem digita muito.

Se preferir não usar npm link, chame o binário direto: node D:/caminho/para/remotepad/dist/cli/index.js.

Depois de mexer no código, recompile (npm run build para o host, npm run build:web para a PWA) — o npm link continua valendo.

Se o celular não conectar

Na ordem de probabilidade:

  1. Firewall do Windows. Na primeira vez que o Node abre uma porta, o Windows pergunta se permite; se você recusou (ou nada apareceu), libere a porta:
    netsh advfirewall firewall add rule name="remotepad" dir=in action=allow protocol=TCP localport=3000
    Rode num terminal como administrador. Para conferir se o servidor está mesmo escutando em todas as interfaces: Get-NetTCPConnection -LocalPort 3000 -State Listen.
  2. Redes diferentes. O celular precisa estar no mesmo Wi-Fi que o PC — não vale um no 5 GHz de convidados e outro no cabo, se as redes forem isoladas.
  3. AP isolation. Comum em hotel e empresa: os dispositivos não se enxergam. Saída rápida — ligue o hotspot do celular e conecte o PC nele; aí o celular e o PC estão na mesma rede e o isolamento some.
  4. O endereço do QR. O remotepad lista os endereços que usou (endereços: ...). Se aparecer algo como 172.x de Docker/WSL/Hyper-V em vez do IP da sua rede, abra uma issue — é bug de detecção.

Desenvolvimento

npm install
npm test          # suíte do host (Node) + suíte da PWA (jsdom)
npm run typecheck
npm run build     # compila o host
npm run build:web # compila a PWA
npm run test:e2e  # navegador de verdade, via Playwright

Como o código está organizado

src/core/      lógica pura, sem I/O — é onde moram as decisões
src/ports/     as interfaces das fronteiras (teclado, shell, janelas, apps…)
src/adapters/  as implementações reais, e os fakes usados nos testes
src/server/    o host: runtime, servidor HTTP/WebSocket, editor
src/cli/       os comandos do terminal
web/src/       a PWA do celular e o editor do PC (Preact)
tests/         suíte do host
e2e/           navegador de verdade

Ports & adapters de ponta a ponta: o que precisa de teclado, rede ou relógio de verdade fica atrás de uma porta. É por isso que a suíte roda inteira sem tocar no sistema — e é por isso que os testes de integração sobem o host completo com adapters falsos, em porta 0.

Duas regras que o projeto segue e que explicam boa parte do código:

  1. Nada de produção sem um teste que falhe antes. Vários defeitos deste repositório foram encontrados assim, inclusive por verificação de mutação — remover a linha e conferir se o teste realmente morde.
  2. Contrato entre as pontas vira teste. Toda tecla que o núcleo aceita tem tradução no adapter; todo ícone que o catálogo pede existe no conjunto. São falhas silenciosas por natureza — sem teste, quem descobre é o usuário.

O estado atual e o que vem a seguir estão em ROADMAP.md.