Coordina multipli agenti AI CLI (Kimi, Claude, Gemini, OpenAI, ecc.) che lavorano contemporaneamente sullo stesso progetto e mantiene una memoria collettiva (wiki) di tutte le sessioni passate. Usa questa skill SEMPRE quando lavori in parallelo con altre AI CLI, quando devi salvare lo stato di una sessione condivisa, quando vuoi evitare sovrascritture su file toccati da altri agenti, quando devi chiedere "questo lavoro è già stato fatto? questo bug si è già visto?", o quando l'utente parla di "multi-tap", "registry agenti", "coordination", "lock file", "handoff condiviso", "wiki delle sessioni", "chi sta lavorando su cosa" o "evitare che le AI si pestino i piedi".
72
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
"""Test per lock_manager.py."""
import sys
import tempfile
import time
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).parent.parent / "scripts"))
import lock_manager as lm
@pytest.fixture
def tmp_lock_dir(monkeypatch):
with tempfile.TemporaryDirectory() as td:
monkeypatch.setattr(lm, "LOCK_DIR", Path(td) / "locks")
lm._OPEN_LOCK_FDS.clear()
yield
lm._OPEN_LOCK_FDS.clear()
def test_acquire_and_release(tmp_lock_dir):
result = lm.acquire_lock("/tmp/test_acquire.txt", "sid-1")
assert result["locked"] is True
assert result["owner"] == "sid-1"
status = lm.is_locked("/tmp/test_acquire.txt")
assert status["locked"] is True
assert status["session_id"] == "sid-1"
release = lm.release_lock("/tmp/test_acquire.txt", "sid-1")
assert release["released"] is True
status = lm.is_locked("/tmp/test_acquire.txt")
assert status["locked"] is False
def test_cannot_acquire_locked_file(tmp_lock_dir):
lm.acquire_lock("/tmp/test_busy.txt", "sid-1")
result = lm.acquire_lock("/tmp/test_busy.txt", "sid-2")
assert result["locked"] is False
assert result["session_id"] == "sid-1"
def test_cannot_steal_fresh_lock_after_owner_process_exits(tmp_lock_dir):
"""Caso CLI: il processo owner è uscito (flock libero) ma il lock logico
è ancora fresco — un altro agente non deve sovrascriverlo."""
lm.acquire_lock("/tmp/test_ephemeral.txt", "sid-1")
# Simula la morte del processo owner: nessun fd aperto, flock rilasciato.
fd = lm._OPEN_LOCK_FDS.pop("/tmp/test_ephemeral.txt")
import os
os.close(fd)
result = lm.acquire_lock("/tmp/test_ephemeral.txt", "sid-2")
assert result["locked"] is False
assert result["session_id"] == "sid-1"
# Il lock originale resta intatto.
status = lm.is_locked("/tmp/test_ephemeral.txt")
assert status["locked"] is True
assert status["session_id"] == "sid-1"
def test_stale_lock_is_taken_over_after_owner_process_exits(tmp_lock_dir):
"""Se il lock dell'owner morto è stale, il nuovo agente lo rileva."""
import os
lm.acquire_lock("/tmp/test_stale_takeover.txt", "sid-1")
fd = lm._OPEN_LOCK_FDS.pop("/tmp/test_stale_takeover.txt")
os.close(fd)
lock_file = lm._lock_file("/tmp/test_stale_takeover.txt")
lock_file.write_text(f"sid-1|{time.time() - 999}", encoding="utf-8")
result = lm.acquire_lock("/tmp/test_stale_takeover.txt", "sid-2")
assert result["locked"] is True
assert result.get("stale_owner") == "sid-1"
def test_check_warns_when_locked(tmp_lock_dir):
lm.acquire_lock("/tmp/test_warn.txt", "sid-1")
check = lm.check_and_warn("/tmp/test_warn.txt", "sid-2")
assert check["ok"] is False
assert "locked" in check["warning"]
assert check["owner"] == "sid-1"
def test_heartbeat_renews_lock(tmp_lock_dir):
lm.acquire_lock("/tmp/test_heartbeat.txt", "sid-1")
before_ts = lm._read_info(lm._lock_file("/tmp/test_heartbeat.txt")).get("timestamp")
time.sleep(0.1)
heartbeat = lm.heartbeat("/tmp/test_heartbeat.txt", "sid-1")
assert heartbeat["ok"] is True
after_ts = lm._read_info(lm._lock_file("/tmp/test_heartbeat.txt")).get("timestamp")
assert after_ts > before_ts
after = lm.is_locked("/tmp/test_heartbeat.txt")
# L'age deve essere "fresco" (rinnovato dall'heartbeat), non stale:
# soglia tollerante per non rendere il test flaky sotto carico/fsync.
assert after["age"] < 1.0
def test_heartbeat_fails_for_non_owner(tmp_lock_dir):
lm.acquire_lock("/tmp/test_hb_owner.txt", "sid-1")
heartbeat = lm.heartbeat("/tmp/test_hb_owner.txt", "sid-2")
assert heartbeat["ok"] is False
assert heartbeat["error"] == "not owner"
def test_stale_lock_is_released(tmp_lock_dir):
lm.acquire_lock("/tmp/test_stale.txt", "sid-1", timeout=0.2)
time.sleep(0.3)
status = lm.is_locked("/tmp/test_stale.txt", timeout=0.2)
assert status["locked"] is False
assert status.get("stale_owner") == "sid-1"
def test_release_fails_for_non_owner(tmp_lock_dir):
lm.acquire_lock("/tmp/test_release.txt", "sid-1")
result = lm.release_lock("/tmp/test_release.txt", "sid-2")
assert result["released"] is False
assert result["error"] == "not owner".claude
commands
.tessl-plugin
docker
openspec
changes
2026-07-22-dockerize-sandbox
agent-registry-sync-setup-wizard
archive
2026-07-16-fix-cross-process-coordination
schemas
spec-as-source
templates
scripts
templates
tests
docker
notifier