Files
Elydora-Python-SDK/elydora/plugins/cursor_io.py
T
雷电芽衣 6dd0197cab chore(python): audit providers claudecode codex cursor gemini
Add _runtime (paths, config validation, status checks) and _shell_command
(quoting, parsers) and move the four providers onto them.

Claude-Session: https://claude.ai/code/session_01Agoc9bRVE9KL7mmWtey9Vq
2026-09-02 23:36:33 -04:00

53 lines
1.4 KiB
Python

"""Cursor hook source and runtime I/O."""
from __future__ import annotations
import os
from typing import List, Optional
from ._managed_files import MAX_SOURCE_BYTES, physical_directory_exists, read_physical_file
from ._runtime import rendered_source_change, runtime_present
from ._transaction import FileChange
from .cursor_contract import (
AGENT_KEY,
CursorDocument,
RenderedDocument,
RuntimeContract,
create_document,
parse_document,
)
CONFIG_FILE = "hooks.json"
def config_path() -> str:
return os.path.join(os.path.expanduser("~"), ".cursor", CONFIG_FILE)
def read_document() -> CursorDocument:
file_path = config_path()
snapshot = read_physical_file(file_path, "Cursor user hooks", MAX_SOURCE_BYTES)
if snapshot is None:
return create_document(file_path)
return parse_document(file_path, snapshot.contents)
def validate_config_directory() -> None:
physical_directory_exists(os.path.dirname(config_path()), "Cursor hooks directory")
def rendered_change(rendered: RenderedDocument) -> Optional[FileChange]:
if not rendered.changed:
return None
return rendered_source_change(
rendered.document.file_path,
"Cursor user hooks",
rendered.document.raw,
rendered.next_source,
)
def runtime_files_exist(contracts: List[RuntimeContract]) -> bool:
return any(runtime_present(contract, AGENT_KEY) for contract in contracts)