pkl

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

moonbit
pkl
parser
interpreter
typechecker
moon add mizchi/pkl@0.6.0
Download zip
Author
Version
0.6.0
License
Apache-2.0
Last updated
13 days ago
Downloads
444
README

#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 byte-matches all Apple Pkl 0.32.1 LanguageSnippetTests that ship reference output (416/416). The remaining 544 fixtures have no gold file; all 960 are still covered by the exclusion-free parser/diagnostic differential. The embedded standard-library type facade resolves all 324 public top-level declarations from the 23 public pkl: modules.

Known gaps for embedded callers:

  • CLI surface is partial. eval, test, format, and analyze exist, but multiple-module/stdin/output-path/expression flows and the upstream repl, server, project, download-package, run, and shell-completion commands are not implemented. Most upstream common CLI options are also absent.
  • Standard-library behavior is not complete. The 324/324 check proves import/type-name resolution, not method-level semantic parity. Several modules use deterministic stubs or partial implementations where Apple Pkl delegates to VM internals.
  • Property computation is memoized and demand-driven. Value carries self-contained property-thunk cells backed by a Pending / Evaluating / Resolved / Rejected state machine. Successful and failed right-hand sides in local/exported object bindings—including typed constructors—are evaluated at first access, with type/constraint checks and recursive-force detection memoized in the same cell. Settled cells release their computation closures, and separate analysis sessions do not share cell state. Lookup, output/rendering, converter, and amend consumers force the values they select; class defaults retain their separate declaration-scoped memo/materialization guard. eval_source remains an eager compatibility projection, while runtime-metadata consumers can call force_value explicitly.
  • 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.6.0. 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
)

#
EvalThunkCell

pub struct EvalThunkCell {
// private fields
}

Opaque runtime handle for a memoized property computation. Value is a public enum, so the payload type is public as well; its fields remain private and cells can only be created and forced by the evaluator API.
impl Eq for EvalThunkCell

#
EvalThunkState

pub enum EvalThunkState {
PendingThunk
EvaluatingThunk
ResolvedThunk(Value)
RejectedThunk(String)
}

Mutable state of one property thunk. The state transition is monotonic: Pending -> Evaluating -> Resolved/Rejected. Re-entering Evaluating is the structural cycle check; both successful values and failures are memoized.

#
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)
ThunkValue(EvalThunkCell)
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

#
force_value

fn force_value(value : Value) -> Value

Force one runtime value when it is a property thunk. Ordinary values are returned unchanged. eval_path already materializes its visible result; this API is for consumers of eval_path_with_runtime_metadata and for runtime integrations that inspect ValueMember.value directly.

#
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