diff --git a/AGENTS.md b/AGENTS.md index c6700ed..7aa1d05 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,6 +4,15 @@ This repository owns the published `elydora` package, its CLI, synchronous and asynchronous API clients, local signing behavior, generated hook runtimes, and Python-specific agent adapters. +## Shared Modules + +- `elydora/_client_common.py` owns request bodies, headers, and error mapping for both clients. +- `elydora/plugins/_runtime.py` owns runtime paths, install config validation, runtime config validation, runtime file changes, and status checks for the transactional adapters. Kiro IDE keeps its workspace-bound variants in `kiroide_io.py`; Kiro CLI and OpenCode keep their own simple checks. +- `elydora/plugins/_shell_command.py` owns shell quoting, PowerShell encoding, and command parsing. +- `elydora/plugins/_file_io.py` owns atomic text and JSON writes plus plain JSON reads for the non-transactional adapters. +- `elydora/plugins/_managed_files.py` and `_transaction*.py` own physical-file reads and rollback-capable commits. +- Put new cross-provider logic in these modules; provider files keep only their schema, ownership, and rendering rules. + ## Integration Sources - Verify every agent hook contract against current official provider documentation before changing an adapter. @@ -44,7 +53,7 @@ This repository owns the published `elydora` package, its CLI, synchronous and a - Keep the package, distribution, and CLI version in `elydora/_version.py`; build metadata must read that literal through Setuptools dynamic metadata. - Ship `elydora/py.typed` in every wheel and verify public annotations from an installed-wheel consumer. - Support every Python version declared in `pyproject.toml`. -- Keep production source files at or below 500 lines. +- Keep every source and test file at or below 500 lines; share test fixtures through `tests/_support.py`. - Keep functions focused on one ownership boundary. - Propagate unexpected errors to the CLI boundary. - Use documented defaults only for genuinely optional configuration. @@ -74,6 +83,8 @@ py -3 -m pip wheel . --no-deps --wheel-dir git diff --check ``` +On Linux and macOS use `python -m` in place of `py -3 -m`, and point `HOME` and `XDG_CONFIG_HOME` at a scratch directory so the suite never touches real agent configuration. `[tool.mypy] platform = "win32"` type-checks the Windows branches on every host. + Provider adapter tests must cover installation, idempotency, official event forwarding, blocking behavior, status, missing runtime files, uninstall ownership, and malformed configuration preservation. Commit and push one root issue before starting the next one. diff --git a/README.md b/README.md index e44d846..7a202a2 100644 --- a/README.md +++ b/README.md @@ -161,14 +161,20 @@ Retryable responses honor both `Retry-After` seconds and HTTP-date values. # Register a new user and organization reg = ElydoraClient.register(base_url, email, password, display_name=None, org_name=None) -# Login and receive a session token +# Login and use the session token auth = ElydoraClient.login(base_url, email, password) +client.token = auth["token"] # Get current authenticated user profile me = client.get_me() -# Issue a new API token (with optional TTL in seconds) +# Issue an API token from the session token (optional TTL in seconds) token_resp = client.issue_api_token(ttl_seconds=3600) +client.token = token_resp["token"] + +# Rotate the API token the client now uses +rotated = client.rotate_api_token() +client.token = rotated["token"] ``` ### Operations @@ -219,6 +225,9 @@ agents_resp = client.list_agents() # Unfreeze a previously frozen agent client.unfreeze_agent(agent_id, reason="review complete") +# Change the integration type +client.update_agent(agent_id, integration_type="cursor") + # Delete an agent permanently deleted_resp = client.delete_agent(agent_id) ``` @@ -260,6 +269,25 @@ detail = client.get_export(export_id) data = client.download_export(export_id) ``` +### Webhooks + +```python +webhooks = client.list_webhooks() +created = client.register_webhook( + endpoint_url="https://example.com/elydora", + events=["operation.accepted", "agent.status_changed"], + secret="", +) +client.delete_webhook(created["webhook"]["webhook_id"]) +``` + +### Organization + +```python +members = client.list_members() +events = client.list_admin_events(limit=50) +``` + ### JWKS ```python @@ -269,9 +297,12 @@ jwks = client.get_jwks() ### Health ```python -# Check API health (no authentication required) +# No authentication required health = client.health() -# health["status"], health["version"], health["protocol_version"], health["timestamp"] +# health["status"], health["version"], health["protocol_version"], health["capabilities"] + +deep = client.deep_health() +# deep["dependencies"]["d1"]["status"], deep["dependencies"]["d1"]["latency_ms"] ``` ### Crypto Functions @@ -303,7 +334,7 @@ from elydora import ( ### Type Definitions -All types are `TypedDict` classes for structural typing: +Records are `TypedDict` classes; enumerations are `Literal` aliases, and `INTEGRATION_TYPES` is a tuple: ```python from elydora import ( @@ -312,18 +343,28 @@ from elydora import ( EAR, # Elydora Acknowledgment Receipt # Entity types - Agent, AgentKey, Operation, Receipt, Epoch, Export, Organization, User, + Agent, AgentAssignment, AgentKey, AdminEvent, AuthMeUser, + CurrentOrganization, DependencyHealth, EpochAnchor, MemberEntry, + Operation, Receipt, Epoch, Export, Organization, User, WebhookEntry, + + # Enumerations + AdminAction, AgentStatus, ErrorCode, ExportStatus, IntegrationType, + KeyStatus, RbacRole, INTEGRATION_TYPES, # API response types - RegisterAgentResponse, GetAgentResponse, ListAgentsResponse, - DeleteAgentResponse, SubmitOperationResponse, GetOperationResponse, + RegisterAgentResponse, UpdateAgentResponse, GetAgentResponse, + ListAgentsResponse, DeleteAgentResponse, FreezeAgentResponse, + UnfreezeAgentResponse, SubmitOperationResponse, GetOperationResponse, VerifyOperationResponse, AuditQueryResponse, GetEpochResponse, ListEpochsResponse, CreateExportResponse, GetExportResponse, - ListExportsResponse, JWKSResponse, AuthRegisterResponse, - AuthLoginResponse, GetMeResponse, IssueApiTokenResponse, HealthResponse, + ListExportsResponse, ListWebhooksResponse, RegisterWebhookResponse, + ListMembersResponse, ListAdminEventsResponse, JWKSResponse, + AuthRegisterResponse, AuthLoginResponse, GetMeResponse, + IssueApiTokenResponse, RotateApiTokenResponse, HealthResponse, + DeepHealthResponse, # Request types - RegisterAgentRequest, + RegisterAgentRequest, UpdateAgentRequest, ) ```