"""Capability-limited protocols exposed to extensions.""" from __future__ import annotations from collections.abc import Callable, Mapping from typing import Protocol from .contracts import Event, ExtensionResult, Fact CommandHandler = Callable[[Event, str], ExtensionResult] class CommandRegistry(Protocol): def register(self, command: str, handler: CommandHandler) -> None: ... class PluginStorage(Protocol): def get(self, key: str) -> str | None: ... def set(self, key: str, value: str) -> None: ... def delete(self, key: str) -> None: ... class ApprovedHttpClient(Protocol): def request( self, profile: str, *, method: str, path: str, query: Mapping[str, str] | None = None, ) -> bytes: ... class ApprovedServiceBroker(Protocol): def call( self, profile: str, *, operation: str, payload: Mapping[str, object], ) -> Mapping[str, object]: ... class FactWriter(Protocol): def write(self, fact: Fact) -> None: ... class Scheduler(Protocol): def schedule(self, key: str, *, run_at: str, payload: Mapping[str, str]) -> None: ... class PluginLogger(Protocol): def info(self, message: str, **fields: object) -> None: ... def warning(self, message: str, **fields: object) -> None: ... class SingleGroupContext(Protocol): """No group selector, GUI sender, raw ledger, environment, or shell access.""" commands: CommandRegistry storage: PluginStorage http: ApprovedHttpClient services: ApprovedServiceBroker facts: FactWriter scheduler: Scheduler logger: PluginLogger