O que decision-board faz?
SKILL.md da Anthropic para quadros de decisão interativos offline — items.json → HTML → usuário escolhe pendente/aceitar/rejeitar → shell heredoc → agente implementa → reprodução de diff. Zero dependências npm, apenas Node 18+.
Funcionamento
- O agente lê um arquivo
items.jsoncontendo uma lista de decisões (cada uma comid,descricao,acaoa ser executada, e talvezstatusinicial). - Gera uma página HTML estática usando um template embutido no SKILL.md.
- O usuário abre o HTML no navegador e interage com os botões "Pendente", "Aceitar" ou "Rejeitar" para cada item.
- Ao clicar em "Aceitar" ou "Rejeitar", a página gera um bloco de código shell heredoc com um comando específico (ex:
aceitar.shourejeitar.sh). - O agente detecta a saída e executa o heredoc, implementando as ações associadas.
- Após a execução, o agente pode gerar um diff para mostrar as mudanças feitas.
Requisitos
- Node.js 18+ instalado.
- Nenhuma dependência npm externa.
- Agente compatível com SKILL.md (ex: Claude Code, Cursor).
Exemplo de items.json
[
{
"id": "1",
"descricao": "Atualizar pacote lodash para v4.17.21",
"acao": "npm install [email protected] --save",
"status": "pendente"
},
{
"id": "2",
"descricao": "Corrigir bug na função de login",
"acao": "sed -i 's/old_function/new_function/g' src/auth.js",
"status": "pendente"
}
]
Template HTML
O agente gera um arquivo HTML com um template como este:
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<title>Quadro de Decisões</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: auto; padding: 20px; }
.item { border: 1px solid #ddd; padding: 15px; margin: 10px 0; border-radius: 5px; }
.pendente { background-color: #fff3cd; }
.aceitar { background-color: #d4edda; }
.rejeitar { background-color: #f8d7da; }
button { margin-right: 5px; }
#saida { white-space: pre-wrap; background: #f4f4f4; padding: 10px; margin-top: 20px; }
</style>
</head>
<body>
<h1>Quadro de Decisões</h1>
<div id="itens"></div>
<h2>Comandos a executar</h2>
<pre id="saida">Nenhum comando ainda.</pre>
<script>
// Carrega items do JSON (embutido ou lido pelo agente)
const items = /* items.json embutido aqui */;
function render() {
const container = document.getElementById('itens');
container.innerHTML = '';
items.forEach(item => {
const div = document.createElement('div');
div.className = `item ${item.status}`;
div.innerHTML = `
<p><strong>${item.id}</strong>: ${item.descricao}</p>
<p>Ação: <code>${item.acao}</code></p>
<button onclick="mudarStatus('${item.id}', 'pendente')">Pendente</button>
<button onclick="mudarStatus('${item.id}', 'aceitar')">Aceitar</button>
<button onclick="mudarStatus('${item.id}', 'rejeitar')">Rejeitar</button>
`;
container.appendChild(div);
});
}
function mudarStatus(id, novoStatus) {
const item = items.find(i => i.id === id);
if (item) {
item.status = novoStatus;
render();
gerarComandos();
}
}
function gerarComandos() {
const saida = document.getElementById('saida');
let comandos = '';
items.forEach(item => {
if (item.status === 'aceitar') {
comandos += `cat << 'EOF' | sh\n${item.acao}\nEOF\n`;
} else if (item.status === 'rejeitar') {
comandos += `echo "Rejeitado: ${item.id}"\n`;
}
});
saida.textContent = comandos;
}
render();
</script>
</body>
</html>
Fluxo de trabalho
- O agente cria
items.jsoncom base na conversa ou em dados fornecidos. - O agente gera o HTML e informa o caminho (
file:///...). - O usuário abre o HTML e faz suas escolhas.
- O usuário copia os heredocs gerados e cola no terminal (ou o agente captura).
- O agente executa os heredocs e aplica as mudanças.
- O agente mostra um
git diffpara confirmar.
Dicas
- Use
node -e "..."para gerar o HTML dinamicamente, se necessário. - O nome do arquivo HTML pode ser
decision-board.html. - Os heredocs gerados são seguros para shell, pois usam
<< 'EOF'(sem expansão de variáveis).
Licença
MIT