TUI ↔️ DAEMON INTEGRATION - COMPLETADO
✅ CAMBIOS REALIZADOS
1. src/tui/tui.ts (Integración)
Imports agregados:
import {
createInteractionLock,
releaseInteractionLock,
refreshInteractionLock,
} from "../omega/daemon-cooperative.js";
Variables de estado (línea ~380):
const workspaceRoot = process.cwd();
let cancelLockRefresh: (() => Promise<void>) | null = null;
Al conectar con gateway (línea ~550):
// Create interaction lock for daemon coordination
try {
cancelLockRefresh = await refreshInteractionLock(workspaceRoot, 10_000);
} catch (error) {
console.warn("[TUI] Warning: Failed to create interaction lock:", error);
}
Función requestExit modificada (ahora async):
const requestExit = async () => {
if (exitRequested) {
return;
}
exitRequested = true;
client.stop();
stopTuiSafely(() => tui.stop());
// Release daemon interaction lock
if (cancelLockRefresh) {
try {
await cancelLockRefresh();
} catch (error) {
console.warn("[TUI] Warning: Failed to release interaction lock:", error);
}
}
process.exitCode = 0;
};
Cambios en handlers de eventos → void requestExit():
- Línea ~942:
if (decision.action === "exit")→void requestExit() - Línea ~952:
editor.onCtrlD→void requestExit() - Línea ~1031:
sigtermHandler→void requestExit()
(Usamos void para ejecutar async sin bloquear el handler síncrono)
FLUJO COMPLETO (TUI ↔️ DAEMON)
Usuario abre: pnpm openskynet tui
↓
runTui() se ejecuta
↓
[TUI] → refreshInteractionLock(cwd, 10_000)
├─ Crea .interaction-lock
├─ Configura intervalo cada 10s para actualizar timestamp
└─ Retorna función cancelLockRefresh()
↓
[DAEMON] → Detecta .interaction-lock existente
├─ <60s viejo = TUI activa
├─ Pausa ciclos
└─ Verifica cada 10s si lock desapareció
↓
Usuario cierra TUI (Ctrl+C, Ctrl+D, o kill signal)
↓
requestExit() se llama
├─ Detiene cliente
├─ Detiene TUI
├─ Llama await cancelLockRefresh()
│ ├─ Limpia intervalo de actualización
│ └─ Borra .interaction-lock
└─ Establece process.exitCode = 0
↓
[DAEMON] → Detecta .interaction-lock desapareció
├─ Espera un ciclo completo
└─ Reanuda ciclos normales (cada 5 min)
ARCHIVOS INVOLUCRADOS
| Archivo | Cambios |
|---|---|
src/tui/tui.ts |
✅ Integración lock create/release/refresh |
src/omega/daemon-cooperative.ts |
✅ Ya exporta las funciones necesarias |
src/omega/heartbeat.ts |
✅ Ya ejecuta runOneHeartbeatCycle() |
src/omega/daemon-cli.ts |
✅ CLI para manejar el daemon |
.interaction-lock |
🔒 Archivo temporal (creado/borrado por TUI) |
VERIFICACIÓN DE IMPORTS (Sin Ciclos)
✅ Circular dependency check:
tui.ts
↓ imports
daemon-cooperative.ts
↓ imports
fs, path (node builtins only)
No hay ciclo. tui.ts importa daemon-cooperative.ts, pero daemon-cooperative.ts NO importa nada de TUI.
PRÓXIMOS PASOS
1️⃣ Compilar y Verificar Sintaxis
# Compila TypeScript sin errores
pnpm tsc --noEmit
# Verifica que no hay imports circulares
pnpm knip
2️⃣ Test Manual (Escenario A: Sin TUI)
# Terminal 1: Inicia daemon
pnpm tsx src/omega/daemon-cli.ts install
pnpm tsx src/omega/daemon-cli.ts start
# Verifica logs (Linux)
journalctl -u openclaw-openskynet-autonomous -f
# Verifica que .interaction-lock NO existe
ls -la .interaction-lock # → No such file
Esperado:
- Daemon ejecuta ciclos cada 5 min ✅
- Logs:
[DAEMON] 🤖 Ciclo #1 - Daemon activo✅
3️⃣ Test Manual (Escenario B: TUI Abierta)
# Terminal 1: Daemon corriendo (ve paso anterior)
# Terminal 2: Abre TUI
pnpm openskynet tui
# Terminal 3: Verifica lock creado
watch 'ls -la .interaction-lock' # → Archivo existe, timestamp actualizado cada 10s
Esperado:
.interaction-lockexiste y se actualiza cada 10s ✅- Daemon logs muestran:
[DAEMON] 🧑 Interacción detectada. Pausa...✅ - Daemon NO ejecuta ciclos mientras TUI está abierta ✅
4️⃣ Test Manual (Escenario C: TUI Cierra)
# Continúa desde paso anterior
# Terminal 2: Presiona Ctrl+C en TUI
# → TUI cierra
# Terminal 3: Verifica lock
watch 'ls -la .interaction-lock' # → Desaparece inmediatamente
Esperado:
.interaction-lockdesaparece cuando TUI cierra ✅- Daemon logs: Dentro de 10s ve lock desapareció ✅
- Daemon reanuda ciclos cada 5 min ✅
5️⃣ Test Manual (Escenario D: Timeout - TUI Crash)
# Terminal 1 & 2: Daemon + TUI (como antes)
# Terminal 3: Mata TUI abruptamente
pkill -9 -f "openskynet tui"
# Verifica lock
watch 'ls -la .interaction-lock' # → Queda viejo (>60s), luego desaparece
Esperado:
.interaction-lockpermanece ~60s ✅- Daemon detecta >60s viejo → borra automáticamente ✅
- Daemon continúa sin bloquear ✅
REGRESIÓN TESTING
Asegurar que cambios no rompen TUI normal:
# TUI sin daemon (debería funcionar como antes)
# Cierra daemon primero
pnpm tsx src/omega/daemon-cli.ts stop
# TUI debería funcionar igual
pnpm openskynet tui
# Verifica que NO hay archivo .interaction-lock
ls .interaction-lock # → ERROR (no existe) ✅
Esperado:
- TUI abre normalmente ✅
- TUI funciona exactamente igual que antes ✅
- No hay errores de lock ✅
COMPORTAMIENTO EN CASOS BORDE
| Caso | Comportamiento |
|---|---|
| Lock creation falla | TUI abre, daemon continúa (no bloqueado) |
| Lock release falla | TUI cierra normalmente, daemon verifica en 60s |
| Daemon no existe | TUI abre, funciona normal (lock se ignora) |
| TUI abierta x2 | Segundo intento actualiza lock (idempotente) |
| Lock >60s viejo | Daemon lo borra automáticamente |
| Network timeout | Cada componente es independiente |
OBSERVABILIDAD
Logs esperados
TUI abre:
[TUI] ✅ Lock creado - Daemon pausado
Daemon pausa (ve lock):
[DAEMON] 🧑 Interacción detectada. Pausa (recheck en 10s)...
TUI cierra:
[TUI] 🔓 Lock liberado - Daemon reanuda
Daemon reanuda:
[DAEMON] 🤖 Ciclo #N - Daemon activo
[DAEMON] ✓ Ciclo N completado
Archivos/Timestamps
# Ver lock en tiempo real
watch 'stat .interaction-lock 2>/dev/null | grep Modify'
# Ver edad del lock
watch 'date; [ -f .interaction-lock ] && echo "Lock age: $(($(date +%s) - $(stat -c %Y .interaction-lock))) s"'
CHECKLIST FINAL
- Compilar sin errores:
pnpm tsc --noEmit - Sin imports circulares:
pnpm knip - Test A (Sin TUI): Daemon ejecuta ciclos
- Test B (TUI abierta): Daemon pausa, lock existe
- Test C (TUI cierra): Lock desaparece, daemon reanuda
- Test D (TUI crash): Timeout graceful, daemon continúa
- Regresión: TUI sin daemon funciona igual
- Logs legibles y sin spam
ESTADO ACTUAL
✅ PRONTO PARA TESTING
- TUI integración: COMPLETADA
- Daemon cooperativo: COMPLETADA
- Documentación: COMPLETADA
- Siguientes: Platform testing + User validation