Skip to content

calternal-plugin

Plugin contracts and the runtime registry.

Core plugins register factories in the distributed slice. The registry validates IDs, sorts plugins and merges their Home-path declarations before it exposes routes or metadata, so linker order cannot affect shared views. Request timing exposes selected operations without User data (#549).

Source: crates/calternal-plugin/src/lib.rs

Module Summary
changes One durable change sequence per User (DESIGN §§24, 58; #668).
media_sandbox Process controls shared by Plugins that decode untrusted media.
notes_writer Shared Home writer identity for Notes and durable Tag operations (#1110, #1111).
http_cache Authorized conditional HTTP reads with strong representation ETags (#665).
outbound Validate and pin public endpoints used by Plugin provider clients.
query URL query parsing that preserves repeated keys for AND Tag filters (#1109, DESIGN §33).
raster_transport One bounded transport for public images, Mail fonts and Notes page metadata (#766, #726, #1151; DESIGN §§9, 21, 45, 53).
timing Cheap request phase timing for Calendar, Notes and Files (#549).
user_settings Per-User preferences in <home>/.calternal/settings.json.
zone The user’s time zone and local-day arithmetic (#141).
mcp_events Trusted webhook producer bus (DESIGN §55, #491).
  • pub use linkme::distributed_slice
pub struct AgentTurnFileMutation

A file change produced by an Agent request. The Files plugin creates this only after its normal Index writer has committed the matching feed row.

Fields

  • pub owner_id: String: Home that owns the changed item.
  • pub cursor: i64: Durable cursor in the Files change feed.
  • pub operation: String: Files change-feed operation.
  • pub path: String: Current owner-relative path.
  • pub old_path: Option<String>: Previous owner-relative path for moves.
  • pub item_id: String: Stable Files item identity.
  • pub content_hash: Option<String>: Hash after the mutation, when the item remains present.
  • pub prior_version: Option<String>: Version name containing the content before an overwrite.
  • pub prior_hash: Option<String>: Hash of the content stored in prior_version.
  • pub trash_name: Option<String>: Trash entry name when the Agent moved an item to Trash.

Implements: Clone, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:534

pub struct AgentTurnScope

Auth-validated context that tags writes made by a data-scope Agent token.

Fields

  • pub turn_id: String: Stable Agent turn identity.
  • pub user_id: String: User who owns the turn.
  • pub request_cursor: i64: Files change-feed cursor captured before this authenticated request.

Implements: Clone

pub fn new(
turn_id: String,
user_id: String,
request_cursor: i64,
recorder: Arc<dyn AgentTurnMutationRecorder>,
) -> Self

Bind a trusted turn identity to its AI plugin mutation writer.

pub async fn record(&self, mutation: AgentTurnFileMutation) -> Result<(), String>

Record one mutation through the turn’s durable writer.

pub async fn record_data_file_write(
&self,
owner_id: &str,
path: &str,
before: Option<calternal_fs::FileFingerprint>,
) -> Result<(), String>

Record one Markdown write through the Files Index single writer.

pub async fn record_data_file_move(
&self,
owner_id: &str,
old_path: &str,
new_path: &str,
) -> Result<(), String>

Record one Markdown move through the Files Index single writer.

Source: crates/calternal-plugin/src/lib.rs:592

pub struct ConnectionLease

Keep the accepted TCP connection’s resource permit alive in an upgraded protocol task after Hyper hands the socket to that task.

Implements: Clone, std::fmt::Debug

pub fn new<T: Send + Sync + 'static>(owner: T) -> Self

Keep owner alive until every clone of this lease is dropped.

Source: crates/calternal-plugin/src/lib.rs:336

pub struct FileTypeHandler

A file type which a plugin can handle in a future preview flow.

Fields

  • pub id: String: Stable handler identifier within the plugin.
  • pub mime_types: Vec<String>: MIME types accepted by this handler.
  • pub extensions: Vec<String>: Filename extensions accepted by this handler, without a leading dot.

Implements: Clone, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:755

pub struct IndexPluginState

Persisted enablement overrides with a request-path memory cache.

Implements: PluginState

pub async fn load(db: Db, root: Root) -> Result<Self, PluginStateError>

Load all persisted overrides before the router and workers start.

Source: crates/calternal-plugin/src/state.rs:16

pub struct InMemoryPluginState

In-memory state for tests and contract-only server builds.

Implements: Default, PluginState

Source: crates/calternal-plugin/src/lib.rs:1027

pub struct JobContext

Input passed to a plugin job handler by a future queue adapter.

Fields

  • pub job_id: String: Stable job identifier supplied by the queue.
  • pub payload: Value: Serialized job payload.

Implements: Clone, Debug

Source: crates/calternal-plugin/src/lib.rs:703

pub struct JobError

A safe error returned by a job handler.

Fields

  • pub message: String: Short error text for the queue and logs.

Implements: Clone, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:712

pub struct JobRegistration

A plugin paired with one of its job handlers.

Fields

  • pub plugin_id: String: Owning plugin ID.
  • pub handler: Arc<dyn JobHandler>: Handler supplied by the plugin.

Source: crates/calternal-plugin/src/lib.rs:1227

pub struct NotificationDraft

A typed event for the Notifications Plugin to persist.

Fields

  • pub user_id: String: Immutable ID of the User who can see this notification.
  • pub kind: NotificationKind: Stable notification category.
  • pub title: String: Short inbox and push title.
  • pub body: Option<String>: Optional inbox and push detail.
  • pub link: Option<String>: Stable UI link, when this event has a navigable target.
  • pub dedupe_key: String: Stable producer identity used to make retries idempotent.

Implements: Clone, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:181

pub struct NotificationPublisherInstallError;

Error returned when another sink is already installed in this process.

Implements: Clone, Copy, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:205

pub struct OwnedPathRegistry

Shared, immutable view of the Home paths declared by registered Plugins.

The registry merges declarations once when Plugins are built. Route handlers can then identify Plugin storage without maintaining local path lists (#606, Calendar Activity #662).

Implements: Clone, Debug, Default

pub fn iter(&self) -> impl Iterator<Item = OwnedPath> + '_

Return the stable, de-duplicated Plugin path declarations.

pub fn owns(&self, candidate: &str) -> bool

Return true when any registered Plugin owns this Home-relative path.

Source: crates/calternal-plugin/src/lib.rs:815

pub struct PluginContext

Stable instance data available when the host builds plugin routes.

Fields

  • pub instance_name: String: Display name for this instance.
  • pub live_instance_name: Option<Arc<RwLock<String>>>: Live instance name, when the server owns a hot-reloaded config file.
  • pub data: Option<PluginData>: Live filesystem and Index handles. Absent while building the static contract.

Implements: Clone, Debug

Source: crates/calternal-plugin/src/lib.rs:923

pub struct PluginData

Server-owned handles shared with compiled Plugins during live routing.

Fields

  • pub root: calternal_fs::Root: The confined data directory.
  • pub db: calternal_db::Db: The Index, with one SQLite writer.

Implements: Clone, std::fmt::Debug

Source: crates/calternal-plugin/src/lib.rs:934

pub struct PluginEvent

An invalidation that plugins publish after a durable mutation. path is a Home-relative path for file-backed plugins; provider-backed plugins may use a documented virtual scope such as Mail’s folders. A global Files reconciliation notice uses an empty User and path scope (#470, #771).

Fields

  • pub user_id: String: Immutable User ID; empty only for the global Files reconciliation notice.
  • pub plugin_id: String: Plugin that owns the changed object, or fs for Files invalidations.
  • pub path: String: Changed Home path or documented plugin scope; empty only for global Files reconciliation.
  • pub kind: String: Short mutation kind, such as created, updated, or reconciled.

Implements: Clone, Debug

pub fn files_reconciled() -> Self

Mark that Files adopted every Home after a full scan. The empty scope means each consumer must reconcile its derived data once; this is not an item change. One bus message avoids a per-file startup storm (#470, DESIGN §2–3).

pub fn is_files_reconciled(&self) -> bool

Identify the global completion notice emitted after Files scans all Homes. Subscribers must handle it before applying User or path filters (#470).

Source: crates/calternal-plugin/src/lib.rs:60

pub struct PluginRegistry

Validated plugin set with stable ordering and enablement-aware views.

pub fn new(
plugins: Vec<Arc<dyn Plugin>>,
state: Arc<dyn PluginState>,
) -> Result<Self, RegistryError>

Build a registry and validate all plugin IDs.

pub fn from_core_plugins(state: Arc<dyn PluginState>) -> Result<Self, RegistryError>

Build a registry from the compile-time core plugin slice.

pub fn all(&self) -> &[Arc<dyn Plugin>]

Return all registered plugins in stable ID order.

pub fn manifest(&self, plugin_id: &str) -> Option<PluginManifest>

Return a registered manifest by its stable ID.

pub fn owned_paths(&self) -> &OwnedPathRegistry

Return the shared Home path declarations from all registered Plugins.

pub fn is_instance_enabled(&self, plugin_id: &str) -> bool

Check whether the Instance has enabled one plugin.

pub fn is_enabled(&self, plugin_id: &str, user_id: Option<&str>) -> bool

Check whether a plugin is enabled for one optional User.

pub fn default_user_enabled(&self, plugin_id: &str) -> bool

Return a registered Plugin’s per-User default, or the historical visible default for an absent ID.

pub async fn set_instance_enabled(
&self,
plugin_id: &str,
enabled: bool,
cascade: bool,
) -> Result<Vec<String>, PluginStateError>

Apply an Instance toggle and its dependency changes atomically.

pub async fn set_user_enabled(
&self,
plugin_id: &str,
user_id: &str,
enabled: bool,
) -> Result<(), PluginStateError>

Apply a user’s mode toggle for one registered plugin.

pub fn enabled(&self, user_id: Option<&str>) -> impl Iterator<Item = &Arc<dyn Plugin>>

Return enabled plugins in stable ID order.

pub fn catalog(&self, user_id: Option<&str>) -> PluginCatalog

Build the catalog for all plugins and the state visible to one user.

pub fn router(&self, context: &PluginContext) -> Router

Mount plugin routers below /api/v1/<plugin-id>.

The enablement and scope guard runs for every request. This keeps state changes effective without rebuilding the server router.

pub fn public_router(&self, context: &PluginContext) -> Router

Mount Plugin capability routes at their declared root paths.

Unlike router, this does not require a User or scope. Each Plugin must authenticate its own bearer capability and limit access to the referenced owner data. Instance-level Plugin disablement still applies.

pub fn openapi_documents(&self) -> impl Iterator<Item = OpenApi> + '_

Return OpenAPI documents from every compiled plugin, including disabled plugins.

The checked-in contract describes the complete binary. Runtime routing still uses only enabled plugins.

pub fn job_handlers(&self, user_id: Option<&str>) -> Vec<JobRegistration>

Return job handlers from enabled plugins.

pub fn all_job_handlers(&self) -> Vec<JobRegistration>

Return job handlers for every registered plugin.

The server uses this list to register stable kinds once. The Worker checks the live Instance state before each claim, so later toggles do not require rebuilding its handler table.

pub fn search_providers(&self, user_id: Option<&str>) -> Vec<SearchRegistration>

Return search providers from enabled plugins.

pub fn file_type_handlers(&self, user_id: Option<&str>) -> Vec<RegisteredFileTypeHandler>

Return file-type handlers from enabled plugins.

pub fn settings_schemas(&self, user_id: Option<&str>) -> Vec<RegisteredSettingsSchema>

Return settings schemas from enabled plugins.

Source: crates/calternal-plugin/src/lib.rs:1294

pub struct PluginRequestContext

Authenticated authority attached to an API request by the server.

The auth adapter must create this extension after validating the session. The plugin host never reads identity or scopes from request headers.

Fields

  • pub user_id: Option<String>: Immutable user ID, if this request belongs to a user.
  • pub allowed_roots: Vec<String>: Auth-validated Home and Share roots available to the request.
  • pub scopes: Vec<String>: Scopes granted to the current session.
  • pub role: Option<String>: Current instance role.
  • pub resource_scope: Option<Value>: Auth-validated resource boundary carried to Plugin routes.
  • pub session_actor: SessionActor: Who holds the session, as the auth layer recorded it at issuance.

Implements: Clone, Debug, Default, PartialEq, Eq

pub fn data_user(&self) -> Option<&str>

The caller’s own User ID when the session has the data scope and no resource scope that names another User; None otherwise.

Per-User projections authorise through this one check, so a request can only ever name its own data (cross-user isolation, #331, #435).

Source: crates/calternal-plugin/src/lib.rs:485

pub struct PluginRequestFreshness(pub bool);

Recent passkey assertion state attached by the authenticated server layer.

Implements: Clone, Copy, Debug, Default, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:529

pub struct PluginRequestSession(pub Vec<u8>);

Exact authenticated session identity for revocable Installation delivery (#759, DESIGN §57). This is a hash-only Index key, never a bearer credential. App Passwords do not carry it.

Implements: Clone

Source: crates/calternal-plugin/src/lib.rs:525

pub struct RegisteredFileTypeHandler

A file-type handler paired with the plugin that owns it.

Fields

  • pub plugin_id: String: Owning plugin ID.
  • pub handler: FileTypeHandler: Handler contribution.

Source: crates/calternal-plugin/src/lib.rs:1243

pub struct RegisteredSettingsSchema

A settings schema paired with the plugin that owns it.

Fields

  • pub plugin_id: String: Owning plugin ID.
  • pub schema: Value: JSON Schema for the plugin settings.

Source: crates/calternal-plugin/src/lib.rs:1251

pub struct SearchContext

Authority data a provider must use when filtering search results.

Authentication will populate this value when its crate is integrated. The host passes an empty, anonymous context until then; a provider must not infer access from a query or result identifier.

Fields

  • pub user_id: Option<String>: Immutable user ID, if the request has an authenticated user.

  • pub allowed_roots: Vec<String>: Auth-validated Home and Share roots the provider may search.

    Each value is a data-directory-relative path. An empty list grants no access. Providers must still validate each root before using it.

  • pub scopes: Vec<String>: Granted session scopes.

  • pub role: Option<String>: The current instance role, if one is available.

  • pub timezone: Option<String>: The user’s IANA zone for day-relative operators (date:today), as the host resolved it (zone::resolve_zone). None means UTC.

Implements: Clone, Debug, Default, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:440

pub struct SearchRegistration

A plugin paired with one of its search providers.

Fields

  • pub plugin_id: String: Owning plugin ID.
  • pub provider: Arc<dyn SearchProvider>: Provider supplied by the plugin.

Source: crates/calternal-plugin/src/lib.rs:1235

pub struct StreamPermit

Holds one stream slot. Dropping it frees the slot, including when the stream task ends by panic or cancellation.

Implements: Debug, Drop

Source: crates/calternal-plugin/src/lib.rs:275

pub enum NotificationKind

A notification kind that a server-side producer can publish.

The variant set is intentionally small. Producers send domain events after their own durable mutation; the Notifications Plugin owns persistence, inbox visibility, push delivery, and user-facing copy.

Variants

  • ShareReceived: A Share was granted to this User.
  • AgentTurnFinished: An autonomous Agent turn completed.
  • AgentApprovalNeeded: An autonomous Agent turn requires User approval.
  • SyncConflict: A sync client found a conflict.
  • CalendarReminder: A calendar reminder trigger became due.
  • LogReminder: A Log entry reminder trigger became due.
  • BlockReminder: A block reminder trigger became due.

Implements: Clone, Copy, Debug, PartialEq, Eq

pub const fn as_str(self) -> &'static str

Stable identifier stored in the Index and sent to clients.

Source: crates/calternal-plugin/src/lib.rs:147

pub enum NotificationPublishError

Error returned when the Notifications Plugin cannot persist an event.

Variants

  • Storage: The notification could not be written to the Index.

Implements: Clone, Copy, Debug, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:198

pub enum OwnedPath

One path below a User’s Home that a Plugin owns (#606, used by Calendar #662).

A directory declaration owns the directory and its descendants. A file declaration owns one exact path. Declarations are compiled Plugin data, so request paths never enter the registry.

Variants

  • File(&'static str): One exact file path relative to a User’s Home.
  • Directory(&'static str): A directory path and every descendant relative to a User’s Home.

Implements: Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd

pub const fn file(path: &'static str) -> Self

Declare one exact Plugin-owned file path below Home.

pub const fn directory(path: &'static str) -> Self

Declare a Plugin-owned directory tree below Home.

pub const fn path(self) -> &'static str

Return the Home-relative path declared by this Plugin.

pub fn owns(self, candidate: &str) -> bool

Return true when this declaration owns the supplied Home-relative path.

Source: crates/calternal-plugin/src/lib.rs:770

pub enum PluginStateError

Error returned when an enablement change violates state or manifest rules.

Variants

  • UnknownPlugin: The requested plugin is not registered.
  • CorePlugin: A Core plugin cannot be disabled.
  • RequiredBy(Vec<String>): Enabled plugins require the requested plugin.
  • UserToggleNotAllowed: This plugin does not allow per-user enablement changes.
  • Storage: The Index could not commit the change.

Implements: Clone, Debug, PartialEq, Eq, std::fmt::Display, std::error::Error

Source: crates/calternal-plugin/src/lib.rs:996

pub enum RegistryError

Failures found while constructing a plugin registry.

Variants

  • InvalidPluginId(String): Plugin IDs must be lowercase path-safe identifiers.
  • DuplicatePluginId(String): More than one plugin declared this ID.
  • MissingDependency { plugin_id: String, required_id: String, }: A plugin requires an ID that is not registered.
  • DependencyCycle(String): Plugin requirements contain a cycle.

Implements: Clone, Debug, PartialEq, Eq, std::fmt::Display, std::error::Error

Source: crates/calternal-plugin/src/lib.rs:1260

pub enum SessionActor

Who holds the session behind a request (#980).

The auth layer sets this from the stored session row. It is not derived from scopes: an Agent container token has the same data scope as the User’s own session, but it must not reach routes that act on the User’s behalf at a higher level, such as starting AI turns or reading AI history. The default is SessionActor::Unclassified so a context that the auth layer did not classify fails closed on every route that requires SessionActor::User.

Variants

  • Unclassified: Not classified by the auth layer; routes that check the actor refuse it.
  • User: The User’s own session: browser cookie, human Installation token (CLI) or app password.
  • Agent: An Agent turn’s container token.
  • Ask: An Ask turn’s read-only container token.

Implements: Clone, Copy, Debug, Default, PartialEq, Eq

Source: crates/calternal-plugin/src/lib.rs:467

pub trait AgentTurnMutationRecorder: Send + Sync

Durable writer installed by the AI plugin for the lifetime of one turn.

fn record<'a>(
&'a self,
turn_id: &'a str,
mutation: AgentTurnFileMutation,
) -> AgentTurnMutationFuture<'a>;

Attach one Files change-feed row to its active turn.

AgentTurnMutationRecorder::record_data_file_write

Section titled “AgentTurnMutationRecorder::record_data_file_write”
fn record_data_file_write<'a>(
&'a self,
turn_id: &'a str,
owner_id: &'a str,
path: &'a str,
before: Option<calternal_fs::FileFingerprint>,
) -> AgentTurnMutationFuture<'a>;

Attach a Markdown write made by the Notes single writer. Files supplies the stable item ID, Version and change-feed cursor for the write.

AgentTurnMutationRecorder::record_data_file_move

Section titled “AgentTurnMutationRecorder::record_data_file_move”
fn record_data_file_move<'a>(
&'a self,
turn_id: &'a str,
owner_id: &'a str,
old_path: &'a str,
new_path: &'a str,
) -> AgentTurnMutationFuture<'a>;

Attach a Markdown move made by the Notes single writer.

Source: crates/calternal-plugin/src/lib.rs:562

pub trait JobHandler: Send + Sync

A plugin-owned asynchronous job kind.

fn kind(&self) -> &'static str;

Kind name stored in the queue.

fn display_name(&self) -> &'static str

Human-readable label shown in the instance Jobs view.

fn description(&self) -> &'static str

One-line explanation shown with the registered kind in Admin Jobs.

fn max_concurrency(&self) -> usize

Maximum number of concurrent jobs of this kind. The host applies this limit in addition to any shared resource semaphore a Plugin uses.

fn run<'a>(&'a self, context: JobContext) -> JobFuture<'a>;

Run one job. Queue leases, retries, and persistence stay outside this crate.

fn run_controlled<'a>(
&'a self,
context: JobContext,
_control: calternal_db::JobControl,
) -> JobFuture<'a>

Run one job with queue control for progress updates and safe stop checkpoints. Existing handlers remain valid and can adopt checkpoints when they have bounded units of work.

Source: crates/calternal-plugin/src/lib.rs:718

pub trait NotificationPublisher: Send + Sync

Durable sink installed by the Notifications Plugin during server startup.

fn publish<'a>(&'a self, event: NotificationDraft) -> NotificationPublishFuture<'a>;

Persist one event and make it available to the User’s inbox.

Source: crates/calternal-plugin/src/lib.rs:212

pub trait Plugin: Send + Sync

A plugin and all server-side contributions it owns.

fn manifest(&self) -> PluginManifest;

Return the public manifest declared by this plugin.

fn owned_paths(&self) -> &'static [OwnedPath]

Return Home-relative paths owned by this Plugin.

Shared views use this registry to exclude Plugin storage while leaving direct Files access unchanged (#606).

fn default_user_enabled(&self) -> bool

Set the initial per-User mode state when no saved choice exists.

The default preserves the historical visible-by-default behavior. A Plugin may opt out until its onboarding flow exists; persisted choices always take precedence over this fallback (DESIGN §34, #34).

fn router(&self, _context: &PluginContext) -> Router

Return routes mounted below /api/v1/<plugin-id>.

fn public_router(&self, _context: &PluginContext) -> Router

Return read-only routes outside the authenticated API prefix.

Public capability URLs (issue #431) need a stable root path and do not require a session. The Registry still checks that the owning Plugin is enabled for the Instance before it dispatches these routes.

fn change_projection<'a>(
&'a self,
_principal: &'a PluginRequestContext,
_record: &'a changes::Record,
) -> changes::ProjectionFuture<'a>

Project one changed ID after checking current access (#668, DESIGN §58). The default fails closed until the owning adoption issue adds an adapter.

fn openapi(&self) -> Option<OpenApi>

Return the OpenAPI fragment contributed by this plugin.

fn job_handlers(&self) -> Vec<Arc<dyn JobHandler>>

Return job handlers. The registry keeps this hook decoupled from the job queue.

fn search_providers(&self) -> Vec<Arc<dyn SearchProvider>>

Return server-side search providers.

fn file_type_handlers(&self) -> Vec<FileTypeHandler>

Return file-type handlers for a later preview flow.

fn settings_schema(&self) -> Option<Value>

Return the JSON Schema for this plugin’s settings, if it has settings.

fn ui_entry_points(&self) -> PluginUiEntryPoints

Return client entry points exposed by the plugin catalog.

Source: crates/calternal-plugin/src/lib.rs:845

pub trait PluginState: Send + Sync

State interface for instance and per-user plugin enablement.

fn is_enabled(
&self,
manifest: &PluginManifest,
default_user_enabled: bool,
user_id: Option<&str>,
) -> bool;

Check if a plugin is enabled for an optional user, using its declared per-User default when no persisted choice exists.

fn is_instance_enabled(&self, manifest: &PluginManifest) -> bool;

Check the instance-wide state without applying a user’s mode preference.

fn is_user_enabled(
&self,
manifest: &PluginManifest,
default_user_enabled: bool,
user_id: &str,
) -> bool;

Return one User’s mode state, using the Plugin’s declared default when no choice is saved.

fn set_instance_enabled<'a>(
&'a self,
manifests: &'a [PluginManifest],
plugin_id: &'a str,
enabled: bool,
cascade: bool,
) -> PluginStateFuture<'a, Vec<String>>;

Apply an instance change with its dependency rules as one serialized operation. The returned IDs are the plugins whose state changed.

fn set_user_enabled<'a>(
&'a self,
manifest: &'a PluginManifest,
user_id: &'a str,
enabled: bool,
) -> PluginStateFuture<'a, ()>;

Set one user’s plugin state when the manifest allows it.

Source: crates/calternal-plugin/src/lib.rs:953

pub trait SearchProvider: Send + Sync

A search provider contributed by a plugin.

fn search<'a>(
&'a self,
context: &'a SearchContext,
query: &'a str,
limit: usize,
) -> SearchFuture<'a>;

Search objects visible to context and return at most limit hits.

fn search_keyword<'a>(
&'a self,
context: &'a SearchContext,
query: &'a str,
limit: usize,
) -> SearchFuture<'a>

Search the keyword index without waiting for semantic retrieval.

Providers without a separate semantic stage keep their normal result path. Search overrides this hook so the palette can show keyword hits first, then replace them with its fused results when semantic search completes.

Source: crates/calternal-plugin/src/lib.rs:409

pub type AgentTurnMutationFuture<'a> =
Pin<Box<dyn Future<Output = Result<(), String>> + Send + 'a>>;

Result type returned by the Agent mutation persistence hook.

Source: crates/calternal-plugin/src/lib.rs:558

pub type JobFuture<'a> = Pin<Box<dyn Future<Output = Result<(), JobError>> + Send + 'a>>;

A job handler future. This hook does not depend on a queue or database.

Source: crates/calternal-plugin/src/lib.rs:699

pub type NotificationPublishFuture<'a> =
Pin<Box<dyn Future<Output = Result<(), NotificationPublishError>> + Send + 'a>>;

Future returned by one typed notification publish hook.

Source: crates/calternal-plugin/src/lib.rs:208

pub type PluginFactory = fn() -> Arc<dyn Plugin>;

A constructor for one compiled core plugin.

Source: crates/calternal-plugin/src/lib.rs:49

pub type PluginStateFuture<'a, T> =
Pin<Box<dyn Future<Output = Result<T, PluginStateError>> + Send + 'a>>;

One serialized state mutation. State changes are asynchronous because the production adapter commits them to the Index before invalidating its cache.

Source: crates/calternal-plugin/src/lib.rs:949

pub type SearchFuture<'a> = Pin<Box<dyn Future<Output = Vec<SearchHit>> + Send + 'a>>;

A search provider future. The boxed future keeps the provider hook object-safe.

Source: crates/calternal-plugin/src/lib.rs:406

pub fn client_stream_permit(ip: IpAddr) -> Option<StreamPermit>

Reserve one of MAX_STREAMS_PER_CLIENT_IP long-lived stream slots for one resolved client IP.

Source: crates/calternal-plugin/src/lib.rs:315

pub fn client_stream_permit_with_limit(ip: IpAddr, limit: usize) -> Option<StreamPermit>

Reserve one stream slot for a resolved client IP. The server resolves forwarded addresses before calling this function. A custom limit supports small deterministic tests; production uses client_stream_permit.

Source: crates/calternal-plugin/src/lib.rs:309

pub fn current_agent_turn_scope() -> Option<AgentTurnScope>

Read the current turn scope inside a writer request.

Source: crates/calternal-plugin/src/lib.rs:664

pub async fn drain_oversized_json(request: Request<Body>, next: Next) -> Response

Drain a known oversized request before sending 413. This lets HTTP/1.1 clients that are still writing a large JSON body receive the status instead of a reset connection. The extractor retains the per-route allocation cap.

Source: crates/calternal-plugin/src/lib.rs:358

pub fn event_bus() -> &'static tokio::sync::broadcast::Sender<PluginEvent>

Process-wide event bus shared by compiled plugins. Lagged receivers must reconcile from the Index; events are invalidations, not durable records.

Source: crates/calternal-plugin/src/lib.rs:136

pub fn install_notification_publisher(
publisher: Arc<dyn NotificationPublisher>,
) -> Result<(), NotificationPublisherInstallError>

Install the Notifications Plugin’s durable event sink once during startup.

A process has one Index and one Notifications Plugin. Refusing replacement prevents one Plugin instance from silently stealing another’s event hook.

Source: crates/calternal-plugin/src/lib.rs:226

pub fn is_change_event(kind: &notify::EventKind) -> bool

Whether a data-directory watcher event can mean that a file changed. Every server-side watcher of Homes filters its events with this.

The inotify backend also reports opens and read-only closes (notify’s Access kind). A read is not a change. Forwarding reads made every download, thumbnail job, video playback and EXIF read look like an edit, and each one rebuilt the Photos index of the whole library. In the search indexer it was a loop: indexing a file reads it, the read was an event, and the event queued the file again, so the indexer never went idle and a steady stream of reads kept new changes waiting (#122). A close after writing does end a write, so it still counts.

Source: crates/calternal-plugin/src/lib.rs:124

pub fn migrations() -> MigrationSet

Plugin enablement is owned by this crate, so its migration has its own namespace and never changes another crate’s migration numbers.

Source: crates/calternal-plugin/src/state.rs:193

pub async fn publish_notification(
event: NotificationDraft,
) -> Result<(), NotificationPublishError>

Persist one notification when the Notifications Plugin is installed.

Startup code may omit the sink in contract-only/static contexts. Producers can still complete their own durable mutation in that case.

Source: crates/calternal-plugin/src/lib.rs:243

pub async fn record_current_agent_data_file_move(
owner_id: &str,
old_path: &str,
new_path: &str,
) -> Result<(), String>

Record a Markdown move when the authenticated request carries an Agent turn scope. Ordinary Notes moves remain unchanged.

Source: crates/calternal-plugin/src/lib.rs:683

pub async fn record_current_agent_data_file_write(
owner_id: &str,
path: &str,
before: Option<calternal_fs::FileFingerprint>,
) -> Result<(), String>

Record a Markdown write when the authenticated request carries an Agent turn scope. Ordinary Notes and Task writes remain unchanged.

Source: crates/calternal-plugin/src/lib.rs:670

pub fn stream_permit(user: &str) -> Option<StreamPermit>

Reserve one stream slot for user, or None when the User already holds MAX_STREAMS_PER_USER streams. Callers answer None with 429 before they upgrade or start the stream.

Source: crates/calternal-plugin/src/lib.rs:302

pub async fn with_agent_turn_scope<F: Future>(scope: AgentTurnScope, future: F) -> F::Output

Run an authenticated Agent request with a server-created turn scope.

Source: crates/calternal-plugin/src/lib.rs:659

pub const MAX_STREAMS_PER_CLIENT_IP: usize

Maximum long-lived streams from one resolved client IP.

Source: crates/calternal-plugin/src/lib.rs:264

pub const MAX_STREAMS_PER_USER: usize

Most long-lived streams (SSE and WebSocket) that one User may hold at the same time. Each stream holds a socket and a task, and SSE streams run a query on every wake-up, so an uncapped User could starve the Instance. A browser needs a few streams per tab; 64 leaves room for many tabs and installations.

Source: crates/calternal-plugin/src/lib.rs:261

pub static CORE_PLUGINS: [PluginFactory]

Compile-time registration point for core plugin factories.

Source: crates/calternal-plugin/src/lib.rs:53