Skip to content

@manifesto-ai/compiler ​

MEL compiler package for importing .mel domains 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:

typescript
import { melPlugin } from "@manifesto-ai/compiler/vite";

export default {
  plugins: [melPlugin()],
};

Then the app imports the MEL domain and activates the SDK runtime:

typescript
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 .mel domains 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()
  • SchemaGraph extraction for tools
  • structural annotations via @meta as an out-of-schema AnnotationIndex sidecar
  • declaration-level source locations as an out-of-schema SourceMapIndex sidecar
  • 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.

typescript
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.

typescript
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:

typescript
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.

typescript
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, not DomainModule.
  • Tooling can use compileMelModule() to read graph, annotations, and sourceMap.
  • If you compile through compileMelModule(), pass module.schema to runtime creation and keep module.annotations and module.sourceMap external.
  • .mel loader and bundler integrations still default-export compiled DomainSchema, even when the source uses @meta.
typescript
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 ​

typescript
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;
};
  • schemaHash matches the emitted DomainSchema.hash.
  • entries includes annotated targets only.
  • stacked annotations preserve source order.
  • repeated tags are preserved and not deduplicated.
  • sourceMap is keyed by the same landed declaration target space and carries physical source spans only.
  • sourceMap remains tooling-only and does not participate in runtime schema input, schema hash, or SchemaGraph derivation.

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 / MelIRPatchPath
  • RuntimeConditionalPatchOp

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.

PackageRelationship
@manifesto-ai/coreExecutes compiled DomainSchema semantics
@manifesto-ai/sdkAccepts DomainSchema or MEL source at runtime creation, not DomainModule
ApplicationRuntime-facing createManifesto() entrypoint
MEL DocsLanguage reference and examples