Tarefa Atual
Extensão de VS Code para quem trabalha em várias janelas, de várias empresas, ao mesmo tempo.
Dois eixos independentes:
- Empresa → a cor da janela. Cor você reconhece sem ler. Você aprende "azul = ACME"
e identifica a janela de canto de olho.
- Tarefa → o texto na barra de status. Muda o tempo todo, então precisa ser lido.
🟦 🛠 Refatorar o login · 1h 20m 🏢 ACME
🟩 🛠 Corrigir o checkout · 12m 🏢 Contoso
🟧 🛠 Revisar PR · 3h 🏢 Iniciativa própria
A cor pinta a barra de status inteira — bem mais área do que só um textinho no rodapé.
Se quiser ainda mais destaque, tarefaAtual.tintActivityBar pinta também a barra lateral
de ícones.
Como funciona
A empresa fica gravada por pasta. Definiu uma vez, toda vez que você reabrir aquele
projeto a janela volta com a cor certa.
A tarefa é por janela. A lista de tarefas é compartilhada entre todas as janelas,
mas cada janela lembra em qual você está.
A tarefa mora na aba. Escolheu uma tarefa com um arquivo aberto? Os dois ficam
ligados, e a aba ganha um selo de 2 letras na cor da empresa. Cada aba tem a sua
tarefa: alternando entre elas, a barra e o cronômetro acompanham.
A aba ativa manda. Aba sem tarefa atribuída mostra "Sem tarefa" — ela não herda a
tarefa da aba anterior, senão as abas deixariam de ser independentes. Pra voltar ao
modelo de uma tarefa por janela, desligue tarefaAtual.taskPerTab.
Vale pra qualquer tipo de aba: arquivos, diffs, notebooks e webviews (sessões do
Claude Code, preview de Markdown, editores customizados).
Criar é digitar e dar Enter. Nos seletores de empresa e de tarefa, o texto que você
digita filtra a lista — e, se não casar com nada, vira o nome do item novo. Sem uma
segunda caixa pedindo o mesmo nome.
Lembretes periódicos ("ACME — Refatorar o login, há 40m") no intervalo que você
escolher. Só a janela em foco cobra, pra não virar spam com várias abertas.
Tempo acumulado por tarefa, somando todas as sessões.
Comandos
Todos na paleta (Cmd+Shift+P) sob Tarefa Atual:
| Comando |
Atalho |
O que faz |
| Definir a empresa desta janela |
Cmd+Alt+E |
Escolhe a empresa e pinta a janela |
| Trocar de tarefa |
Cmd+Alt+T |
Menu de tarefas + criar nova / pausar / concluir |
| Onde eu estou? |
Cmd+Alt+W |
Mostra empresa, tarefa e há quanto tempo |
| Nova tarefa |
— |
Cria já vinculada à empresa da janela |
| Concluir tarefa atual |
— |
Fecha a tarefa e oferece a próxima |
| Pausar |
— |
Fica sem tarefa nesta janela |
| Gerenciar tarefas |
— |
Renomear, trocar de empresa, zerar tempo, excluir |
| Gerenciar empresas |
— |
Renomear, mudar a cor, excluir |
| Fazer a tarefa atual morar nesta aba |
— |
Liga a aba ativa à tarefa em andamento |
| Desligar esta aba da tarefa |
— |
Remove o vínculo da aba ativa |
| Limpar cor e título desta janela |
— |
Desfaz tudo que foi gravado no projeto |
| Conectar ao Claude Code |
— |
Liga a ponte e instala o hook que avisa o Claude da tarefa |
| Diagnóstico |
— |
Mostra a versão, a aba ativa e o mapa de aba → tarefa |
Configurações
| Chave |
Padrão |
Descrição |
tarefaAtual.reminderMinutes |
30 |
Intervalo do lembrete em minutos. 0 desliga. |
tarefaAtual.taskPerTab |
true |
A tarefa mora na aba e volta sozinha ao reabrir o arquivo. |
tarefaAtual.decorateTabs |
true |
Selo de 2 letras na aba, na cor da empresa. |
tarefaAtual.taskIcon |
tools |
Codicon quando há tarefa. |
tarefaAtual.idleIcon |
question |
Codicon quando não há tarefa. |
tarefaAtual.remindWhenIdle |
true |
Cobrar também quando não há tarefa marcada. |
tarefaAtual.tintWindow |
true |
Pintar a janela com a cor da empresa. |
tarefaAtual.tintActivityBar |
false |
Pintar também a barra lateral de ícones. |
tarefaAtual.tintTitleBar |
false |
Pintar a barra de título (exige window.titleBarStyle: custom). |
tarefaAtual.setWindowTitle |
true |
Pôr a tarefa e a empresa no título da janela (Mission Control). |
tarefaAtual.showCompanyInStatusBar |
true |
Mostrar o nome da empresa na barra. |
tarefaAtual.showElapsed |
true |
Mostrar o tempo decorrido. |
tarefaAtual.statusBarAlignment |
left |
Lado da barra de status. |
tarefaAtual.highlightStatusBar |
false |
Destaque amarelo no item da tarefa. Só vale em janela sem empresa, que portanto não está pintada. |
tarefaAtual.agentBridge |
false |
Deixar o Claude Code anotar a tarefa sozinho. |
tarefaAtual.fallbackCompany |
"" |
Empresa usada quando a janela não tem uma. Vazio pergunta uma vez por projeto. |
Deixar o Claude Code anotar por você
Com tarefaAtual.agentBridge ligado, o Claude Code passa a manter o rodapé em dia: mudou
de assunto na conversa, ele começa a tarefa; terminou o que você pediu, ele pergunta se
pode concluir. Você não digita nada — só acompanha a barra de status.
Pra ligar: Tarefa Atual: Conectar ao Claude Code. Ele liga a configuração, instala uma
CLI em ~/.tarefa-atual/tarefa.js e oferece pôr o hook no .claude/settings.json deste
projeto ou no do seu home. O hook é uma linha só, que a cada mensagem sua conta ao Claude
qual é a tarefa da janela.
Se você trabalha em várias janelas de várias empresas, escolha o do home: vale em
qualquer pasta que você abrir, sem commitar nada no repositório de cliente nenhum, e é
inerte onde a ponte não está ligada — sem arquivo de estado, o hook não imprime nada.
Escolha só um dos dois: o Claude Code soma os hooks das duas origens, então um projeto que
tenha o seu e o do home recebe o mesmo contexto duas vezes por mensagem.
Concluir é sempre no clique. O agente acha que terminou assim que para de escrever
código — antes de você olhar, testar e dizer que serve. Então ele só levanta a mão: aparece
um aviso "O Claude Code diz que terminou X. Concluir?" e quem fecha a tarefa é você.
Começar uma tarefa, esse sim é automático — errar o nome custa um rename, não uma tarefa
fechada por engano.
Como a conversa acontece:
Claude Code --escreve--> ~/.tarefa-atual/inbox.jsonl --lê--> janela do VS Code
janela do VS Code --publica--> ~/.tarefa-atual/estado/ --lê--> Claude Code
Tudo no seu home, fora do projeto: nada de arquivo de controle aparecendo no git status
do cliente. Cada linha da caixa carrega a pasta do projeto, e só a janela daquela pasta
obedece — é isso que faz o comando cair na janela certa com várias empresas abertas ao
mesmo tempo. Comando com mais de 5 minutos é ignorado, pra reabrir uma janela não
reexecutar a fila de ontem.
O que esperar de bom e de ruim:
- Quem decide é o modelo. Ele vai dividir demais de vez em quando, ou insistir numa
tarefa que já virou outra coisa. Trocar e renomear na mão continua funcionando igual, e
a correção que você faz vale — na mensagem seguinte ele já lê o rótulo novo.
- Com
taskPerTab ligado, a tarefa nasce morando na aba do Claude Code, que é a aba
ativa na hora. Clicar num arquivo sem tarefa mostra "Sem tarefa", como em qualquer outra
aba. Se preferir a tarefa valendo pra janela inteira, desligue tarefaAtual.taskPerTab.
- Duas janelas na mesma pasta obedecem as duas ao mesmo comando. É raro, e não quebra
nada, mas as duas vão trocar de tarefa juntas.
- Precisa de
node no PATH — o mesmo que o Claude Code já exige.
Pra desligar: tarefaAtual.agentBridge de volta pra false. O hook pode ficar onde está;
sem a ponte ligada ele não imprime nada. Pra remover de vez, apague a entrada
UserPromptSubmit do .claude/settings.json e a pasta ~/.tarefa-atual.
A CLI também serve na mão, se você quiser amarrar em outra coisa (um script de git hook,
outro agente):
node ~/.tarefa-atual/tarefa.js iniciar "Refatorar o login"
node ~/.tarefa-atual/tarefa.js estado # o que a janela está mostrando, em JSON
node ~/.tarefa-atual/tarefa.js ajuda
E quando a janela não tem empresa?
Tarefa criada numa janela sem empresa nasceria órfã. Era um detalhe enquanto tarefa se
criava na mão, uma de cada vez — com o agente criando tarefa em qualquer pasta que você
abrir, a maioria nasceria assim.
Então, na primeira tarefa de uma pasta sem empresa, a extensão pergunta uma vez:
Esta janela ainda não tem empresa
🏢 ACME (as empresas que você já tem)
🏢 Contoso
👤 Jeffo trabalho próprio
+ Nova empresa… (ou digite o nome e dê Enter)
⊘ Deixar sem empresa não pergunta de novo neste projeto
A sugestão de trabalho próprio vem do seu git config user.name — o nome que você já
escolheu pra se chamar, e curto de propósito. Sem git, cai no usuário do sistema.
A resposta fica gravada por pasta, junto com a empresa. Uma pergunta na vida de cada
projeto, não uma por tarefa. Descartar com Esc não grava nada: a tarefa nasce sem empresa
e a pergunta volta na próxima — pra não ser mais perguntado existe o "Deixar sem empresa".
Quem não quer diálogo nenhum preenche tarefaAtual.fallbackCompany. Aí a janela adota
aquela empresa calada, e você recebe um aviso uma vez por pasta ("Esta janela não tinha
empresa e adotou X. Trocar?"). Esse aviso importa: adoção calada é o que erra quando você
abre a pasta de um cliente novo e esquece de definir a empresa — e trabalho de cliente
registrado como seu é um dado errado que ninguém percebe depois.
Como empresa é a cor da janela, adotar significa pintar, o que grava
.vscode/settings.json no projeto — o mesmo preço de qualquer troca de empresa, com a
mesma saída (tintWindow: false).
Como uma aba é identificada
Abas baseadas em arquivo (texto, diff, notebook, editor customizado) são identificadas
pela URI — estável, sobrevive a renomear a aba e a reabrir a janela.
Webviews não têm URI. A API do VS Code expõe delas apenas o viewType e o rótulo, então
a chave é viewType::rótulo. Consequência: renomear a aba desfaz o vínculo com a
tarefa, e duas abas de mesmo tipo e mesmo rótulo compartilham a tarefa. Não há como
contornar — o VS Code não dá identidade estável a uma webview.
O selo de 2 letras também só aparece em abas de arquivo, porque decoração é resolvida
por URI. Em webview, a tarefa aparece só na barra de status.
O caminho inverso não existe: a extensão não consegue pôr o nome da tarefa no título
da aba. Título de aba de arquivo vem do nome do arquivo, e título de webview pertence à
extensão que criou aquela aba. Não há API para nenhum dos dois. Se quiser que os nomes
batam, renomeie a aba primeiro (pela extensão dona dela) e crie a tarefa com esse nome.
O preço da cor: .vscode/settings.json
Não existe API pra pintar a janela. O único caminho é gravar
workbench.colorCustomizations nas configurações do workspace — ou seja, num
.vscode/settings.json dentro da pasta do projeto. O mesmo vale pro window.title.
A extensão mexe apenas nas chaves que ela gerencia e preserva qualquer outra
customização que você tenha feito à mão. Mas o arquivo aparece no projeto — e o
window.title é regravado a cada troca de tarefa, o que com taskPerTab ligado
significa a cada troca de aba. Se essa reescrita constante incomodar, desligue
tarefaAtual.setWindowTitle; a cor não tem esse problema, porque só muda quando você
troca de empresa.
Se o projeto for versionado, provavelmente você quer:
echo ".vscode/settings.json" >> .gitignore
Pra desfazer numa janela: Tarefa Atual: Limpar cor e título desta janela.
Instalação
Gere o pacote e instale pelo próprio VS Code:
npm install
npm run package # gera tarefa-atual-<versão>.vsix
O npm run package chama o vsce. Se ele não estiver instalado:
npx @vscode/vsce package --no-dependencies
Cmd+Shift+P → Extensions: Install from VSIX… → escolha o arquivo.
Pela linha de comando, se o code estiver no PATH (no macOS ele mora dentro do app, em
/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code):
code --install-extension tarefa-atual-<versão>.vsix --force
Nos dois casos, Developer: Reload Window depois — o host de extensões não troca de
versão sozinho.
Mandar pra outra pessoa
O .vsix é um arquivo só, sem dependências — mande por Slack, e-mail ou Drive. Quem
recebe instala assim:
Cmd+Shift+P (ou Ctrl+Shift+P no Windows/Linux)
- Extensions: Install from VSIX…
- Escolhe o arquivo e recarrega a janela
Não precisa de conta, de Node nem de nada instalado. Funciona em VS Code, Cursor e
VSCodium. O único requisito é VS Code 1.85 ou mais novo.
Se o Gmail ou o Slack bloquearem a extensão .vsix, zipe o arquivo antes de enviar.
Desenvolvimento
Pra iterar sem reempacotar, instale como symlink:
ln -sfn "$PWD" ~/.vscode/extensions/tarefa-atual
npm run watch
Depois de cada mudança, Cmd+Shift+P → Developer: Reload Window nas janelas abertas.
Alternativa isolada, que não afeta suas janelas reais: abra esta pasta e aperte F5 —
sobe uma segunda janela ("Extension Development Host") só com a extensão carregada.
Não use o symlink e o .vsix ao mesmo tempo: são duas cópias do mesmo id de extensão,
e o VS Code carrega uma delas de forma imprevisível.
Pra remover o symlink, desinstale em vez de apagar:
code --uninstall-extension local.tarefa-atual
Um rm ~/.vscode/extensions/tarefa-atual não avisa o VS Code: o índice
~/.vscode/extensions/extensions.json continua com a entrada apontando pra uma pasta que
não existe mais, e a extensão vira um card fantasma na lista, com um aviso de
package.json inexistente. Se isso já aconteceu, o mesmo --uninstall-extension limpa o
índice — a instalação boa, com o id jeffogranetto.tarefa-atual, não é afetada.
Estrutura
- src/extension.ts — toda a extensão: estado, cores, barra de status, comandos, lembretes.
- src/bridge.ts — a ponte com o agente: caixa de entrada, estado publicado, instalação do hook.
- bin/tarefa.js — a CLI que o Claude Code chama. Sem dependências, copiada pro home na ativação.
- package.json — comandos, atalhos, cores e configurações declarados pro VS Code.
- scripts/make-icon.js — gera o
icon.png sem dependências (npm run icon).