Expand description
§The host API (VAPP-91)
What a surface needs from its host, the same on all four platforms
(packages/exponential-ui/catalog/host.json): the router turning server
messages into ops, the wire decoders (JSONL, SSE, A2UI-over-MCP), the
function / URL / media policy, binding sources, catalog negotiation and
declarative app packages. A line-by-line port of the TypeScript reference
(packages/exponential-ui/src/host/) over serde_json::Value; every
output is JSON-equal to it, locked by fixtures/host-*.json. The I/O
(transports, the runtime host) stays on each platform; the Swift and
Kotlin painters reach this module through exponential-ui-ffi.
Re-exports§
pub use actions::action_call_name;pub use actions::action_var_types;pub use actions::apply_record_batch;pub use actions::apply_record_batch_as;pub use actions::function_effect;pub use actions::is_action_name;pub use actions::run_action;pub use actions::validate_package_actions;pub use actions::validate_package_effects;pub use actions::ActionContext;pub use actions::ACTION_CALL_PREFIX;pub use actions::ACTION_LIMIT_ACTIONS;pub use actions::ACTION_LIMIT_MAX_STEPS;pub use actions::ACTION_LIMIT_STEPS;pub use actions::ACTION_NAME_PATTERN;pub use actions::ACTION_STEP_KINDS;pub use actions::RECORDS_BATCH_FUNCTION;pub use components::validate_package_components;pub use expressions::literal_type;pub use expressions::record_row_type;pub use expressions::records_value_type;pub use expressions::schema_type;pub use expressions::validate_package_expressions;pub use expressions::validate_record_computed;pub use exposes::expose_action_access;pub use exposes::expose_issues;pub use exposes::expose_name_destructive;pub use exposes::expose_template_paths;pub use exposes::validate_package_exposes;pub use exposes::validate_upstreams;pub use exposes::ExposeIssue;pub use decoders::decode_jsonl;pub use decoders::mcp_action_call;pub use decoders::messages_from_mcp_result;pub use decoders::DecodeIssue;pub use decoders::Decoded;pub use decoders::JsonlDecoder;pub use decoders::SseDecoder;pub use package::available_extensions;pub use package::client_capabilities;pub use package::merge_data;pub use package::package_sources;pub use package::source_allowed;pub use package::supported_catalog_ids;pub use package::template_messages;pub use package::validate_package;pub use package::validate_package_in;pub use package::validate_package_with;pub use package::version_satisfies;pub use package::AvailableExtension;pub use package::PackageIssue;pub use package::PACKAGE_FORMAT_VERSION;pub use policy::combine_decisions;pub use policy::decide_function;pub use policy::decide_url;pub use policy::image_dimensions;pub use policy::image_frames;pub use policy::image_header;pub use policy::is_builtin_function;pub use policy::is_private_host;pub use policy::media_image_check;pub use policy::ImageHeader;pub use policy::matches_pattern;pub use policy::media_image_within_limits;pub use policy::media_request;pub use policy::media_within_limits;pub use policy::package_policy;pub use policy::svg_dimensions;pub use policy::safe_href;pub use policy::FunctionDecision;pub use policy::FunctionPolicy;pub use policy::MediaOptions;pub use policy::MediaRequest;pub use policy::MediaRule;pub use policy::UrlDecision;pub use policy::UrlPolicy;pub use policy::BUILTIN_FUNCTIONS;pub use router::normalize_path;pub use router::HostRouter;pub use router::SurfaceInfo;pub use screens::fill_screen_params;pub use screens::package_screens;pub use screens::resolve_screen;pub use screens::screen_data;pub use screens::validate_package_screens;pub use screens::ResolvedScreen;pub use screens::MAX_SCREENS;pub use screens::MAX_SCREEN_TITLE;pub use screens::NAVIGATE_FUNCTION;pub use screens::SCREEN_PARAMS_KEY;pub use query::computed_data;pub use query::expand_query_source;pub use query::fill_query_templates;pub use query::kind_computed;pub use query::kind_refs;pub use query::month_days;pub use query::month_label;pub use query::parse_records_json;pub use query::parse_records_query;pub use query::parse_records_source;pub use query::records_value;pub use query::records_value_owned;pub use query::shift_month;pub use query::RecordRow;pub use query::RecordRowRef;pub use query::RecordsAggregate;pub use query::RecordsAggregateOp;pub use query::RecordsBefore;pub use query::RecordsContext;pub use query::RecordsDay;pub use query::RecordsFilter;pub use query::RecordsFilterOp;pub use query::RecordsFilterValue;pub use query::RecordsGroupKey;pub use query::RecordsMonthView;pub use query::RecordsOrder;pub use query::RecordsQueryIssue;pub use query::RecordsRunning;pub use query::RecordsRunningOp;pub use query::RecordsQuery;pub use query::RecordsSortKey;pub use query::RECORDS_AGGREGATE_OPS;pub use query::RECORDS_AGGREGATE_RESERVED;pub use query::RECORDS_COMPUTED_MAX;pub use query::RECORDS_COMPUTED_ROW_KEYS;pub use query::RECORDS_FILTER_OPS;pub use query::RECORDS_MONTHS;pub use query::RECORDS_OP_ALIASES;pub use query::RECORDS_RUNNING_OPS;pub use query::RECORDS_RESERVED_PARAMS;pub use query::RECORDS_ROW_KEYS;pub use query::RECORDS_SCHEME;pub use query::RECORDS_WEEKDAYS;pub use record_migrations::is_version_range;pub use record_migrations::kind_changes;pub use record_migrations::kind_changes_json;pub use record_migrations::migrate_record;pub use record_migrations::migration_refusal;pub use record_migrations::package_migrations;pub use record_migrations::range_holds;pub use record_migrations::validate_migrations;pub use record_migrations::KindChange;pub use record_migrations::MigrateResult;pub use record_migrations::MIGRATION_OP_NAMES;pub use record_migrations::RECORD_MIGRATIONS_MAX;pub use record_migrations::RECORD_MIGRATION_OPS_MAX;pub use record_transitions::initial_states;pub use record_transitions::kind_transitions;pub use record_transitions::transition_refusal;pub use record_transitions::transitions_from;pub use record_transitions::validate_record_transitions;pub use record_transitions::RecordTransitions;pub use record_transitions::TransitionRefusal;pub use record_transitions::TransitionViewer;pub use record_transitions::RECORD_TRANSITIONS_ROW_KEY;pub use record_transitions::TRANSITION_LEVELS;pub use record_policy::readable_rows;pub use record_policy::record_allowed;pub use record_policy::record_policy;pub use record_policy::record_policy_copy;pub use record_policy::record_refusal;pub use record_policy::validate_record_policy;pub use record_policy::RecordOp;pub use record_policy::RecordPolicy;pub use record_policy::RecordViewer;pub use record_policy::APP_ACCESS_LEVELS;pub use record_policy::DEFAULT_RECORD_POLICY;pub use record_policy::RECORD_POLICY_LEVELS;pub use record_policy::RECORD_POLICY_OPS;pub use record_store::RECORDS_FUNCTIONS;pub use records::is_record_kind;pub use records::record_attachment_fields;pub use records::record_attachment_id;pub use records::record_attachment_ids;pub use records::validate_record;pub use records::validate_record_refs;pub use records::validate_record_schema;pub use records::RECORD_FIELD_TYPES;pub use records::RECORD_FORMATS;pub use records::RECORD_RESERVED_KEYS;pub use signature::canonical_json;pub use signature::package_file_signed_bytes;pub use signature::AUTHOR_KEY_PREFIX;pub use signature::AUTHOR_NAME_MAX;pub use signature::PACKAGE_FILE_SIGNATURE_ALG;pub use signature::PACKAGE_FILE_SIGNATURE_CONTEXT;pub use sources::parse_source;pub use sources::source_with_params;pub use sources::ParsedSource;pub use tests::package_test_issues;pub use tests::run_package_tests;pub use tests::test_failure;pub use tests::test_matches;pub use tests::validate_package_tests;pub use tests::PackageTestResult;pub use tests::PACKAGE_TEST_DEFAULT_AS;pub use tests::PACKAGE_TEST_DEFAULT_NOW;pub use tests::PACKAGE_TEST_DEFAULT_ROLE;pub use tests::PACKAGE_TEST_ROLES;pub use tests::PACKAGE_TEST_KINDS;pub use tests::PACKAGE_TEST_LIMIT_GOT_MAX;pub use tests::PACKAGE_TEST_LIMIT_TESTS;pub use tools::tool_call;pub use tools::tool_consent;pub use tools::tool_consent_key;pub use tools::validate_tools;pub use tools::ToolCall;pub use tools::ToolConsentRow;pub use tools::TOOL_KINDS;pub use contract::*;
Modules§
- actions
- VAPP-194 (eApps E1, spec docs/spec/apps.md §4.5): typed effects, the
twin of
packages/exponential-ui/src/host/actions.ts(read its header). - components
- VAPP-203: install checks every template the way the renderer will. Each
template’s components go through the reducer (
reduce_surface: unknown components, missing or wrong props, child ids that name nothing, cycles, slots, styles), so a package that would render broken never installs. A reducer issue (keyed by a component id) becomes a JSON pointer: the component’s own entry, or, for an id no component has, every place that names it (children/<j>,children/componentId,slots/<name>). The twin ofsrc/host/components.ts(fixtures/host-router.json). - contract
- The host API contract (
catalog/host.json) as constants, plus the client messages every platform host sends (tests/host_fixtures.rsgates the constants against the JSON). - decoders
- The wire decoders every transport adapter shares (pure, incremental,
fixture-locked in
fixtures/host-transport.json): A2UI JSONL over a byte stream, Server-Sent Events, and the A2UI-over-MCP carrier. - exposes
- VAPP-180: the MCP tools a package EXPOSES (docs/package-format.md
“Exposes”): declarative bindings
{name, title, description, input, access, run}a host’s MCP broker lists and runs as the calling person, never code. The format half of the eMCP contract; what a run may reach on a given host is that host’s own check. Mirrorspackages/exponential-ui/src/host/exposes.tsline by line;fixtures/host-router.json(validation) replays it. - expressions
- VAPP-191 (eApps Q2): expressions are type-checked at package validation,
the twin of
src/host/expressions.ts. Every{"call": "expr", "args": {"expr": "<CEL>", "vars": {…}}}anywhere in a template is parsed and checked (crate::cel::check_expression) against the types of its vars: a literal’s own type, a records binding’s value (the kind’s schema fields) or the template data’s; anything else is open (dyn). An issue names the JSON pointer of the expression and the reason (fixtures/expressions.jsonpackages). - package
- Catalog negotiation and declarative app packages (VAPP-82: a manifest + A2UI templates + bindings, data never code).
- policy
- The policy rules every host applies before a client function, a URL open
or a media load (
catalog/host.jsonfunctions / urls / media). Pure;fixtures/host-policy.jsonlocks them on every platform. - query
- VAPP-189 (S1): THE records query, the Rust twin of
packages/exponential-ui/src/host/query.ts, locked byfixtures/records-query.json(parseCases,sourceCases,jsonCases,valueCases,expandCases;bucketCaseslockcrate::dates). A binding’s URL sugar (records:<kind>?q) parses INTO the structuredRecordsQuery;records_valueevaluates it over the rows of any store. The desktop host calls it directly; the Swift and Compose SDKs reach it throughexponential-ui-ffi(parse_records_query_json,parse_records_json,parse_records_source_json,records_value_json). - record_
migrations - eApps R8 (VAPP-233, docs/spec/apps.md §3.6/§2.3): declarative record
migrations between package versions. A line-by-line port of
src/host/record-migrations.ts;fixtures/record-migrations.jsonis the spec (tests/record_migrations.rsreplays it). - record_
policy - eApps R3 (docs/spec/apps.md §3.4, §9): who may read, create, update and
delete a kind’s records, under the member’s app access. A line-by-line
port of
src/host/record-policy.ts;fixtures/record-policy.jsonis the spec (tests/record_policy.rsreplays it). - record_
store - VAPP-161: the format’s NEUTRAL records (docs/package-format.md
“Records”). A surface reads a kind through the binding
records:<kind>?queryand writes through the host functionsrecords.upsert/records.delete; the HOST provides the store. The query and its value aresuper::query(VAPP-189: one evaluator over the rows of any store,fixtures/records-query.json). - record_
transitions - eApps R6 (VAPP-222, docs/spec/apps.md §3.3/§3.4): a kind’s state machine
on ONE enum field (
records.<kind>.transitions). A line-by-line port ofsrc/host/record-transitions.ts;fixtures/record-transitions.jsonis the spec (tests/record_transitions.rsreplays it). - records
- VAPP-122: an app’s RECORDS, its own data. The manifest declares every
kind with a JSON Schema SUBSET (
records: {<kind>: {schema}}); a host validates a record against it before it is stored. Mirrorspackages/exponential-ui/src/host/records.tsline by line;fixtures/host-router.jsonrecordsreplays it. - router
- The host router. Server messages in, ops out (
catalog/host.jsonops); the platform host performs them on its surfaces. Pure and synchronous, sofixtures/host-router.jsonlocks the same behaviour on every platform. - screens
- VAPP-218 (eApps U1): a package’s SCREENS, the navigation manifest. A
line-by-line port of
packages/exponential-ui/src/host/screens.ts;fixtures/host-router.json(validation,screens,navigate) locks the same behaviour on every platform.screens: [{template, title, icon?, params?}]lists the templates a person can open (keyed by the template); the host draws the navigation;app.navigate {screen, params?}opens one, its params landing under/params/*. - signature
- VAPP-161: the PACKAGE FILE’s signed bytes (docs/package-format.md “The
package file”): a context line + the RFC 8785 canonical JSON of the whole
file without
signature. MirrorscanonicalJson+packageFileSignedBytesofpackages/exponential-ui/src/host/signature.ts; the Ed25519 itself is the host’s own (no crypto here).fixtures/host-package.jsoncanonical+signatures[].signedTextreplay it. - sources
- Binding sources. A data model path can follow a host source
(
exp:issues?board=…): the host registers one resolver per scheme, the router emits abindop, the resolver’s emits land at the path. - tests
- VAPP-196 (eApps T1): PACKAGE TESTS, the twin of
packages/exponential-ui/src/host/tests.ts. A package carriestests: [{name, records?, now?, as?, expr | query | action, expect}];validate_packageruns every one on an otherwise valid package, each against its OWN in-memory store seeded withrecords, on a fixed clock (now, UTC) as the memberas. A failing test is an install issue at/tests/<i>(expected vs got). Locked byfixtures/package-tests.json. - tools
- VAPP-161: a package’s TOOLS (docs/package-format.md “Tools”): the MCP
servers and scripts its functions call (
tools.<id>.<name>for an MCP tool,tools.<id>for a script), each behind the consent card the host MUST show before the first call. Mirrorspackages/exponential-ui/src/host/tools.tsline by line;fixtures/host-router.json(validation) andfixtures/host-package.jsonconsent+toolCallsreplay it.