Lexicon Authoring Overview
A lexicon is a plugin that teaches chant about a specific operational area — types, lint rules, serialization, and build validation. You can create lexicons for any infrastructure platform, internal tool, or custom domain.
When You Need This Section
Section titled “When You Need This Section”You’re in the right place if you want to:
- Add support for a new cloud provider (GCP, Azure, Kubernetes)
- Create an internal lexicon for your organization’s infrastructure patterns
- Extend chant with custom resource types and lint rules
If you’re using an existing lexicon (like AWS CloudFormation), see the User Guide instead.
The LexiconPlugin Interface
Section titled “The LexiconPlugin Interface”Every lexicon exports a LexiconPlugin object:
import type { LexiconPlugin } from "@intentius/chant";
export const myPlugin: LexiconPlugin = { name: "my-lexicon", serializer: mySerializer, // ... lifecycle methods};Required fields
Section titled “Required fields”| Field | Type | Description |
|---|---|---|
name | string | Human-readable name (e.g. "aws", "gcp") |
serializer | Serializer | Serializer for build output |
Required lifecycle methods
Section titled “Required lifecycle methods”Every lexicon must implement these 4 methods to support the full generation and distribution workflow:
| Method | Signature | Description |
|---|---|---|
generate | (options?) => Promise<void> | Generate lexicon artifacts (types, registry, runtime) from upstream spec |
validate | (options?) => Promise<void> | Validate generated artifacts |
coverage | (options?) => Promise<void> | Analyze spec coverage across resource dimensions |
package | (options?) => Promise<void> | Package lexicon into a distributable bundle |
Optional methods
Section titled “Optional methods”| Method | Returns | Description |
|---|---|---|
lintRules() | LintRule[] | Imperative lint rules |
declarativeRules() | RuleSpec[] | Declarative lint rules (compiled via rule()) |
postSynthChecks() | PostSynthCheck[] | Post-build validation checks |
intrinsics() | IntrinsicDef[] | Lexicon-specific intrinsic functions |
pseudoParameters() | string[] | Pseudo-parameter names |
detectTemplate() | boolean | Detect if a template belongs to this lexicon |
templateParser() | TemplateParser | Parser for importing external templates |
templateGenerator() | TypeScriptGenerator | Generator for converting IR to TypeScript |
initTemplates(template?) | InitTemplateSet | Source file templates for chant init scaffolding (accepts optional template name) |
skills() | SkillDefinition[] | AI assistant skills |
completionProvider() | CompletionItem[] | LSP completions for resource/property names |
hoverProvider() | HoverInfo | LSP hover information for resource types |
docs() | Promise<void> | Generate documentation pages |
mcpTools() | McpToolContribution[] | MCP tool contributions |
mcpResources() | McpResourceContribution[] | MCP resource contributions |
Registering in chant.config.ts
Section titled “Registering in chant.config.ts”Users register lexicons in their project config:
import type { ChantConfig } from "@intentius/chant";
export default { lexicons: ["my-lexicon"],} satisfies ChantConfig;The CLI resolves lexicons by looking for @intentius/chant-lexicon-{name} packages in node_modules.
Authoring Workflow
Section titled “Authoring Workflow”Building a lexicon follows these steps:
- Scaffold —
chant init lexicongenerates the project structure - Implement Generate — wire up
generatePipelinewith your upstream spec - Create a Serializer — convert evaluated resources to your target format
- Write Lint Rules — imperative, declarative, and post-synth checks
- LSP & MCP Providers — editor completions, hover, and AI tool support
- Skills — AI agent skill files
- Package & Publish — bundle and publish to npm
- CI & Distribution —
chant dev onboardwires CI, Docker smoke tests, and npm publishing
Example: Minimal Custom Lexicon
Section titled “Example: Minimal Custom Lexicon”import type { LexiconPlugin, Serializer, Declarable } from "@intentius/chant";
const serializer: Serializer = { name: "k8s", rulePrefix: "K8S", serialize(entities: Map<string, Declarable>): string { const manifests = []; for (const [name, entity] of entities) { manifests.push({ apiVersion: "v1", kind: entity.entityType, metadata: { name }, }); } return JSON.stringify(manifests, null, 2); },};
export const k8sPlugin: LexiconPlugin = { name: "k8s", serializer,
async generate() { // TODO: Fetch upstream schemas and run generatePipeline throw new Error("Not yet implemented"); },
async validate() { // TODO: Validate generated artifacts console.error("All checks passed."); },
async coverage() { // TODO: Analyze spec coverage console.error("Coverage analysis not yet implemented."); },
async package() { // TODO: Run packagePipeline to produce a distributable bundle throw new Error("Not yet implemented"); },};Publish this as @intentius/chant-lexicon-k8s (or @yourorg/lexicon-k8s) and users can add it to their project.
Background Reading
Section titled “Background Reading”These architecture pages cover the internals a lexicon author needs to understand:
- Core Type System —
Declarable,ResourceType, and the evaluator’s type model - Lexicon Registry — how chant discovers, loads, and validates lexicon plugins
- Serializer Architecture — the serialization contract your plugin must implement