Files
pulse-memory/pulse-dev/agents/backend/agent.js
T
Pulse Agent adeb4dad33 feat: pulse-dev — dev environment full-stack com hot reload + agentes + taskboard + vault Obsidian
- Stack Swarm 'dev': redis + taskboard + frontend HMR (Vite) + backend HMR (tsx) + 5 agents
- TaskBoard standalone React com Redis pub/sub e BLPOP queue
- Backend API Express: /tasks /agents /health com hot reload
- Agentes: 2 FE (frontend), 2 BE (backend), 1 DevOps (parallel workers)
- Vault Obsidian: /root/Obsidian-Pulse/ com estrutura Inbox/Projetos/Docker/Dev/Codex/Logs/Memorias/Templates
- Skill obsidian-vault-linker instalada e documentada
- Caddy labels: board.octal.tec.br + api.octal.tec.br + frontend.octal.tec.br
- Protocolo task queue Redis documentado em MEMORY.md
2026-05-20 19:40:54 -03:00

57 lines
2.2 KiB
JavaScript

import Redis from 'ioredis'
const redis = new Redis({ host: 'redis', port: 6379, lazyConnect: true })
const QUEUE = 'dev-tasks'
const LOG = 'dev-logs'
function log(level, msg) {
const line = JSON.stringify({ ts: new Date().toISOString(), level, msg })
redis.publish(LOG, line).catch(() => {})
console.log(`[${level}] ${msg}`)
}
async function claimTask(task) {
await redis.hset(`agent:agent-backend:task`, task.id, JSON.stringify(task))
await redis.hset(`agent:agent-backend`, 'status', 'busy')
await redis.hset(`agent:agent-backend`, 'current_task', task.title)
await redis.publish(LOG, JSON.stringify({ ts: new Date().toISOString(), level: 'AGENT', msg: `Backend pegou: "${task.title}"` }))
task.status = 'in_progress'
task.assignee = 'agent-backend'
await redis.set(`task:${task.id}`, JSON.stringify(task))
log('AGENT', `▶️ Processando: ${task.title}`)
await new Promise(r => setTimeout(r, Math.random() * 6000 + 3000))
task.status = 'done'
task.done_at = new Date().toISOString()
await redis.set(`task:${task.id}`, JSON.stringify(task))
await redis.hset(`agent:agent-backend`, 'status', 'idle')
await redis.hdel(`agent:agent-backend:task`, task.id)
await redis.hincrby('agent:agent-backend', 'tasks_done', 1)
await awaitingTask(task)
}
async function awaitingTask(task) {
await redis.hset(`agent:agent-backend`, 'status', 'idle')
await redis.hdel(`agent:agent-backend:task`, task.id)
log('AGENT', `✔️ Concluído: ${task.title}`)
}
async function run() {
await redis.connect()
await redis.set('agent:agent-backend', JSON.stringify({
id: 'agent-backend', role: 'backend', status: 'online',
started_at: new Date().toISOString(), tasks_done: 0,
}))
log('AGENT', 'Backend Agent online — aguardando tarefas')
while (true) {
const [_, taskId] = await redis.blpop(QUEUE, 60)
if (!taskId) { await new Promise(r => setTimeout(r, 1000)); continue }
const raw = await redis.get(`task:${taskId}`)
if (!raw) continue
const task = JSON.parse(raw)
if (task.domain !== 'backend' && task.domain !== 'fullstack') {
await redis.rpush(QUEUE, taskId); continue
}
await claimTask(task)
}
}
run().catch(e => { console.error(e); process.exit(1) })