Documentation / Développement / Référence / SDK surface

SDK surface

@meridian/shared (libs/shared/package.json) is the one package a plugin compiles against. It is browser-safe: no filesystem access, no host internals, no dependency on apps/api. A plugin's runtime code imports it as import type wherever possible, so the import is erased at compile/bundle time — see Bundling and distribution.

This page is the exhaustive map of what the package exports, file by file. It does not explain how to author a manifest, a behavior, or a workflow — see Plugin manifest, Autonomy and packaging, and the how-to guides linked from each section below.

Package identity

Name @meridian/shared
Version version in libs/shared/package.json, released with the other @meridian/* libraries
Runtime dependencies @opentelemetry/api, croner, zod
exports (dev) "./*": "./src/*.ts" — every subpath resolves 1:1 to a .ts source file
exports (publishConfig, published) "./*": { "types": "./dist/*.d.ts", "default": "./dist/*.js" }
Build npm run build → tsc -p tsconfig.build.json (declaration, declarationMap, sourceMap, outDir: dist, rootDir: src)

Two resolution paths coexist:

  • The repository's plugins (external-plugins/<name>/) resolve @meridian/shared/* via the path alias "@meridian/shared/*": ["../libs/shared/src/*"] (external-plugins/tsconfig.json) — straight to source, no build step.
  • Out-of-repo plugins resolve the published npm package, whose exports only take effect through publishConfig — a field pnpm publish/pnpm pack apply and npm ignores. See Bundling and distribution.

PLUGIN_CONTRACT_VERSION (below) is a hand-maintained constant that is decoupled from the @meridian/shared package version: it moves when the plugin-facing contract does (see version), not on every library release.

Directory layout

libs/shared/src/
  version.ts              PLUGIN_CONTRACT_VERSION
  plugin/                 the plugin-authoring contract
    behavior.ts
    source.ts
    mapping.ts
    assist.ts
    inbound.ts
    manifest.ts
    manifest-keys.ts
    dependencies.ts
    declared-events.ts
    node-contribution.ts
    agent-contribution.ts
    instance.ts
    i18n.ts
  domain/                 shared platform vocabulary
    types.ts
    object-types.ts
    value-sets.ts
    dimensions.ts
    context-kinds.ts
    event-types.ts
    event-routing.ts
    trigger-filter.ts
    trigger-facts.ts
    validation.ts
    terminology.ts
    agent-spec.ts
    agent-tools.ts
    memory.ts
    ports.ts
    workflow-spec.ts
  engine/                 type-system & catalog helpers
    type-system.ts
    conversions.ts
    catalog-metadata.ts
    event-contract.ts
    dynamic-ports.ts
    derived-ports.ts
    template.ts
    effects.ts
    agent-tool-eligibility.ts
    memory.ts
    schedule.ts
  observability/
    trace.ts

Every file above is a real, committed source file (git ls-files libs/shared/src); there is no generated or build-manifest step involved in producing this list.

plugin/* — the plugin-authoring contract

Import Exports Purpose
@meridian/shared/plugin/behavior NodeBehavior<I,O,C>, RunArgs<I,C>, Proposal<O>, NodeBehaviorFactory<I,O>, PluginNodeContext, ValidationResolution, PortSandboxFactory, WorkflowToolFactory The node behavior contract — what a behavior.module (and a portSandboxes module) exports. Full contract at Behavior contract.
@meridian/shared/plugin/source SourceFactory, SourceFactoryOpts, SourceFeed, SourceHandle The event-source mechanism contract (polling). The host starts the factory for each inbound connection of the source: config holds the connection's parameters, declared defaults applied, without connection; connection the outbound connection that parameter names, else the default connection of the type; feeds one feed per binding enabled on the connection. emit resolves once the host's reception has stored the record, and rejects when it could not store it — see Contribute an event source and binding.
@meridian/shared/plugin/connections AUTH_SCHEMES/AuthScheme, SCHEME_CREDENTIAL_KIND, CONNECTION_NAME, CONNECTIONS_MIN_SDK, ConnectionTypeContribSchema, ConnectionRequirementSchema, InstanceConnectionSchema, StoredConnectionConfigSchema, INBOUND_AUTH_SCHEMES, connectionIssues(), instanceAuthIssues(), paramIssues(), paramValues(), effectiveParams(), ConnectionHandle, ConnectionAccessor Connections: the contribution of a connection type, the requirement of an adapter, a source or a node, and the handle the host passes them (PluginNodeContext.connection, SourceFactoryOpts.connection, the second argument of an adapter factory). The handle's fetch adds the authentication, the timeout and the trace. See Connection types.
@meridian/shared/plugin/mapping MapExprSchema (zod), MapExpr Raw-record → event field projection grammar, used by eventBindings.map. Full grammar at MapExpr.
@meridian/shared/plugin/assist NodeAssist, AssistSuggestion Host-side configuration assistance of a node (assist in the manifest): checks beyond the schema, suggestions taken from a sample, preview. See Declared configuration and ports.
@meridian/shared/plugin/inbound InboundReceiverFactory, InboundReceiverOptions (the receiver of an inbound connection type: the connection's params, encoding, onMessage, onError), InboundProtocol, InboundIdentity, INBOUND_ENCODINGS/InboundEncoding (the encodings a connection accepts), HOST_TRANSPORTS/HostTransport/isHostTransport() (http and directory, offered to every protocol), InboundTransport (a protocol's own transport as its manifest describes it: name, defaultPort?, hint?), LISTENER_PORTS (the ports a connection with a protocol transport listens on, 1024–65535), DEFAULT_MEDIA_TYPES (text/plain, application/octet-stream: the media types of an HTTP connection when the protocol declares none), InboundReceiver, ReceiverOptions, ListenerOptions, TransportFactory, ValidationProfile, ValidationReport, MessageBinding, MessageBindingContext, MessageBindingOption, InboundRejection, message encoding and bounded-reception helpers Protocol-owned inbound reception, safe validation reports, and raw-message projection. The host retains the inbox and generic transports. See Connect an EAI.
@meridian/shared/plugin/manifest TypeRefSchema, PluginManifest (zod schema + type), ManifestShorthand, MANIFEST_SHORTHANDS (the shorthands the schema admits, by place: an agent's input/output for inputs/outputs), NodeContribution, TypeContribution, ConversionContribution, AgentContribution, AdapterContribution, ContextKindContribution, EventContribution, EventFieldContribution, EventContextContribution, PortSandboxContribution, EventSourceContribution, EventBindingContribution, MessageBindingContribution, ReceiveContribution (a pinned trigger's receive, transports normalized to InboundTransport) The plugin.yaml schema. Full field reference at Plugin manifest.
@meridian/shared/plugin/manifest-keys StrippedKey, strippedKeys(), keyPath(), manifestKeyIssues() The keys of a YAML document that a schema drops. strippedKeys(written, parsed) compares the document (the parsed YAML, before the schema) with what the schema returns and lists each key absent from it at the same path, at any depth, arrays index by index; a value the schema keeps whole (z.record, z.unknown()) is open. keyPath(path, key) writes a key's path (contributes.nodes[3].config[0].option). manifestKeyIssues(document, manifest) turns the keys a plugin manifest's schema dropped into load problems of kind key (a declared shorthand that does not apply gets a message that says why), shared by the host and meridian-plugin validate/build/publish; the host also logs the keys dropped from the instance manifest with strippedKeys. See Load checks.
@meridian/shared/plugin/dependencies DependencySemver, RangeKind, rangeKind(), RangeState, rangeState(), testedRange(), DependencyState, DependencyCheck, DependencyReport, dependencyIssues() The dependsOn ranges of a set of manifests checked against the versions found, shared by the host and meridian-plugin validate/build/deps. dependencyIssues(manifests, refused, semver) takes the manifests whose contract is accepted, those refused for their contract, and the caller's semver operations (validRange, satisfies, gtr, valid; the SDK does not depend on semver): an entry that names the plugin itself, an invalid range or a version found outside the range refuses the plugin (refused), a dependency absent or refused with a version in the range is a problem and the plugin loads; problems of kind dependency named after the dependency, in dependency order, and the state of each dependency (checks). DependencyState is ok, unconstrained (*), out-of-range, invalid-range, absent, refused or self; rangeState(range, version, semver) gives the first four, and the registry resolution uses it. testedRange(version, semver) gives ^<version>, the range a message proposes. See Load checks.
@meridian/shared/plugin/declared-events DECLARED_EVENTS_MIN_SDK, EVENT_DEFAULT_SELECTOR_MIN_SDK, RECEIVE_PRESENTATION_MIN_SDK, RESERVED_EVENT_FIELDS, EVENT_TYPE_PATTERN, EVENT_FIELD_PATTERN, PluginLoadIssue, isLoadNote(), usesDeclaredEvents(), usesReceivePresentation(), dependsOnClosure(), eventDeclarationIssues(), declareEvent(), TriggerDerivation, triggerFromEvent(), strayFromIssues(), eventBindingIssues(), messageBindingIssues(), declaredEventUsageIssues(), pluginContractIssue(), sdkFloorIssue(), portDimensionIssues() The load checks of a plugin, shared by the host and meridian-plugin validate/build: contract (pluginContractIssue(manifest, accepts): a range that does not accept the host's contract refuses the plugin), declarations and examples, derivation of an event: trigger, dimensions of event fields and node ports resolved in the dependsOn closure (portDimensionIssues(node, closure) for the ports), bindings (declaredEventUsageIssues, once every plugin is applied), sdk floor (sdkFloorIssue(manifest, rangeCovers): 0.1.1 for declared events, 0.1.3 with an event defaultSelector, 0.1.4 when a node describes its reception, 0.1.5 for conditional port rules, 0.1.6 with connections, one problem for the highest floor). PluginLoadIssue.kind is one of contract, event, example, trigger, node, filter, binding, sdk, module, key and dependency. The registration of a manifest's events lives in @meridian/engine-core/engine/plugin-events, because the default filter is a jexl expression: registerPluginEvents sets aside a type already declared, then declarePluginEvent declares each event, refuses a type equal to a pinned address and checks the default filter. See contributes.events.
@meridian/shared/plugin/node-contribution ContributedNode, contributedNodeMeta(), nodeIssues(), PinnedAddress, pinnedAddresses() The projection of a node contribution onto its NodeTypeMeta, shared by the host and meridian-plugin validate/build: the flat trigger keys of the manifest become receives, a node the projection refuses comes with its problems, and a node-level defaultSelector is ignored with a problem; nodeIssues gives them kind trigger on a trigger, node on another node. pinnedAddresses(manifests) lists the addresses no declared event may take, each with its triggers and their plugin: the core's pinned triggers (CORE_CATALOG_META) and the pinned triggers of the manifests whose contribution projects. See Load checks.
@meridian/shared/plugin/agent-contribution agentSlug(), contributedAgentNodeId(), contributedAgent() The projection of an agent contribution onto its AgentDef, shared by the host and meridian-plugin validate/build: the agent's node type is agent.<slug>, and an agent that breaks the rules of AgentSpec (an empty provider or model, no input or no output) comes with its problems, of kind node, instead of a definition. See contributes.agents.
@meridian/shared/plugin/instance InstanceManifest (zod schema + type), PortBinding, PluginRequirement, EMPTY_INSTANCE The instance manifest schema (deployment configuration, not a plugin contribution). Full field reference at Instance manifest.
@meridian/shared/plugin/i18n I18nEntry, I18nBundle, PluginBundles, manifestI18nEntries(), bundleLookup(), interpolate(), resolveRuntimeKey(), localizeManifest(), receiveTransportHintPath() (the key of a transport's hint under its trigger, receive.transports.<name>.hint) The key-derivation walker shared by the host (resolution) and the CLI (i18n extract/i18n check) — see Translate a plugin.

domain/* — shared platform vocabulary

Import Exports Purpose
@meridian/shared/domain/types PrimitiveName, TypeRef (union), t (TypeRef builder helpers), typeLabel(), ContextKey, ContextEnvelope The TypeRef vocabulary every port type is expressed in. Full kind-by-kind reference at TypeRef.
@meridian/shared/domain/object-types FieldDescriptor, TypeDescriptor, ObjectTypeName, OBJECT_TYPES, registerType(), getType(), isObjectType() The open registry of object-kind types ({ kind: "object", name }). Starts empty — the core contributes no domain type; plugins populate it via registerType.
@meridian/shared/domain/value-sets ValueSetConcept, ValueSetDef, VALUE_SETS, registerValueSet(), hasValueSet(), isExternalValueSet(), valueSetConcepts(), codeInValueSet(), displayOfCode(), subsumes() The open registry backing coded types. Starts empty; external: true value-sets are not enumerated here (resolved by a terminology port instead).
@meridian/shared/domain/dimensions Dimension (string, a registered dimension name), UnitDef, DimensionDef (with its source plugin), DIMENSIONS, registerDimension(), getDimension(), dimensionOfUnit(), unitInDimension(), convertUnit(), unknownDimensionReason() The open registry backing quantity types (unit checking + conversion by multiplicative factor). Starts empty — the core declares no dimension; plugins contribute them via contributes.dimensions (@posos/common contributes the common physical dimensions). A registered dimension cannot be redefined by another plugin or differently.
@meridian/shared/domain/context-kinds ContextKindDescriptor, CONTEXT_KINDS, registerContextKind(), getContextKind(), isContextKind(), contextIdField(), listContextKinds(), contextKindForEntity() The open registry of ambient-context kinds (context:/establishes: keys, ref entities, subject id fields). Starts empty — the core knows no kind; plugins contribute them via contributes.contextKinds (@posos/common contributes patient/encounter/order/document).
@meridian/shared/domain/event-types EventContextKind, EventFieldDescriptor, EventTypeDescriptor, duplicateEventMessage(), registerEventType(), getEventType(), listEventTypes(), replaceEventTypes() The open registry of declared events (contract of each event type: context kinds, typed fields, example, default filter, declaring plugin). Starts empty; plugins contribute via contributes.events. registerEventType returns a problem instead of throwing when another plugin already declared the type.
@meridian/shared/domain/memory MEMORY_SCOPES, MEMORY_TTL_DEFAULT, MemoryAddress, MemoryEntry, MemoryListing, MemoryWrite, MemoryWriteResult, MemoryStore, MemoryRef, NodeMemory, MemorySeedEntry, the zod schemas MemoryAddressSchema/MemoryWriteSchema/MemorySeedEntrySchema, workflowSlug(), memoryTypeName() The workflow-memory contract: the address of an item (scope, workflow, subject, key), what the store returns (value, stored type, version, provenance, expiry), the result of a write ({ written: true, entry } or { written: false, currentVersion } for a refused conditional write), and the store interface the host implements. Behaviors of plugins do not reach the memory; the core memory nodes do. See Remember values between runs.
@meridian/shared/domain/validation PendingValidationRecord, ValidationClosure, ValidationClosureOutcome The platform human-in-the-loop concept, as a pair: the request published to a subject's record when a run suspends (runId/pendingId correlate and resume the run), and its closing when the validation ends outside the record (outcome: accepted, rejected, expired, withdrawn; by?, at, comment?). See Port contracts.
@meridian/shared/domain/terminology TerminologyPort (interface), InternalTerminology, RoutingTerminology The terminology port and its two implementations: the in-registry resolver, and a per-value-set router over the terminology adapters contributed by plugins (used when several plugins each own a code system).
@meridian/shared/domain/agent-spec LLM_PROVIDERS, DEFAULT_LLM_PROVIDER, DEFAULT_LLM_MODEL, AgentPortSchema/AgentPort, AgentSpec (zod, with legacy input/output → inputs/outputs coercion), AgentDef, coerceLegacyAgentIo(), resolveTypeName(), agentPortType(), agentPortTypeLabel(), selectableTypeNames() The agent specification schema (apiVersion: meridian/agent-v1) and its TypeRef resolution helpers. See Author an agent.
@meridian/shared/domain/ports AgentToolHandle, AgentRunRequest, AgentRunnerPort, SubjectRecordPort, Ports (open bag, [pluginPort: string]: unknown), requirePort() The hexagonal port bundle a behavior reaches through ctx.ports. The SDK types only the ports the core calls (agent, terminology) plus the SubjectRecordPort platform capability; business port contracts live with their owning plugin, which augments Ports via declare module. requirePort<T>(ports, name) is the common runtime guard. Full contract at Port contracts.
@meridian/shared/domain/agent-tools AgentToolResolution, AgentToolSource, ResolvedAgentTools, resolveAgentTools() The shared resolution loop turning an agent's tools references into invocable handles, composed from per-executor sources.
@meridian/shared/domain/workflow-spec NodePosition, WorkflowNodeInstance, Connection, WorkflowSpec (zod, apiVersion: meridian/v3), parsePortRef(), withSpecReplaced(); routing: SelectorEvaluator, RouteSelection, RouteMatch, RouteHit, RouteResult, RoutedWorkflow, selectorMatches(), hasNoSelector(), routeEvent() The workflow DSL schema, and the routing of an event to the published workflows: routeEvent returns { hits, candidates } — every workflow whose trigger receives the type and whose filter keeps the event (or that has none), with its reason (selector, unfiltered, targeted, pinned). Full grammar at Workflow DSL.
@meridian/shared/domain/event-routing IngestEventResponse<V>, DeliveredRun, DeliveryFailure, RunRouting, RecentEvent, RecentEventOutcome, RecentEventsResponse, AlsoReceivedFile, AlsoReceivedNotice, RoutingNotice, SelectorSample, PublishResponse, RollbackResponse, PublishRefusal Types only: the HTTP shapes of routing shared by the API and the console — the POST /api/events response, the routing fields of a run, the recent-arrivals trace, and the publication notes about other receivers. See Event ingestion API.
@meridian/shared/domain/trigger-filter SelectorRole, FilterOp, FilterLiteral, FilterRow, FilterModel, EventFieldType, EventField, FILTER_OPS_BY_TYPE, isFilterPath(), quoteString(), renderLiteral(), FilterBuildError, buildSelector() The trigger filter (trigger.selector) helpers shared by the API and the console: the filter's role (route, filter, ignored, computed by triggerFacts), the guided model (rows of field, operator, value), the operators allowed per field type, and the JEXL it produces.
@meridian/shared/domain/trigger-facts TriggerFamily, TriggerProblem, TriggerFacts, TriggerInstance, TriggerMeta, triggerFacts(), declaredEventOf(), eventConfigField(), TriggerRoute, triggerRoute(), EventClaim, eventClaims(), EventAdmission, eventAdmission(), triggerKey(), contractEstablishes(), exampleEvent() The only resolution of what a trigger instance receives (node type and spec.trigger.config): family, type received (for a configurable trigger, the event of its configuration field), selector role, contract read in the event registry, context established, example, default filter and problem (trigger-unknown, event-absent, event-unknown). Also the routing key of a workflow (triggerRoute), the triggers that can receive a type (eventClaims: a configurable trigger claims every declared event, with the configuration that makes it receive it), whether a type is routed to every matching workflow (eventAdmission: routable, addressed, unclaimed), the console identity of an instance (triggerKey) and the pre-filled event of a trigger (exampleEvent). Browser-safe.

Terminology port

TerminologyPort is the one domain contract with more than a data shape: has, validateCode, expand, display, subsumes — each implementation may answer synchronously (InternalTerminology) or asynchronously (a terminology adapter, reached through RoutingTerminology). A terminology server is plugged in by a plugin that contributes a terminology adapter. See Configure terminology.

engine/* — type-system & catalog helpers

Import Exports Purpose
@meridian/shared/engine/type-system objectFields(), isAssignable(), validateValue(), exampleValue(), describeCatalogTypes() Structural connection compatibility (design-time) and value validation (runtime, port boundaries), crossing TypeRef against the OBJECT_TYPES/VALUE_SETS/DIMENSIONS registries.
@meridian/shared/engine/event-contract ownValue(), OCCURRED_AT_TYPE, CONTEXT_ID_TYPE, isAbsent(), ContextIdState, contextIdState(), EventContractKey, eventContractKeys(), EventContractIssue, EventContractOptions, eventContractIssues(), invalidReason(), projectDeclaredEvent(), ResolvedTriggerOutput, contractOutputs(), contractOutputPorts() Conformity of a payload to a declared event (validity without conversion, required fields, context ids; messages never quote the value), the defensive projection behind the declarative trigger, and the default outputs of a trigger on a declared event: one output per field of the contract, in declaration order (contractOutputs for the projection, contractOutputPorts for the ports).
@meridian/shared/engine/conversions Conversion (interface), CONVERSIONS, registerConversion(), findConversion(), listConversions() The From/Into conversion registry backing the transform.convert node and the editor's auto-insert. Starts empty — the core knows no conversion; plugins contribute declarative entries via contributes.conversions (JEXL over value).
@meridian/shared/engine/catalog-metadata NodeKind, PortDef, ConfigFieldDef, NodeTypeMeta, TriggerReceives, CATALOG_META, CORE_CATALOG_META, triggerMetaIssues(), registerNodeMeta() The node-type registry (kind, ports, category). Seeded with only the core primitives (value.*, transform.*, flow.*, memory.*, the core triggers, sub-workflow and agent nodes); every domain node is registered by a plugin via registerNodeMeta. CORE_CATALOG_META is a copy of the core entries taken before any plugin registers. For a trigger, NodeTypeMeta carries receives (pinned, dedicated or configurable, see What a trigger receives); registerNodeMeta throws when triggerMetaIssues reports a problem.
@meridian/shared/engine/effects effectSummary() The effect node types of a workflow (writes and notifications, human tasks, agent calls, sub-workflows), listed side by side for the workflows that start on the same event: publication notes, the filter panel, the assistant's digest, the routing audit.
@meridian/shared/engine/template TEMPLATE_CONTEXT_ROOT, TemplatePart, ParsedTemplate, parseTemplate(), hasTemplate(), templateVariables(), templateContextKinds(), templateFields(), templateTexts() Templates in the text fields of a node's config ({name}, {context.patient.id}): parsing and the list of template fields; the evaluation lives in @meridian/engine-core.
@meridian/shared/engine/dynamic-ports DynamicKind, templateVariables(), resolveDynamicPorts(), nodePorts(), nodeRequiredContext() Resolves ports from node config: core flow/transform/memory nodes, plugin nodes that declare derivedPorts, and a configurable trigger (the fields of the chosen event's contract, then done); nodeRequiredContext adds a memory node's subject kind to its catalog context.
@meridian/shared/engine/derived-ports DerivedPorts, PortRule, TypeTemplate, ValueRef, resolveDerivedPorts() Evaluates the port rules a plugin node declares (derivedPorts): one port or one port per config list item, types read in the config, chosen by a value, or built as records; returns the ports and what could not become one.
@meridian/shared/engine/memory MEMORY_DYNAMICS, isMemoryDynamic(), isConditionalWrite(), memoryConfigErrors(), memoryWriteMismatch(), memoryReadValue(), memoryValueType(), memoryTtlMs() The rules of the core memory nodes, shared by static validation, the editor and the node behaviors: configuration checks, the retention (30 days by default), the type check run on write, and the read of a stored value against the declared type, converted through the conversion registry when the stored type differs.
@meridian/shared/engine/agent-tool-eligibility AgentToolEligibility, agentToolEligibility() Whether a catalog node may be exposed as a tool of an out-of-workflow agent — judged from its meta (kind, dynamic, agentTool opt-in) and the composability of its context against the context-kind registry (a kind with an idField is composable by the caller).
@meridian/shared/engine/schedule ScheduleRuleSchema/ScheduleRule, ScheduleConfigSchema/ScheduleConfig, MIN_PERIOD_SECONDS, helpers The trigger.schedule rule grammar (cron/period) and its validation helpers.

observability/trace

Export Purpose
tracer The single OpenTelemetry tracer instance (meridian), shared by proxy, engine and plugins so spans assemble into one end-to-end trace.
TraceCarrier Record<string, string> — a W3C traceparent/tracestate carrier for out-of-band propagation (e.g. a Restate invocation payload).
withSpan() Runs a function inside an active span; records exceptions and sets ERROR status on throw.
injectTraceContext() Captures the active trace context into a serializable carrier.
runWithRemoteContext() Restores a carrier's trace context and runs a function under it.

Depends only on @opentelemetry/api — a no-op API when no SDK is registered, so this module costs nothing unless observability is enabled. See Enable observability and Observability signals.

Shared expression and configuration validation

@meridian/shared/engine/expression exports the existing JEXL evaluator (evalExpression, compiledExpression, expressionAst, TRANSFORM_NAMES). @meridian/shared/engine/expression-check exports expressionProblems for the standard expression kinds or an explicit array of allowed root names. @meridian/shared/engine/config-schema exposes configSchemaError and configValueErrors, the same JSON Schema checks used by the engine. @meridian/shared/engine/text-value exposes the shared value formatter. The engine-core paths re-export these implementations. Metadata and port resolution do not import the evaluator; plugin behaviors and host-side assistance can opt into it without bringing plugin code into the browser.

version

Export Value
PLUGIN_CONTRACT_VERSION "0.1.6" (libs/shared/src/version.ts)

A plugin declares the contract range it needs in its manifest (sdk: "^0.1.1"). At plugin discovery the host (apps/api/src/plugins.ts) checks that range against PLUGIN_CONTRACT_VERSION using satisfies() from the npm semver package (no hand-rolled semver comparison); a plugin whose range does not match is logged and skipped, the others still load. See the sdk field in Plugin manifest.

The version follows its own doctrine:

  • patch (0.1.0 → 0.1.1): a new manifest key that an older host would strip (the schema drops a key it does not know: a host that reports unknown keys, kind key, logs it at load; an earlier host drops it silently) and that changes what gets loaded. A plugin using it declares sdk: "^0.1.<patch>", so an older host refuses it instead of loading it by halves, while existing plugins (^0.1.0) stay accepted. 0.1.1 adds declared events (contributes.events, a trigger's event, an output's from); meridian-plugin validate/build fail on a manifest that uses them with a lower range, and the host warns. 0.1.2 adds resolve.pending on an event binding (the validation a decision is about); no load check covers its range. 0.1.3 adds the default filter of a declared event (events[].defaultSelector), checked like 0.1.1. 0.1.4 adds the description of a protocol's reception (receive.mediaTypes, receive.example, a transport written { name, defaultPort?, hint? }), checked like 0.1.1. 0.1.5 adds the derivedPorts rule when, checked the same way. 0.1.6 adds connections (contributes.connectionTypes, connection on an adapter, an event source or a node), checked like 0.1.1;
  • minor: a real break of the plugin-facing surface (a type, port, helper or manifest form removed or renamed) — plugins must be republished with a widened range;
  • nothing: an addition an older host can ignore without consequence, such as SubjectRecordPort.closeValidationRequest: an optional adapter method, with no manifest key, that a host which does not know it never calls, or label and params on an event source, which an older host drops at load (« clé ignorée »).

0.1.3 also removes two manifest forms, the node-level defaultSelector and the trigger without pinnedRouting and without event, which the rule above puts in a minor. It stays a patch by a decision specific to this release: only @posos/common used one of these forms in the repository, and each removal is reported at load, never dropped silently. A plugin in ^0.1.x stays accepted and shows the problem.

A host of contract 0.1.3 refuses a plugin in ^0.1.4: with a contract problem when its schema reads the manifest (it would drop the two keys), with « manifeste invalide » when a transport is written as an object, since its schema reads a transport as a name and parses the manifest before the sdk range. A transport written by its name stays valid, and plugins in ^0.1.x stay accepted.

A host of contract 0.1.5 refuses a plugin in ^0.1.6 with a contract problem; plugins in ^0.1.x stay accepted.

The check of the dependsOn ranges (kind dependency) has no contract version of its own: it adds no manifest key, and a host that predates it ignores the ranges, as every host did before. Requiring a higher sdk floor to get the check would make a rolled-back image refuse the plugins.

What is not exported

The SDK exposes contracts and pure/registry helpers only. It has no CLI (that is @meridian/plugin-cli, see meridian-plugin CLI), no plugin loader or filesystem discovery (that is the API host's PluginHost), and no bundler (plugins are built with meridian-plugin build, an esbuild bundle — see Bundling and distribution and Build and bundle). Publishing and registry resolution (meridian-plugin publish, the instance manifest's registry:/plugins: fields, the MERIDIAN_REGISTRY environment variable) are documented in Publish to the registry and Set up a plugin registry.

97 documents10 sectionssource : /docs · généré au build