feat: agent coordination system (workflows, locks, components, messages)
Adds /api/coord/* endpoints for real-time cross-session coordination: - coord_workflows: named units of work per project - coord_work_items: tasks within workflows with dependency chains - coord_session_locks: exclusive resource locks with auto-expiry (TTL) - coord_component_states: live component state per project (upsert) - coord_messages: cross-session messaging and broadcasts - /api/coord/status: cross-project snapshot endpoint Replaces PROJECT_STATE.md as the coordination layer for Claude sessions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
64
api/models/coord_session_lock.py
Normal file
64
api/models/coord_session_lock.py
Normal file
@@ -0,0 +1,64 @@
|
||||
"""Coordination session lock model."""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from sqlalchemy import DateTime, Index, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
from .base import Base, TimestampMixin, UUIDMixin
|
||||
|
||||
|
||||
class CoordSessionLock(Base, UUIDMixin, TimestampMixin):
|
||||
"""An exclusive lock held by a session on a resource path."""
|
||||
|
||||
__tablename__ = "coord_session_locks"
|
||||
|
||||
project_key: Mapped[str] = mapped_column(
|
||||
String(200),
|
||||
nullable=False,
|
||||
doc="Project namespace this lock applies to"
|
||||
)
|
||||
|
||||
session_id: Mapped[str] = mapped_column(
|
||||
String(200),
|
||||
nullable=False,
|
||||
doc="Session holding the lock, e.g. 'DESKTOP-0O8A1RL/Claude'"
|
||||
)
|
||||
|
||||
resource: Mapped[str] = mapped_column(
|
||||
String(500),
|
||||
nullable=False,
|
||||
doc="Resource path being locked, e.g. 'server/src/', 'migrations/'"
|
||||
)
|
||||
|
||||
description: Mapped[Optional[str]] = mapped_column(
|
||||
Text,
|
||||
doc="Why this lock was acquired"
|
||||
)
|
||||
|
||||
acquired_at: Mapped[datetime] = mapped_column(
|
||||
DateTime,
|
||||
nullable=False,
|
||||
server_default=func.now(),
|
||||
doc="When the lock was claimed"
|
||||
)
|
||||
|
||||
expires_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime,
|
||||
doc="NULL means no expiry; otherwise the lock expires at this time"
|
||||
)
|
||||
|
||||
released_at: Mapped[Optional[datetime]] = mapped_column(
|
||||
DateTime,
|
||||
doc="NULL means still held; set when lock is explicitly released"
|
||||
)
|
||||
|
||||
__table_args__ = (
|
||||
Index("idx_coord_locks_project_resource", "project_key", "resource"),
|
||||
Index("idx_coord_locks_session", "session_id"),
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<CoordSessionLock(project_key='{self.project_key}', resource='{self.resource}', session_id='{self.session_id}')>"
|
||||
Reference in New Issue
Block a user