astra-lang.org

Machine interface · integration spec

The compiler is an API.
This page is its documentation.

If you're building an agent, a coding assistant, or a framework that generates Astra, everything you need is here: the CLI surface, the JSON contract, the error-code catalog, and the canonical loop.

SurfaceThree commands, stable semantics

CommandWhat it doesExit code
astra verify --error-format=json <file> Parse + typecheck only. No codegen, no execution. ~100 ms. 0 = verified · non-zero = diagnostics emitted
astra compile --error-format=json <file> --output <bin> Full pipeline to a native executable. 0 = binary written · non-zero = failed
astra explain E0002 Expands any error code into a full explanation + guidance. 0

Rust callers can skip the CLI entirely:

let report = astra::compiler::verify(source);
let result = astra::compiler::compile_to_result(source);

ContractThe diagnostic JSON shape

One object per invocation. Fields are stable; new fields may be added, existing ones are never repurposed.

{
  "success": false,
  "diagnostics": [
    {
      "phase": "typecheck",       // "parse" | "typecheck" | "codegen"
      "kind": "TypeError",        // coarse class
      "error_code": "E0002",      // stable, catalog below
      "message": "Type error: Undefined variable 'total'",
      "file": null,
      "line": 4,                  // 1-based; null if unresolvable
      "column": 12,               // 1-based; null if unresolvable
      "severity": "error",
      "suggestion": "Declare 'total' with let before use, e.g. let total = ...;"
    }
  ]
}
  • Parse errors always carry line and column of the offending token.
  • Typecheck errors carry them when the error names a symbol; otherwise null (never 0).
  • suggestion is a human/LLM-readable repair hint, name-aware where possible.
  • Success shape: {"success": true, "diagnostics": []}.

CatalogStable error codes

Codes are permanent identifiers — safe to branch on, cache repair strategies against, or fine-tune with. astra explain E#### returns the long-form description for any of them.

CodeMeaningTypical agent repair
E0001Syntax errorRe-emit the statement; check delimiters and semicolons
E0002Undefined variableDeclare with let, or fix the identifier spelling
E0003Undefined functionDefine the function or correct the call target
E0004Type mismatchAlign value type with the annotation / return type
E0005Wrong number of argumentsMatch the call to the function signature
E0006Condition must be booleanUse a comparison, not a bare value, in if/while
E0007Unknown methodCheck the receiver type's supported methods
E0008Cannot index non-arrayIndex arrays only; check the variable's type
E0009Duplicate definitionRename or remove the redefinition
E0010Struct field errorUse fields declared on the struct; check literal completeness
E0011Generic type errorMake type parameters consistent at the call site
E0012IO errorCheck the file path passed to the CLI
E0099Internal / uncategorizedReport upstream; do not retry blindly

The loopCanonical integration pattern

# pseudocode for any agent framework
source = llm.generate(task)

for attempt in 1..MAX_REPAIRS:
    report = run("astra verify --error-format=json", source)
    if report.success:
        break                                # verified — safe to compile
    source = llm.repair(source, report.diagnostics)
                                             # feed error_code + line +
                                             # column + suggestion back in

binary = run("astra compile --error-format=json", source)
execute(binary)                              # native, already typechecked

Why this converges better than a Python retry loop:

  • Diagnostics are positional — the model repairs one pinpointed line instead of regenerating the file.
  • Codes are categorical — frameworks can route E0002 to a cheap local fix and reserve the LLM for E0004/E0011.
  • Verification is ~100 ms — cheaper than any token round-trip, so verify after every single edit.
  • Whole error classes cannot escape to runtime, so the expensive failure mode (bad code executing) is structurally removed.

Versioning promise: the JSON field set and the E-code catalog only grow — existing codes and fields are never renamed or repurposed. Breaking changes to this contract would get a major version bump and a migration note on this page.