Skip to content

IR schema

Axint’s Intermediate Representation (IR) is the cross-language contract that makes it possible for both the TypeScript and Python SDKs to produce byte-identical Swift output. Every authoring surface eventually serializes to this schema; the validator and generator operate purely on the IR.

JSON schema

{
"name": "CreateCalendarEventIntent",
"title": "Create Calendar Event",
"description": "Creates a new event on the user's calendar.",
"domain": "productivity",
"isDiscoverable": true,
"parameters": [
{
"name": "eventTitle",
"type": "string",
"description": "Title of the event",
"optional": false,
"default": null
},
{
"name": "durationMinutes",
"type": "int",
"description": "Length of the event in minutes",
"optional": false,
"default": null
}
],
"entitlements": ["com.apple.developer.calendars"],
"infoPlistKeys": ["NSCalendarsUsageDescription"],
"returnType": null,
"sourceFile": "intents/create_event.ts",
"sourceLine": 3
}

Field reference

FieldTypeNotes
namestringSwift struct name
titlestringHuman-facing title
descriptionstringHuman-facing description
domainstringApp Intent domain
isDiscoverablebooleanDefaults to true
parametersIRParameter[]Ordered list (insertion order preserved)
entitlementsstring[]Reverse-DNS identifiers
infoPlistKeysstring[]Info.plist usage description keys
returnTypeIRType | nullInferred from perform(); null if none
sourceFilestringSource file for diagnostics
sourceLinenumberLine where defineIntent(...) starts

IRParameter

FieldTypeNotes
namestringParameter name in source
typeIRTypeSee below
descriptionstringUsed as @Parameter(title:)
optionalbooleanDefaults to false
defaultunknown | nullOnly valid if optional: true

IRType

One of: "string", "int", "double", "float", "boolean", "date", "duration", "url", or the legacy alias "number" (which normalizes to "int" during validation).

Why camelCase?

The IR uses camelCase keys (isDiscoverable, infoPlistKeys) even when authored from Python, because the JSON schema is the cross-language contract and needs to be stable across both sides. The Python IntentIR.to_dict() method emits camelCase specifically for this reason.

Using the IR directly

You can consume IR JSON directly without using either SDK — useful for building your own authoring layer on top:

import { generateSwift, validateIntent } from "@axint/compiler";
const ir = JSON.parse(irJson);
const diagnostics = validateIntent(ir);
if (diagnostics.some(d => d.severity === "error")) {
console.error(diagnostics);
process.exit(1);
}
const swift = generateSwift(ir);