pkl

    Pure MoonBit parser, interpreter, and typechecker experiments for Apple's Pkl language.

    moonbit
    pkl
    parser
    interpreter
    typechecker
    Download zip
    Author
    Version
    0.4.1
    License
    Apache-2.0
    Last updated
    18 days ago
    Downloads
    723

    #mizchi/pkl

    Pure-MoonBit parser, typechecker, evaluator, and renderer for Apple's Pkl language. Builds clean on all four MoonBit targets (native, js, wasm, wasm-gc); the @pkl surface is pure (no IO, no async) so an embedder running in a wasm sandbox can depend on it directly. The cmd/mpkl package includes a Marketplace SKILL.md and a moon runwasm entry for parse, check, eval, and format workflows over inline source or local files with relative imports and cache-backed package:// modules.

    The CLI lives in cmd/mpkl (mpkl parse|check|eval|test|format|analyze|codegen). See the repository README for install / usage / benchmarks against Apple Pkl.

    #What the library exposes

    Entry points:

    • parse_source(source) -> ParseResult — top-level CST-backed parse.
    • eval_source(source) -> EvalResult — parse + evaluate a single source.
    • typecheck_source(source) -> TypecheckResult — parse + typecheck.
    • lint_program(program) -> Array[LintFinding] — static-analysis pass.
    • codegen(program, target) -> String — code generator dispatch (CodegenTarget::MoonBit today).
    • AnalysisSession — incremental, ripple-backed analysis for editor / multi-file flows.

    Renderers (one entry per format): render_value (PCF, default), plus render_value_as_json / _yaml / _xml / _textproto / _properties / _plist / _jsonnet and their _document / _fragment / _with_indent / _with_options variants. Apple Pkl's output { renderer = new <Renderer> { ... } } is honoured.

    Sandbox configuration (configure_sandbox_* / register_*): module allowlist, module paths, package caches, prop: / env: populating, static read-resource registration, import-glob registration, extends-chain parent binding resolver, and the lazy stdlib base.pkl loader. The dynamic resource-reader hook configure_sandbox_resource_reader(scheme, fn(uri) -> SandboxResource?) lets an embedded caller service read("scheme:path") calls in-process (HTTP / DB / shell-exec etc.).

    #Status

    The release gate passes its curated Apple Pkl 0.32.1 LanguageSnippetTests across the advertised renderers (PCF, JSON, YAML, properties, plist, textproto, XML, Jsonnet). Coverage of the broader PCF test surface is 399 / 416 (95.9%) by gold-match. The 17-fixture compatibility work is tracked in #32; see the repository's TODO.md for the current DIFF inventory.

    Known gaps for embedded callers:

    • Eager property evaluation. mpkl evaluates every property of a new T { ... } object eagerly; Apple Pkl is lazy. Object bodies that contain a slot whose body errors on a code path the caller never reads (new Result { cases = cases.length; ... } where cases.length would fail but the caller only reads result.passed) still error in mpkl. Tracked as a follow-up.
    • External-reader subprocess protocol. Apple Pkl's --external-resource-reader=<scheme>=<bin> ships a MessagePack-framed IPC; mpkl's in-process callback hook is the embedded substitute. A subprocess-side adapter would need MoonBit's core / x packages to ship a subprocess runtime first.

    #Versioning

    This is 0.4.1. Pre-1.0 minor bumps may break the public surface — semver promises kick in at 1.0.0.

    AnalysisSession

    pub struct AnalysisSession {
    // private fields
    }

    AnalysisSession::eval_path

    fn AnalysisSession::eval_path(self : AnalysisSession, path : String) -> EvalResult

    AnalysisSession::eval_path_with_runtime_metadata

    fn AnalysisSession::eval_path_with_runtime_metadata(self : AnalysisSession, path : String) -> EvalResult

    Evaluate a module while retaining hidden runtime metadata such as class tags and reflection kinds. Renderers and CLI output projection need these markers; callers displaying ordinary Pkl values should use eval_path.

    AnalysisSession::new

    AnalysisSession::reset_stats

    fn AnalysisSession::reset_stats(self : AnalysisSession) -> Unit

    AnalysisSession::set_source

    fn AnalysisSession::set_source(self : AnalysisSession, path : String, source : String) -> Unit

    AnalysisSession::stats

    AnalysisSession::typecheck_path

    fn AnalysisSession::typecheck_path(self : AnalysisSession, path : String) -> TypecheckResult

    AnalysisStats

    pub(all) struct AnalysisStats {
    parse_count : Int
    typecheck_count : Int
    eval_count : Int
    } derive(Eq,
    Debug
    )

    Annotation

    pub(all) struct Annotation {
    class_name : String
    body_kind : AnnotationBodyKind
    body_text : String
    } derive(Eq,
    Debug
    )

    PKL-128d: structured capture of a single annotation that precedes a declaration. class_name holds the identifier after @ (e.g. "Deprecated", "ModuleInfo", "my.pkg.Custom"). body_text is the verbatim source between the surrounding delimiters; the body_kind field identifies which delimiters were used so a downstream tool (pkldoc / codegen) can re-parse the body in the matching mode without scanning back to the open token.

    Forms recognised:
    • @Name → body_kind = NoBody, body_text = ""
    • @Name(arg, ...) → body_kind = ParenBody, body_text = inside parens
    • @Name { field = expr } → body_kind = BraceBody, body_text = inside braces

    Capturing only the raw text keeps the slice tight: the downstream consumer can lex/parse the body when needed, and the AST avoids carrying a second Expr-tree shape for arguments that the evaluator never sees.

    AnnotationBodyKind

    pub(all) enum AnnotationBodyKind {
    NoBody
    ParenBody
    BraceBody
    } derive(Eq,
    Debug
    )

    BinaryOp

    pub(all) enum BinaryOp {
    Add
    Subtract
    Multiply
    Divide
    IntDivide
    Modulo
    Power
    Equal
    NotEqual
    LessThan
    LessOrEqual
    GreaterThan
    GreaterOrEqual
    And
    Or
    NullCoalesce
    Is
    As
    Pipe
    } derive(Eq,
    Debug
    )

    Binding

    pub(all) struct Binding {
    name : String
    type_name : String?
    value : Expr
    exported : Bool
    is_const : Bool
    annotations : Array[Annotation]
    abstract_slot : Bool
    sibling_slot : Bool
    } derive(Eq,
    Debug
    )

    ClassDecl

    pub(all) struct ClassDecl {
    name : String
    type_parameters : Array[String]
    type_parameter_bounds : Array[String?]
    parent_name : String?
    properties : Array[ClassProperty]
    methods : Array[FunctionDecl]
    annotations : Array[Annotation]
    is_abstract : Bool
    } derive(Eq,
    Debug
    )

    ClassExport

    pub(all) struct ClassExport {
    name : String
    parent_name : String?
    properties : Array[ClassProperty]
    methods : Array[FunctionDecl]
    } derive(Eq,
    Debug
    )

    ClassProperty

    pub(all) struct ClassProperty {
    name : String
    type_name : String?
    value : Expr?
    annotations : Array[Annotation]
    } derive(Eq,
    Debug
    )

    CodegenTarget

    pub(all) enum CodegenTarget {
    MoonBit
    } derive(Eq,
    Debug
    )

    PKL-131b: target-driven codegen dispatcher. Only MoonBit is wired today; the enum + dispatcher pair keeps the public surface stable when future targets (Java / Kotlin / Swift / Go / TypeScript) land — embedders never need to swap entry points or learn a new per-target function name.

    Declaration

    pub(all) enum Declaration {
    ClassDeclaration(ClassDecl)
    FunctionDeclaration(FunctionDecl)
    TypeAliasDeclaration(TypeAliasDecl)
    } derive(Eq,
    Debug
    )

    Diagnostic

    pub(all) struct Diagnostic {
    message : String
    start : Int
    end : Int
    } derive(Eq,
    Debug
    )

    EvalResult

    pub(all) enum EvalResult {
    EvalOk(Value)
    EvalError(Array[Diagnostic])
    } derive(Eq,
    Debug
    )

    Expr

    pub(all) enum Expr {
    IntLiteral(Int64)
    FloatLiteral(Double)
    BoolLiteral(Bool)
    StringLiteral(String)
    NullLiteral
    Identifier(String)
    ImportExpr(String)
    ImportGlobExpr(String)
    ObjectLiteral(Array[ObjectMember])
    TypedObjectLiteral(String, Array[ObjectMember])
    ListingLiteral(Array[Expr])
    MappingLiteral(Array[MappingEntry])
    MemberAccess(Expr, String)
    SafeMemberAccess(Expr, String)
    SubscriptAccess(Expr, Expr)
    AmendExpr(Expr, Array[ObjectMember])
    CallExpr(Expr, Array[Expr])
    LambdaExpr(Array[FunctionParameter], Expr, String?)
    LetExpr(String, String?, Expr, Expr)
    NonNullExpr(Expr)
    UnaryExpr(UnaryOp, Expr)
    BinaryExpr(BinaryOp, Expr, Expr)
    ConditionalExpr(Expr, Expr, Expr)
    ForGenerator(String, String?, Expr, Array[ObjectMember], String?, String?)
    WhenSpread(Expr)
    InterpolatedString(Array[Expr])
    NullSafeCallExpr(Expr, Array[Expr])
    UnsupportedExpr
    ErrorExpr(String)
    } derive(Eq,
    Debug
    )

    FunctionDecl

    pub(all) struct FunctionDecl {
    name : String
    type_parameters : Array[String]
    type_parameter_bounds : Array[String?]
    parameters : Array[FunctionParameter]
    return_type_name : String?
    body : Expr?
    annotations : Array[Annotation]
    is_const : Bool
    is_abstract : Bool
    } derive(Eq,
    Debug
    )

    FunctionParameter

    pub(all) struct FunctionParameter {
    name : String
    type_name : String?
    } derive(Eq,
    Debug
    )

    ImportDecl

    pub(all) struct ImportDecl {
    uri : String
    import_name : String
    is_glob : Bool
    } derive(Eq,
    Debug
    )

    LintFinding

    pub(all) struct LintFinding {
    rule : String
    message : String
    } derive(Eq,
    Debug
    )

    PKL-102: lightweight static-analysis checks surfaced through pkl analyze <file>. Each finding identifies a category (rule) and carries a human-readable message. Source positions become useful once PKL-107 propagates byte offsets into the AST; until then the CLI prints path: rule: message and the byte offsets stay at -1.

    MappingEntry

    pub(all) struct MappingEntry {
    key : Expr
    value : Expr
    } derive(Eq,
    Debug
    )

    ModuleRelation

    pub(all) struct ModuleRelation {
    kind : ModuleRelationKind
    uri : String
    } derive(Eq,
    Debug
    )

    ModuleRelationKind

    pub(all) enum ModuleRelationKind {
    ModuleAmends
    ModuleExtends
    } derive(Eq,
    Debug
    )

    ObjectMember

    pub(all) struct ObjectMember {
    name : String
    type_name : String?
    value : Expr
    annotations : Array[Annotation]
    } derive(Eq,
    Debug
    )

    ParseResult

    pub(all) struct ParseResult {
    root :
    SyntaxNode

    program : Program
    diagnostics : Array[Diagnostic]
    unsupported_syntax : Array[UnsupportedSyntax]
    } derive(Eq)

    Program

    pub(all) struct Program {
    module_name : String?
    module_relation : ModuleRelation?
    imports : Array[ImportDecl]
    declarations : Array[Declaration]
    bindings : Array[Binding]
    body : Expr?
    module_annotations : Array[Annotation]
    } derive(Eq,
    Debug
    )

    SandboxResource

    pub(all) struct SandboxResource {
    uri : String
    resource_uri : String
    text : String
    } derive(Eq,
    Debug
    )

    Type

    pub(all) enum Type {
    IntType
    FloatType
    BoolType
    StringType
    NullType
    ObjectType(Array[TypeMember])
    ClassType(String, Array[TypeMember])
    ListingType(Array[Type])
    MappingType(Array[TypeEntry])
    PairType(Type, Type)
    IntSeqType
    SetType(Array[Type])
    MapType(Array[TypeEntry])
    FunctionType(Array[Type], Type)
    ConstrainedType(String, Type)
    UnionType(Array[Type])
    NullableType(Type)
    DefaultedType(Type)
    TypeVariable(String)
    AnyType
    UnknownType
    } derive(Eq,
    Debug
    )

    TypeAliasDecl

    pub(all) struct TypeAliasDecl {
    name : String
    type_parameters : Array[String]
    target : String
    annotations : Array[Annotation]
    } derive(Eq,
    Debug
    )

    TypeEntry

    pub(all) struct TypeEntry {
    key : Type
    value : Type
    } derive(Eq,
    Debug
    )

    TypeExport

    pub(all) struct TypeExport {
    name : String
    typ : Type
    } derive(Eq,
    Debug
    )

    TypeMember

    pub(all) struct TypeMember {
    name : String
    typ : Type
    } derive(Eq,
    Debug
    )

    TypecheckResult

    pub(all) enum TypecheckResult {
    TypeOk(Type)
    TypeError(Array[Diagnostic])
    } derive(Eq,
    Debug
    )

    UnaryOp

    pub(all) enum UnaryOp {
    Negate
    Not
    } derive(Eq,
    Debug
    )

    UnsupportedSyntax

    pub(all) struct UnsupportedSyntax {
    start : Int
    end : Int
    text : String
    kind : String
    } derive(Eq,
    Debug
    )

    Value

    pub(all) enum Value {
    IntValue(Int64)
    FloatValue(Double)
    BoolValue(Bool)
    StringValue(String)
    NullValue
    DeferredImportValue(String)
    ObjectValue(Array[ValueMember])
    ListingValue(Array[Value])
    ListValue(Array[Value])
    MappingValue(Array[ValueEntry])
    DefaultedListingValue(Array[Value], Array[Value], Value)
    DefaultedMappingValue(Array[ValueEntry], Array[ValueEntry], Value)
    PairValue(Value, Value)
    IntSeqValue(Int64, Int64, Int64)
    SetValue(Array[Value])
    MapValue(Array[ValueEntry])
    FunctionValue(Array[FunctionParameter], Expr, String?, Array[ValueBinding], Int)
    DurationValue(Double, String)
    DataSizeValue(Double, String)
    RegexValue(String)
    BytesValue(Bytes)
    } derive(Eq,
    Debug
    )

    ValueBinding

    pub(all) struct ValueBinding {
    name : String
    value : Value
    } derive(Eq,
    Debug
    )

    ValueEntry

    pub(all) struct ValueEntry {
    key : Value
    value : Value
    } derive(Eq,
    Debug
    )

    ValueMember

    pub(all) struct ValueMember {
    name : String
    value : Value
    annotations : Array[Annotation]
    source : Expr?
    } derive(
    Debug
    )

    clear_sandbox_env_vars

    fn clear_sandbox_env_vars() -> Unit

    clear_sandbox_resource_readers

    fn clear_sandbox_resource_readers() -> Unit

    Drop all dynamic resource readers. Useful for embedded callers that share a sandbox across runs.

    codegen

    fn codegen(program : Program, target : CodegenTarget) -> String

    PKL-131b: single entry point for codegen, parametric over the target language. Returns the generated source as a String; embedders write it to disk / a stream as they see fit. Each target's lowering rules live in its own helper so the dispatcher stays a one-line match.

    configure_pklbinary_module_uri_normalizer

    fn configure_pklbinary_module_uri_normalizer(normalizer : (String) -> String) -> Unit

    configure_sandbox_allowed_modules

    fn configure_sandbox_allowed_modules(patterns : Array[String]) -> Unit

    Replace the configured allowed-modules pattern list. An empty list disables the allow-list (everything is permitted).

    configure_sandbox_env_vars

    fn configure_sandbox_env_vars(vars : Map[String, String]) -> Unit

    configure_sandbox_module_paths

    fn configure_sandbox_module_paths(dirs : Array[String]) -> Unit

    Replace the configured module-path search list. Directories are consulted in order when resolving an unqualified import.

    configure_sandbox_package_caches

    fn configure_sandbox_package_caches(dirs : Array[String]) -> Unit

    Replace the configured package-cache search list. See SandboxConfig.package_caches for the layout each directory must follow.

    configure_sandbox_props

    fn configure_sandbox_props(props : Map[String, String]) -> Unit

    Replace the configured props map. Pass an empty map to clear.

    configure_sandbox_resource_reader

    fn configure_sandbox_resource_reader(scheme : String, reader : (String) -> SandboxResource?) -> Unit

    Register a dynamic resource reader for scheme: URIs. The reader is invoked the first time read("<scheme>:<path>") misses the static read_resources map. Returning None falls back to the "Cannot find / refusing" diagnostic. Re-registering for the same scheme replaces the prior reader. Pass the bare scheme (no trailing colon) — configure_sandbox_resource_reader("cmd", fn) services read("cmd:ls") etc.

    configure_stdlib_base_paths

    fn configure_stdlib_base_paths(loader : () -> String?) -> Unit

    Register candidate filesystem paths for base.pkl. The first readable path is loaded lazily on the first sandbox_stdlib_base_source() call. Reads go through stdlib_base_loader so this module avoids a direct dependency on @fs.

    configure_stdlib_base_source

    fn configure_stdlib_base_source(source : String) -> Unit

    Eagerly register the base.pkl source text. Use this when the caller already holds the source in memory (tests, embedded callers). CLI callers should prefer configure_stdlib_base_paths so the file is only read on first reflect use.

    eval_source

    fn eval_source(source : String) -> EvalResult

    extract_output_value

    fn extract_output_value(value : Value) -> Value

    Resolve a top-level module value to what Apple Pkl actually renders.

    output is a hidden module property, so it never appears in rendered output. When the user sets output.value = <expr> (as pkspec's Test.pkl does via output { value = new Rendered { ... } }), that value — not the raw module body — is the render target. A bare output member (only renderer / other knobs, no value) is simply dropped.

    eval_source deliberately keeps the output member on the raw eval result (see PKL-104); render-boundary callers (the CLI / loader) apply this before handing a value to render_value_as_json & friends. Returns the value unchanged when it isn't a module-shaped ObjectValue carrying an output member.

    fdlibm_cos

    fn fdlibm_cos(x : Double) -> Double

    fdlibm_sin

    fn fdlibm_sin(x : Double) -> Double

    fdlibm_tan

    fn fdlibm_tan(x : Double) -> Double

    finalize_output_super_text_for_format

    fn finalize_output_super_text_for_format(value : Value, format : String) -> Value

    lint_program

    fn lint_program(program : Program) -> Array[LintFinding]

    Entry point: walk program once per rule and accumulate findings in source order so the CLI output is stable across runs.

    lookup_triple_dot_resolution

    fn lookup_triple_dot_resolution(from : String, uri : String) -> String?

    PKL-148r: look up a previously-registered triple-dot resolution. Returns the absolute path the CLI loaded the module under, or None if the CLI never saw this (from, uri) pair.

    parse_source

    fn parse_source(source : String) -> ParseResult

    register_import_glob

    fn register_import_glob(from : String, pattern : String, uris : Array[String]) -> Unit

    register_import_glob_errors

    fn register_import_glob_errors(from : String, pattern : String, errors : Map[String, String]) -> Unit

    register_module_alias

    fn register_module_alias(raw : String, resolved : String) -> Unit

    PKL-148bo: register a canonical alias from one URI form to another. Used for import "@dep/foo.pkl"package://...#/foo.pkl so the resolvedImports table sees the right shape even when callers ask for the raw form.

    register_module_imports

    fn register_module_imports(module_uri : String, import_uris : Array[String]) -> Unit

    PKL-148bo: record the resolved import edges for a single module. module_uri is the canonical file:///$snippetsDir/... or package://... URI of the module; import_uris is the (ordered) list of resolved URIs the module declares via import / import* / amends / extends. The list preserves source order because pkl:analyze.importGraph is order-sensitive in its rendering.

    register_read_glob

    fn register_read_glob(from : String, pattern : String, resources : Array[SandboxResource]) -> Unit

    register_read_resource

    fn register_read_resource(from : String, uri : String, visible_uri : String, resource_uri : String, text : String) -> Unit

    register_triple_dot_resolution

    fn register_triple_dot_resolution(from : String, uri : String, resolved : String) -> Unit

    PKL-148r: register a triple-dot import resolution. Called by the CLI loader after @fs.path_exists finds the matching ancestor candidate, so the analysis-layer resolver can map the same (from, uri) pair back to the same absolute path without re-doing FS access.

    render_module_as_pklbinary

    fn render_module_as_pklbinary(value : Value, module_name : String, module_uri : String) -> Bytes

    Render a module projection. Values reconstructed from output.value = module do not retain their hidden class marker, so restore it before writing the Pkl binary object envelope.

    render_type

    fn render_type(typ : Type) -> String

    render_value

    fn render_value(value : Value) -> String

    render_value_as_json

    fn render_value_as_json(value : Value) -> String

    render_value_as_json_document

    fn render_value_as_json_document(value : Value) -> String

    render_value_as_json_document_with_indent

    fn render_value_as_json_document_with_indent(value : Value, indent_text : String) -> String

    render_value_as_json_with_indent

    fn render_value_as_json_with_indent(value : Value, indent_text : String) -> String

    render_value_as_jsonnet

    fn render_value_as_jsonnet(value : Value) -> String

    render_value_as_jsonnet_document

    fn render_value_as_jsonnet_document(value : Value) -> String

    render_value_as_jsonnet_document_with_indent

    fn render_value_as_jsonnet_document_with_indent(value : Value, indent_text : String) -> String

    render_value_as_jsonnet_document_with_options

    fn render_value_as_jsonnet_document_with_options(value : Value, indent_text : String, omit_null_properties : Bool) -> String

    render_value_as_jsonnet_with_indent

    fn render_value_as_jsonnet_with_indent(value : Value, indent_text : String) -> String

    render_value_as_jsonnet_with_options

    fn render_value_as_jsonnet_with_options(value : Value, indent_text : String, omit_null_properties : Bool) -> String

    render_value_as_pcf_document

    fn render_value_as_pcf_document(value : Value) -> String

    render_value_as_pcf_document_with_indent

    fn render_value_as_pcf_document_with_indent(value : Value, indent_text : String) -> String

    render_value_as_pcf_document_with_options

    fn render_value_as_pcf_document_with_options(value : Value, indent_text : String, use_custom_string_delimiters : Bool) -> String

    render_value_as_pcf_fragment

    fn render_value_as_pcf_fragment(value : Value) -> String

    render_value_as_pcf_fragment_with_indent

    fn render_value_as_pcf_fragment_with_indent(value : Value, indent_text : String) -> String

    render_value_as_pcf_fragment_with_options

    fn render_value_as_pcf_fragment_with_options(value : Value, indent_text : String, use_custom_string_delimiters : Bool) -> String

    render_value_as_pklbinary_with_module

    fn render_value_as_pklbinary_with_module(value : Value, module_name : String, module_uri : String) -> Bytes

    Render a value using Pkl's MessagePack-based binary format while keeping user class and module metadata anchored to the containing module.

    render_value_as_plist

    fn render_value_as_plist(value : Value) -> String

    render_value_as_plist_fragment

    fn render_value_as_plist_fragment(value : Value) -> String

    render_value_as_properties

    fn render_value_as_properties(value : Value) -> String

    render_value_as_properties_fragment

    fn render_value_as_properties_fragment(value : Value) -> String

    render_value_as_protobuf_fragment

    fn render_value_as_protobuf_fragment(value : Value, indent_text : String) -> String

    render_value_as_textproto

    fn render_value_as_textproto(value : Value) -> String

    render_value_as_textproto_fragment

    fn render_value_as_textproto_fragment(value : Value, indent_text : String) -> String

    render_value_as_textproto_with_indent

    fn render_value_as_textproto_with_indent(value : Value, indent_text : String) -> String

    render_value_as_xml

    fn render_value_as_xml(value : Value) -> String

    render_value_as_xml_fragment

    fn render_value_as_xml_fragment(value : Value, indent_text : String) -> String

    render_value_as_xml_with_options

    fn render_value_as_xml_with_options(value : Value, root_element_name : String, indent_text : String, xml_version : String) -> String

    render_value_as_yaml

    fn render_value_as_yaml(value : Value) -> String

    render_value_as_yaml_fragment

    fn render_value_as_yaml_fragment(value : Value) -> String

    render_value_as_yaml_fragment_with_mode

    fn render_value_as_yaml_fragment_with_mode(value : Value, indent_width : Int, is_stream : Bool, mode : String) -> String

    render_value_as_yaml_fragment_with_options

    fn render_value_as_yaml_fragment_with_options(value : Value, indent_width : Int, is_stream : Bool) -> String

    render_value_as_yaml_stream

    fn render_value_as_yaml_stream(value : Value, indent_width : Int) -> String

    render_value_as_yaml_with_indent_width

    fn render_value_as_yaml_with_indent_width(value : Value, indent_width : Int) -> String

    render_value_as_yaml_with_mode

    fn render_value_as_yaml_with_mode(value : Value, indent_width : Int, is_stream : Bool, mode : String) -> String

    Mode-aware entry point used by the runtime renderer dispatch. External callers should prefer this when the YamlRenderer's mode slot matters; render_value_as_yaml_with_options keeps the historical default-"compat" behaviour intact.

    render_value_as_yaml_with_options

    fn render_value_as_yaml_with_options(value : Value, indent_width : Int, is_stream : Bool) -> String

    render_value_with_pcf_indent

    fn render_value_with_pcf_indent(value : Value, indent_text : String) -> String

    render_value_with_pcf_options

    fn render_value_with_pcf_options(value : Value, indent_text : String, use_custom_string_delimiters : Bool) -> String

    reset_sandbox_io_cache

    fn reset_sandbox_io_cache() -> Unit

    sandbox_all_module_uris

    fn sandbox_all_module_uris() -> Array[String]

    PKL-148bo: every module URI we've registered. The intrinsic uses this to break out of cycles cleanly.

    sandbox_is_module_allowed

    fn sandbox_is_module_allowed(uri : String) -> Bool

    True when uri is permitted by the current allow-list. An empty allow-list means "no restriction" so the default CLI behaviour is unchanged from before the slice. Each pattern is treated as a literal URI prefix — the format matches Apple Pkl's |-separated prefix lookup (e.g. pkl:|file:|https:).

    Bare filesystem paths (no scheme: prefix) bypass the allow-list because the check is intended for sandbox-relevant URIs that cross trust boundaries (https:, package:, the stdlib pkl:, etc.). The entrypoint and locally-rooted imports are already gated by filesystem permissions and the user typing the path on the command line, so re-checking them against the same allow-list would force users to spell out every directory.

    sandbox_module_alias

    fn sandbox_module_alias(raw : String) -> String?

    sandbox_module_imports

    fn sandbox_module_imports(module_uri : String) -> Array[String]?

    PKL-148bo: lookup helper used by the _pkl_analyze_import_graph intrinsic to walk a recorded module's adjacency list.

    sandbox_module_paths

    fn sandbox_module_paths() -> Array[String]

    Iterate the configured --module-path directories in CLI order. The loader prepends each directory to an unqualified import URI and tries the resulting path; the first hit wins. Returning the array directly keeps the loader free of an iterator wrapper.

    sandbox_package_caches

    fn sandbox_package_caches() -> Array[String]

    Iterate the configured --package-cache directories in CLI order.

    sandbox_stdlib_base_source

    fn sandbox_stdlib_base_source() -> String?

    typecheck_source

    fn typecheck_source(source : String) -> TypecheckResult