ziran api --json --root DIR file.zi loads and checks the input and its
transitive imports, then prints one bounded JSON object describing visible declarations
in each loaded module. The same command accepts saved .zir inputs. Use
--module-path DIR for import search roots and --define NAME for the same
conditional source selection as ziran check. A project
can use ziran api --project --locked --json to query its entry and imports.
Without --json, the command prints concise text signatures with source
locations. A failed load or check exits nonzero and does not print an API
object.
The JSON object has schema_version: 1 and a modules array. Each module has
name, source, imports, constants, globals, types, and functions.
Imports include their kind, alias/name, target, foreign target and symbol when
present, signature, and source location. Constants expose their checked value
text; globals expose their type and initializer text. A type includes its name,
checked body text, type parameters, record-template, enum, and procedure flags,
a procedure type's return_type (empty for other types), and source path
and line. A function includes its name, checked parameter signature, return
type, declaration defaults, inferred effect, must_use, template and host-use
flags, and source path and line. Empty defaults and effect strings mean the
corresponding information is absent. Consumers should reject unknown schema
versions and ignore new fields within a known version.
Only declarations visible across module boundaries appear. File/module-private declarations, generated specializations, and compiler-generated default argument helpers are omitted. The output lists each loaded module separately; it does not flatten import names into the entry module. For example:
ziran api --json --root std std/json_scan.zi
The additive schema-1 retrieval fields include document identities, semantic
symbol IDs, checked ownership, module laws and exact known source anchors.
Per-symbol target availability and checked usage examples remain unavailable;
examples is explicitly null. Use ziran capabilities --json for
target-wide limits, use ziran explain to decode diagnostic
codes, and compile a small call before relying on a target that has not been
exercised by your project.
Scoped retrieval and budgets
Use --module NAME to select one loaded module, --symbol NAME to select an
exact public declaration name (including all matching overloads), or
--symbol ID to retrieve its opaque semantic id. Both filters compose.
--imports-only returns the checked module import graph without declarations
or function bodies; resolved_module is the actual resolved module when known.
Compile-time file composition is not reconstructed as a separate graph when
checked IR has no import edge for it. Package module imports have one slash,
#import "package/Module"; relative source composition uses the explicit
#import, file "path.zi" form. Private helpers need not become public to use
that file form.
These symbol/import filters require --json.
ziran api --json --module json_scan --symbol JsonNext --max-bytes 8192 \
--root std std/json_scan.zi
--max-symbols N defaults to 256 and accepts 1–4096. --max-bytes N defaults
to 65536 and accepts 1024–1048576. The byte limit includes JSON framing,
query and truncation metadata, and the final newline. Whole declarations are
omitted when needed; strings and JSON objects are never cut. An insufficient
budget for the module framing rejects with no API output; narrow --module
or increase the budget. Text output also respects the byte budget and rejects
rather than publishing a partial projection. Output byte counts are not token
counts.
query records the exact filter and requested limits. truncation reports
matched_symbols, emitted_symbols, complete, symbol_limit and byte_limit.
Imports, declarations and laws count as symbols. A missing name returns zero
matches; truncation never implies the omitted declarations do not exist.
Modules sort by checked module identity; declaration order within each kind
follows checked IR. Repeated equivalent invocations produce identical bytes.
Each declaration's id hashes a versioned, NUL-delimited checked identity:
module, declaration kind, name and relevant checked signature/type parameters.
Function bodies, document versions and incidental line positions do not change
that identity. Overloads have distinct signature identities. These IDs are
opaque retrieval keys, not compatibility promises across semantic signature
changes. Source and saved IR preserve the same semantic IDs and coverage.
document records available, sha256 and bytes for the raw bytes captured
before source rewriting; the API does not reread files after checking.
Saved IR does not retain the raw source identity: its fields are false/null,
even when a same-named source file happens to exist. Hashes and line-offset
tables belong to the compiler context and are freed with it. Offset retention
is capped at 1 MiB per document and 8 MiB per context; a large document retains
its hash/length while its byte offsets remain null. Contexts hold at most 4096
distinct document versions; exceeding that limit rejects the parse explicitly.
Raw source bodies are not duplicated in this registry.
span.kind: "declaration_anchor" identifies the exact extent the checked
parser retained, which may be only a declaration header. It never claims a
whole body. Coordinates are one-based UTF-8 byte columns and half-open end
positions. If source rewriting changed byte positions (including #string),
coordinate_space is rewritten_source and raw byte offsets are explicitly
unavailable; no rewrite map is guessed. Otherwise it is source.
start_byte/end_byte are zero-based offsets, or null when source
identity/offsets are unavailable. The existing path and line fields remain.
ownership is derived from checked type identity. Function parameters and
results report move for owned storage, borrow for pointers/slices, copy
for copyable values, and none for void. Unresolved template ownership is
null. Type declarations report the corresponding value mode. Module laws
include checked claims and their evaluated status when available; unavailable
status is null. They explicitly carry visibility: "module_contract": checked
IR has no separate law visibility field, so the API preserves those module
contracts without guessing public/private status from source. This is distinct
from exporting a procedure. Private declarations and generated helpers remain
omitted. Every entry also records its symbol_kind.