@manifesto-ai/compiler
MEL compiler package for importing
.meldomains into SDK apps and tooling.
Overview
@manifesto-ai/compiler provides the MEL compilation seams used by runtime creation, tooling, and bundler integration.
Most app code reaches it through a bundler plugin:
import { melPlugin } from "@manifesto-ai/compiler/vite";
export default {
plugins: [melPlugin()],
};Then the app imports the MEL domain and activates the SDK runtime:
import { createManifesto } from "@manifesto-ai/sdk";
import TodoMel from "./todo.mel";
const app = createManifesto(TodoMel, {}).activate();For normal app code, stop at the bundler plugin and import the .mel file from your SDK runtime module. Use the direct compile APIs below when you are writing build scripts, editor tooling, Studio-style inspection, or tests.
The current canonical compiler contract is documented in the current SPEC index, with the compiler aligned to v5.0.0 in packages/compiler/docs/SPEC-v1.2.0.md.
Current compiler responsibilities include:
- bundler and loader seams for importing
.meldomains into apps - optional generated domain facades for SDK/React/agent TypeScript code
- schema-only compilation through
compileMelDomain()for tooling - tooling-only module compilation through
compileMelModule() SchemaGraphextraction for tools- structural annotations via
@metaas an out-of-schemaAnnotationIndexsidecar - declaration-level source locations as an out-of-schema
SourceMapIndexsidecar - authoring-time source edits through
compileFragmentInContext() - intent-level dispatchability via
dispatchable when - dynamic patch target lowering/preservation through full-domain compilation
Current compiler highlights include:
- object-literal spread as the sole bounded parser-level shorthand
- canonical lowering of spread through
merge(...) - presence-aware object typing shared by spread and direct
merge() - optional spread-result reads observed as
T | null, requiring explicit normalization before non-null sinks - compiler-owned MEL source-fragment editing for authoring-time tooling
Direct Tooling Entry Points
compileMelDomain()
Use compileMelDomain() when you need the semantic runtime artifact only.
import { compileMelDomain } from "@manifesto-ai/compiler";
const result = compileMelDomain(melSource, { mode: "domain" });
if (result.schema) {
// Runtime-facing seam
const schema = result.schema;
}compileMelDomain() returns DomainSchema only. Structural annotations and source maps never appear inside that schema.
compileMelModule()
Use compileMelModule() when tooling needs compiler-owned helper artifacts in addition to the schema.
import { compileMelModule } from "@manifesto-ai/compiler";
const result = compileMelModule(melSource, { mode: "module" });
if (result.module) {
const { schema, graph, annotations, sourceMap } = result.module;
}compileMelModule() returns a tooling-only DomainModule:
type DomainModule = {
readonly schema: DomainSchema;
readonly graph: SchemaGraph;
readonly annotations: AnnotationIndex;
readonly sourceMap: SourceMapIndex;
};annotations is the compiler-owned sidecar for @meta. sourceMap is the compiler-owned sidecar for declaration-level MEL provenance. Both remain outside DomainSchema and SchemaGraph.
compileFragmentInContext()
Use compileFragmentInContext() when authoring-time tooling needs the compiler to validate and materialize one MEL source edit.
import { compileFragmentInContext } from "@manifesto-ai/compiler";
const compileResult = compileFragmentInContext(melSource, {
kind: "addComputed",
name: "nextCount",
expr: "add(count, 1)",
}, { includeSchemaDiff: true });
if (compileResult.ok) {
const nextSource = compileResult.newSource;
const changedTargets = compileResult.changedTargets;
const impact = compileResult.schemaDiff;
}compileFragmentInContext() is a tooling API, not a runtime mutation API. It returns a full newSource string, diagnostics, base-source text edits, changed targets, and optional schema impact. The caller decides whether to accept the edit and where to store the source.
Pre-materialization failures return diagnostics as values with newSource === baseSource, empty edits, and empty changedTargets. The compiler rejects invalid operation shapes, raw-splice attempts through identifiers or JSON object keys, invalid JSON defaults, stale baseModule inputs, missing targets, and target-kind mismatches before producing text edits.
removeDeclaration and renameDeclaration are Safe v1 all-or-nothing edits. The compiler materializes complete edits when references are provably safe, including compiler-known rename references, and otherwise returns diagnostics such as E_REMOVE_BLOCKED_BY_REFERENCES or E_UNSAFE_RENAME_AMBIGUOUS with no partial edits.
Runtime creation still consumes DomainSchema. If a tool accepts an edited source, compile the accepted source through compileMelDomain() or compileMelModule() and pass only the resulting schema into runtime seams.
Dynamic Patch Targets
Dynamic patch targets are part of full-domain Flow semantics.
The compiler parses and type-checks MEL target syntax, then preserves dynamic target expressions for Core. Core resolves those targets during compute() before emitting concrete Patch[].
New integrations should compile a full MEL domain through compileMelDomain() or compileMelModule() and pass only the resulting DomainSchema to runtime creation.
Tooling vs Runtime
- Runtime seams consume
DomainSchema, notDomainModule. - Tooling can use
compileMelModule()to readgraph,annotations, andsourceMap. - If you compile through
compileMelModule(), passmodule.schemato runtime creation and keepmodule.annotationsandmodule.sourceMapexternal. .melloader and bundler integrations still default-export compiledDomainSchema, even when the source uses@meta.
import { compileMelModule } from "@manifesto-ai/compiler";
import { createManifesto } from "@manifesto-ai/sdk";
const result = compileMelModule(melSource, { mode: "module" });
const module = result.module!;
const app = createManifesto(module.schema, {}).activate();
const annotations = module.annotations;
const sourceMap = module.sourceMap;Tooling Sidecar Types
type Annotation = {
readonly tag: string;
readonly payload?: JsonLiteral;
};
type AnnotationIndex = {
readonly schemaHash: string;
readonly entries: Record<LocalTargetKey, readonly Annotation[]>;
};
type SourceMapIndex = {
readonly schemaHash: string;
readonly sourceHash: string;
readonly format: "manifesto/source-map-v1";
readonly coordinateUnit: "utf16" | "bytes";
readonly emissionFingerprint: string;
readonly entries: Record<LocalTargetKey, SourceMapEntry>;
};
type SourceMapEntry = {
readonly target: SourceMapPath;
readonly span: SourceSpan;
};schemaHashmatches the emittedDomainSchema.hash.entriesincludes annotated targets only.- stacked annotations preserve source order.
- repeated tags are preserved and not deduplicated.
sourceMapis keyed by the same landed declaration target space and carries physical source spans only.sourceMapremains tooling-only and does not participate in runtime schema input, schema hash, orSchemaGraphderivation.
Retired v5 Patch Evaluation Surface
ADR-028 removes compiler-owned runtime patch evaluation from the current v5 contract. The compiler does not evaluate dynamic target expressions, allocate runtime values, emit "*" placeholder targets, or produce runtime patches from runtime data.
The following APIs are not current v5 integration seams:
compileMelPatch()evaluateConditionalPatchOps()evaluateRuntimePatches()evaluateRuntimePatchesWithTrace()lowerRuntimePatch()/lowerRuntimePatches()IRPatchPath/MelIRPatchPathRuntimeConditionalPatchOp
The generated public-surface inventory no longer lists these retired APIs after ADR-028 PR-3. This curated guide describes the current compiler contract rather than the historical patch-evaluation surface.
Related Packages
| Package | Relationship |
|---|---|
| @manifesto-ai/core | Executes compiled DomainSchema semantics |
| @manifesto-ai/sdk | Accepts DomainSchema or MEL source at runtime creation, not DomainModule |
| Application | Runtime-facing createManifesto() entrypoint |
| MEL Docs | Language reference and examples |