starbox

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 20, 2026 License: MIT Imports: 22 Imported by: 4

README ΒΆ

πŸ₯‘ Starbox - Unboxing the Potential of Starlark

godoc codecov codacy codeclimate go report

Starbox is a pragmatic Go wrapper around the Starlark in Go project, making it easier to execute Starlark scripts, exchange data between Go and Starlark, and call functions across the Go-Starlark boundary. With a focus on simplicity and usability, Starbox aims to provide an enhanced experience for developers integrating Starlark scripting into their Go applications.

πŸš€ Key Features

A host of powerful features are provided to supercharge your Starlark scripting experience:

  • Streamlined Script Execution: Simplifies setting up and running Starlark scripts, offering a seamless interface for both script execution and interactive REPL sessions.
  • Efficient Data Interchange: Enables robust and smooth data exchange between Go and Starlark, enhancing the interoperability and simplifying the integration process.
  • Versatile Module Management: Extends Starlark's capabilities with a suite of built-in functions and the ability to load custom and override existing modules, covering functionalities from data processing to HTTP handling and file manipulation.
  • Cross-Language Function Calls: Leverage the power of both languages by calling Go functions from Starlark and vice versa, creating powerful integrations.
  • Integrated HTTP Context: Facilitates handling HTTP requests and responses within Starlark scripts, catering to web application development and server-side scripting.
  • Collective Memory Sharing: Introduces a shared memory concept, enabling data sharing across different script executions and instances, fostering a more connected and dynamic scripting environment.
  • Advanced Scripting Tools: Utilize features like REPL for interactive exploration and debugging, along with script caching for improved performance.

πŸ“¦ Installation

To include starbox in your Go project, use the following command:

go get github.com/1set/starbox

βš™οΈ Usage

Here's a quick example of how you can use Starbox:

import "github.com/1set/starbox"

// Define your box with global variables and modules
box := starbox.New("quick")
box.AddKeyValue("greet", func(name string) string {
    return fmt.Sprintf("Hello, %s!", name)
})
box.AddNamedModules("random")

// Run a Starlark script
script := starbox.HereDoc(`
    target = random.choice(["World", "Starlark", "Starbox"])
    text = greet(target)
    print("Starlark:", text)
    print(__modules__)
`)
res, err := box.Run(script)

// Check for errors and results
if err != nil {
    fmt.Println("Error executing script:", err)
    return
}
fmt.Println("Go:", res["text"].(string))

This may output:

[⭐|quick](15:50:27.677) Starlark: Hello, Starbox!
[⭐|quick](15:50:27.677) ["random"]
Go: Hello, Starbox!

πŸ”’ Security Model & Capability Gating

Starbox is a host runtime: the Go host decides what an untrusted script may reach, and the script cannot widen that grant. The control surface has two distinct layers β€” Starbox implements the first; the second lives at the layer that constructs the modules.

Load gate β€” which modules a script may load()

New selects modules through a four-tier module set (EmptyModuleSet, SafeModuleSet, NetworkModuleSet, FullModuleSet); SafeModuleSet is an explicit, hand-curated allowlist that can reach neither the network nor the filesystem.

For stricter, host-declared control, construct the box with a Policy β€” a Go-side, default-deny allowlist the script can neither read nor mutate:

// Only "math" and "json" are loadable, no matter what the module set requests.
box := starbox.NewWithPolicy("sandboxed", starbox.Policy{
    Modules: starbox.ModuleAllow{Names: []string{"math", "json"}},
})
box.SetModuleSet(starbox.FullModuleSet) // requested set is INTERSECTED with the policy
  • The zero Policy{} permits nothing β€” strict default-deny by construction.
  • ModuleAllow.Capabilities is opt-in capability widening: a non-zero tier (e.g. starlet.CapNetwork) permits every builtin whose capability set is a subset of it.
  • The gate covers every named-module path a script can load: builtin, custom (AddModule*), dynamic, and script modules (AddModuleScript, matched by their registered .star name).
  • A withheld builtin surfaces a typed ModuleWithheldError (matchable via errors.As). A policy-denied non-builtin (custom/dynamic/script) module is simply absent β€” load() fails as "not found", so the sandbox is not told a host-private module exists but is forbidden.

SetFS is an explicit exception. A host-mounted fs.FS is a raw filesystem grant with no module-name registry to match against, so it is not governed by the load gate. Under a restrictive policy, curate the mounted filesystem (or do not call SetFS).

Exec gate β€” what a loaded module may do β€” is NOT in Starbox

Per-call filesystem / network / command / secret gating (what a loaded module is allowed to actually do) is out of scope for Starbox: it never imports the domain modules, which arrive as opaque loaders, so exec-gating belongs where those loaders are constructed (the host shell / CLI). Starbox ships the load gate only; it does not ship inert exec-grant fields that would be a fail-open footgun.

πŸ“ Execution Budgets & Output Limits

box.SetMaxExecutionSteps(1_000_000) // bound runaway loops a wall-clock timeout cannot stop
box.SetMaxOutputEntries(100)        // cap the number of top-level result entries

A run that exceeds the step budget fails with a starlet.MaxStepsExceededError; one that produces too many result entries is withheld with an OutputLimitExceededError. Both are reachable via errors.As, and both are enforced on every run path (Run, RunFile, RunTimeout, RunInspect*, and the RunnerConfig.Execute() builder).

πŸ”Ž Inspection without Execution

Learn what a script would see, and catch problems, without running it:

diags, _ := box.Check(script)            // []Diagnostic: syntax + resolve errors as "file:line:col: msg"
surface, _ := box.DescribeSurface()      // Surface: modules (name/origin/members) + globals (name/type)

Both honor the active Policy β€” they report and accept exactly the modules a real Run would load, never a wider surface.

πŸ“€ Structured Results & Console Capture

box.AddResultBuiltin("output")           // script calls output(v) once per run to set its result
res, _ := box.Run(`output({"ok": True})`)
val, ok := box.GetResult()               // the captured value; reset at the start of every run

con := box.EnableConsoleCapture()        // funnel console output into a drainable buffer instead of stderr
box.Run(`print("hi")`)
for _, e := range con.Drain() {          // []ConsoleEntry: Time, Level, Message, structured Fields
    fmt.Println(e.Level, e.Message, e.Fields)
}

print() becomes a LevelPrint entry; when the log module is loaded, log.* calls become leveled entries whose keyword arguments are preserved as structured Fields (never pre-rendered into the message). Drain returns the buffered entries and clears them, for a per-run drain.

🧩 Typed Errors

Run failures carry typed, errors.As-matchable causes, and ClassifyRunError maps any run failure to a RunError{Kind} (Syntax, Compile, ModuleWithheld, MaxSteps, OutputLimit, Eval) for uniform host handling.

πŸ‘₯ Contributing

We welcome contributions to the Starbox project. If you encounter any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request. Before undertaking any significant changes, please let us know by filing an issue or claiming an existing one to ensure there is no duplication of effort.

πŸ“œ License

Starbox is licensed under the MIT License.

πŸ™Œ Credits

This project is inspired by and builds upon several open-source projects:

  • Starlark in Go: The official Starlark interpreter in Go, created by Google.
  • Starlight: A well-known Go wrapper and data conversion tool between Go and Starlark.
  • Starlight Enhanced: A sophisticated fork of the original Starlight, with bug fixes and enhancement features.
  • Starlib: A collection of third-party libraries for Starlark.
  • Starlet: A Go wrapper that simplifies usage, offers data conversion, libraries and extensions for Starlark.

We thank the authors and contributors of these projects for their excellent works πŸŽ‰

Documentation ΒΆ

Overview ΒΆ

Package starbox provides a comprehensive set of utilities for building and managing Starlark virtual machines with ease.

Module Sources ΒΆ

Starbox supports loading modules from various sources, including built-in modules from Starlet, custom modules added by the user, and dynamic modules resolved by name on demand.

Built-in Modules:

Use SetModuleSet(modSet ModuleSetName) to select a predefined set of modules from Starlet to preload before execution. Available sets include:

  • EmptyModuleSet: No modules.
  • SafeModuleSet: Safe modules without access to the file system or network.
  • NetworkModuleSet: Safe modules plus network modules.
  • FullModuleSet: All available modules.

Custom Modules:

  • AddModuleLoader(moduleName string, moduleLoader starlet.ModuleLoader): Adds a custom module loader. Members can be accessed in the script via load("module_name", "member_name") or member_name.
  • AddModuleFunctions(name string, funcs FuncMap): Adds a module of custom functions. Functions can be accessed in the script via load("module_name", "func_name") or module_name.func_name.
  • AddModuleData(moduleName string, moduleData starlark.StringDict): Adds a module of custom data. Data can be accessed in the script via load("module_name", "key") or module_name.key.
  • AddStructFunctions(name string, funcs FuncMap): Adds a struct of custom functions. Functions can be accessed in the script via load("struct_name", "func_name") or struct_name.func_name.
  • AddStructData(structName string, structData starlark.StringDict): Adds a struct of custom data. Data can be accessed in the script via load("struct_name", "key") or struct_name.key.

Dynamic Modules:

  • SetDynamicModuleLoader(loader DynamicModuleLoader): Sets a dynamic module loader function, which returns module loaders based on their names before execution. These module names should be defined using AddNamedModules or AddModulesByName.

Module Loading Priority ΒΆ

Modules are loaded in the following order of priority before execution:

  1. Preloaded Starlet modules from predefined sets and additional Starlet modules by name.
  2. Custom modules added by users, preloaded Starlet modules with the same names would not be overwritten.
  3. Dynamically loaded modules based on their names just before execution.
  4. If a module name is not found in any of the built-in, custom, or dynamic modules, an error is returned.

Index ΒΆ

Constants ΒΆ

View Source
const LevelPrint = "print"

LevelPrint is the Level of a ConsoleEntry produced by a print() call (the log.* entries carry their zap level name: "debug", "info", "warn", "error").

Variables ΒΆ

View Source
var (
	// HereDoc returns unindented string as here-document.
	HereDoc = here.Doc
	// HereDocf returns formatted unindented string as here-document.
	HereDocf = here.Docf
)
View Source
var (
	// ErrModuleNotFound is the error for module cannot be found by name.
	ErrModuleNotFound = errors.New("module not found")
)
View Source
var (
	// ErrNoStarbox is the error for RunnerConfig.Execute() when no Starbox instance is set
	ErrNoStarbox = errors.New("no starbox instance")
)

Functions ΒΆ

func NewMemory ΒΆ

func NewMemory() *dataconv.SharedDict

NewMemory creates a new shared dictionary for la mΓ©moire collective.

func SetLog ΒΆ

func SetLog(l *zap.SugaredLogger)

SetLog sets the logger from outside the package.

Types ΒΆ

type Console ΒΆ added in v0.2.0

type Console struct {
	// contains filtered or unexported fields
}

Console buffers console output captured during runs when a Box has console capture enabled (see Starbox.EnableConsoleCapture). It is safe for concurrent use: a run appends to it under lock while the caller drains it from another goroutine.

func (*Console) Drain ΒΆ added in v0.2.0

func (c *Console) Drain() []ConsoleEntry

Drain returns the buffered entries and clears the buffer, so the next run starts empty - the per-run drain pattern. It returns nil when nothing was captured.

func (*Console) Len ΒΆ added in v0.2.0

func (c *Console) Len() int

Len reports how many entries are currently buffered (not yet drained).

type ConsoleEntry ΒΆ added in v0.2.0

type ConsoleEntry struct {
	// Time is when the entry was captured.
	Time time.Time
	// Level is LevelPrint for print(), or the zap level name for a log.* call.
	Level string
	// Message is the message text. A log.* call's positional arguments are
	// folded into it exactly as the log module renders them; its keyword
	// arguments are kept structured in Fields instead.
	Message string
	// Fields holds a log.* call's keyword arguments verbatim; nil for print().
	Fields []ConsoleField
}

ConsoleEntry is a single piece of console output captured during a run: a print() call or a log.<level>() call from the script.

type ConsoleField ΒΆ added in v0.2.0

type ConsoleField struct {
	Key   string
	Value interface{}
}

ConsoleField is one structured key/value attached to a captured log entry. The value is the raw Go value the script passed, never pre-rendered into a string - the caller decides how to format it.

type Diagnostic ΒΆ added in v0.2.0

type Diagnostic struct {
	File string // source filename the problem is in (e.g. "box.star")
	Line int    // 1-based line
	Col  int    // 1-based column
	Msg  string // human-readable description
}

Diagnostic is one problem Check found in a script - a syntax error or a resolve error (e.g. an undefined name) - with its 1-based source position.

func (Diagnostic) String ΒΆ added in v0.2.0

func (d Diagnostic) String() string

String renders the diagnostic in the conventional compiler format "file:line:col: message" (the file is omitted when unknown).

type DoNotCompare ΒΆ added in v0.1.2

type DoNotCompare [0]func()

DoNotCompare prevents == and != comparisons on the containing struct.

type DynamicModuleLoader ΒΆ added in v0.1.2

type DynamicModuleLoader func(string) (starlet.ModuleLoader, error)

DynamicModuleLoader is a function type that takes a module name as input and returns a corresponding module loader. It is invoked before execution to dynamically load modules as needed, and serves as a complement to Starlet's built-in modules and custom-added modules. For given module names, if the module is not a built-in module or a custom-added module, this function is called to look it up. If the module is not found or fails to initialize, an error is returned. For non-existent modules, it should return (nil, nil) or (nil, error).

type FuncMap ΒΆ

type FuncMap map[string]StarlarkFunc

FuncMap is a map of Starlark functions.

type GlobalSurface ΒΆ added in v0.2.0

type GlobalSurface struct {
	// Name is the binding's name in the script namespace.
	Name string
	// Type is its Starlark type (e.g. "string", "builtin_function_or_method"),
	// or the Go type for a host value that has not been converted yet.
	Type string
}

GlobalSurface describes one global value injected into a Box.

type InspectCondFunc ΒΆ

type InspectCondFunc func(starlet.StringAnyMap, error) bool

InspectCondFunc is a function type for inspecting the converted output of Run*() and decide whether to continue.

type ModuleAllow ΒΆ added in v0.2.0

type ModuleAllow struct {
	// Names are module names permitted verbatim (builtin or custom/dynamic).
	Names []string
	// Capabilities is OPT-IN capability widening: a non-zero tier permits every
	// builtin whose capability bits are a subset of it (e.g. CapNetwork permits
	// pure + network builtins). The zero value (CapPure) does NOT widen β€” an
	// exact pure allowlist is expressed via Names or a module set.
	Capabilities starlet.ModuleCapability
}

ModuleAllow is an explicit load-gate allowlist (never a denylist subtraction β€” that was BOX-05). A module name is permitted iff it is listed in Names OR it is a builtin whose capability set is a subset of Capabilities. The effective loadable set is whatever the Box requests (module set + AddNamedModules + custom/dynamic) INTERSECTED with what this allows β€” the policy only tightens.

The zero ModuleAllow (nil Names, Capabilities = CapPure = 0) permits NOTHING β€” strict default-deny by construction.

type ModuleOrigin ΒΆ added in v0.2.0

type ModuleOrigin string

ModuleOrigin identifies where a module in a Box's Surface comes from.

const (
	// OriginBuiltin is a Starlet builtin module (from a module set or AddNamedModules).
	OriginBuiltin ModuleOrigin = "builtin"
	// OriginCustom is a module added via AddModuleLoader/AddModule{Functions,Data}/AddStruct{Functions,Data}.
	OriginCustom ModuleOrigin = "custom"
	// OriginScript is a *.star module added via AddModuleScript.
	OriginScript ModuleOrigin = "script"
	// OriginDynamic is a module resolved on demand by a DynamicModuleLoader.
	OriginDynamic ModuleOrigin = "dynamic"
)

type ModuleSetName ΒΆ

type ModuleSetName string

ModuleSetName defines the name of a module set.

When a script load()s a module that exists in Starlet but is not part of the active set, the run fails with a ModuleWithheldError (reachable via errors.As) - distinct from load()ing a non-existent module (a "not found" error) and from referencing an undefined name (a resolve error).

const (
	// EmptyModuleSet represents the predefined module set for empty scripts, it contains no modules.
	EmptyModuleSet ModuleSetName = "none"
	// SafeModuleSet represents the predefined module set for safe scripts, it contains only safe modules that do not have side effects with outside world.
	SafeModuleSet ModuleSetName = "safe"
	// NetworkModuleSet represents the predefined module set for network scripts, it's based on SafeModuleSet with additional network modules.
	NetworkModuleSet ModuleSetName = "network"
	// FullModuleSet represents the predefined module set for full scripts, it includes all available modules.
	FullModuleSet ModuleSetName = "full"
)

type ModuleSurface ΒΆ added in v0.2.0

type ModuleSurface struct {
	// Name is the name used in load("name", ...) or as a global.
	Name string
	// Origin says where the module comes from.
	Origin ModuleOrigin
	// Members are the exported member names, sorted. It is nil (not empty) when
	// the members cannot be enumerated without running host code or the script:
	// an opaque AddModuleLoader func, a script (.star) module, or a dynamic one.
	Members []string
}

ModuleSurface describes one module a Box exposes to scripts.

type ModuleWithheldError ΒΆ added in v0.2.0

type ModuleWithheldError = starlet.ModuleWithheldError

ModuleWithheldError reports that a script load()ed a module that exists in Starlet but is not part of the Box's active module set. It is re-exported from Starlet (the same type Starlet returns) so callers can match it via errors.As without importing starlet directly. This is distinct from ErrModuleNotFound, which marks a module that does not exist at all.

Policy interaction (contract): a withheld error is surfaced for a known builtin that the active module set or the Policy excludes. A NON-builtin module (custom, dynamic, or script) that the Policy denies is simply not registered, so load()ing it fails as "not found" rather than as a withheld error - the sandbox is deliberately not told that a host-private module exists but is forbidden.

type OutputLimitExceededError ΒΆ added in v0.2.0

type OutputLimitExceededError struct {
	Limit uint // the configured maximum number of result entries
	Count uint // the number of result entries the run actually produced
}

OutputLimitExceededError marks a run whose result exceeded the configured output-entry limit (SetMaxOutputEntries). It is reachable via errors.As and is one of the typed run errors STAR-8's RunError taxonomy will classify.

func (OutputLimitExceededError) Error ΒΆ added in v0.2.0

func (e OutputLimitExceededError) Error() string

Error returns the error message.

type Policy ΒΆ added in v0.2.0

type Policy struct {
	// Modules is the load gate: which module names a script may load.
	Modules ModuleAllow
}

Policy is the host-side, default-deny capability grant for a Box. It is declared in Go (never in Starlark), cannot be read or mutated by the sandboxed script, and is applied as an ADDITIVE opt-in via NewWithPolicy β€” a Box created with New (no policy) is unaffected.

A4 scope note: this carries only the LOAD gate (which modules a script may load). The exec gate (what a loaded module may DO: fs/net/cmd/secret) is NOT here β€” starbox cannot reach starpkg modules' construction-time knobs (it never imports starpkg; they arrive as opaque loaders), so exec-gating lives where the loaders are constructed (the host shell / starcli). Shipping inert fs/net grant fields here would be a fail-open footgun, so they are omitted.

The load gate covers every named-module path a script can load(): builtin modules, custom modules (AddModule*), dynamic modules, and script modules (AddModuleScript, matched by their registered ".star" name). It does NOT gate SetFS: a host-mounted fs.FS is a raw, deliberate filesystem grant with no module-name registry to match against, so a default-deny Box that also calls SetFS exposes whatever that filesystem contains. Curate the mounted FS (or do not call SetFS) when running under a restrictive policy.

type RunError ΒΆ added in v0.2.0

type RunError struct {
	Kind RunErrorKind
	Err  error // the underlying error
}

RunError classifies a failed run by Kind while preserving the original error chain: errors.As / errors.Is against the underlying typed errors (ModuleWithheldError, starlet.MaxStepsExceededError, OutputLimitExceededError, *starlark.EvalError, …) keep working through it via Unwrap.

func ClassifyRunError ΒΆ added in v0.2.0

func ClassifyRunError(err error) *RunError

ClassifyRunError wraps a Run/Call error in a *RunError tagged with its Kind, classifying by the most specific typed error first (a withheld-module or budget error also presents as a Starlark eval error, so those are matched before RunErrorEval). It returns nil for a nil error and preserves the original error via Unwrap, so callers can both switch on Kind and errors.As to the specific typed error for details.

func (*RunError) Error ΒΆ added in v0.2.0

func (e *RunError) Error() string

Error implements error.

func (*RunError) Unwrap ΒΆ added in v0.2.0

func (e *RunError) Unwrap() error

Unwrap returns the underlying error so the original chain stays reachable (errors.As / errors.Is pass through a *RunError unchanged).

type RunErrorKind ΒΆ added in v0.2.0

type RunErrorKind int

RunErrorKind classifies why a Run/Call failed. The zero value RunErrorUnknown is intentional and fail-loud: an unrecognised error is never silently treated as a known kind.

const (
	// RunErrorUnknown is an error that could not be classified.
	RunErrorUnknown RunErrorKind = iota
	// RunErrorSyntax is a parse failure (the script is not valid Starlark).
	RunErrorSyntax
	// RunErrorCompile is a resolve failure: an undefined name, a bad load
	// binding, and similar pre-execution problems.
	RunErrorCompile
	// RunErrorModuleWithheld is load() of a real module the active set withholds.
	RunErrorModuleWithheld
	// RunErrorMaxSteps is the execution step budget being exceeded.
	RunErrorMaxSteps
	// RunErrorOutputLimit is the result exceeding the configured output limit.
	RunErrorOutputLimit
	// RunErrorEval is a runtime evaluation error (the script raised or failed
	// while executing).
	RunErrorEval
)

func (RunErrorKind) String ΒΆ added in v0.2.0

func (k RunErrorKind) String() string

String returns a short, stable name for the kind.

type RunnerConfig ΒΆ

type RunnerConfig struct {
	// contains filtered or unexported fields
}

RunnerConfig defines the execution configuration for a Starbox instance.

func NewRunConfig ΒΆ

func NewRunConfig() *RunnerConfig

NewRunConfig creates a new RunnerConfig instance.

func (*RunnerConfig) Clone ΒΆ added in v0.1.1

func (c *RunnerConfig) Clone() *RunnerConfig

Clone creates a new RunnerConfig instance from the current one.

func (*RunnerConfig) Context ΒΆ

func (c *RunnerConfig) Context(ctx context.Context) *RunnerConfig

Context sets the context for the execution.

func (*RunnerConfig) Execute ΒΆ

func (c *RunnerConfig) Execute() (starlet.StringAnyMap, error)

Execute executes the box with the given configuration.

func (*RunnerConfig) FileName ΒΆ

func (c *RunnerConfig) FileName(name string) *RunnerConfig

FileName sets the script file name for the execution.

func (*RunnerConfig) Inspect ΒΆ

func (c *RunnerConfig) Inspect(force bool) *RunnerConfig

Inspect sets the inspection mode for the execution. It works like InspectCond with a condition function that forces the REPL mode, by adding a condition function to force the REPL mode, regardless of the output or error. It can be overridden by InspectCond() or Inspect().

func (*RunnerConfig) InspectCond ΒΆ

func (c *RunnerConfig) InspectCond(cond InspectCondFunc) *RunnerConfig

InspectCond sets the inspection mode with a condition function for the execution. It can be overridden by InspectCond() or Inspect().

func (*RunnerConfig) KeyValue ΒΆ

func (c *RunnerConfig) KeyValue(key string, value interface{}) *RunnerConfig

KeyValue sets the key-value pair for the execution.

func (*RunnerConfig) KeyValueMap ΒΆ

func (c *RunnerConfig) KeyValueMap(extras starlet.StringAnyMap) *RunnerConfig

KeyValueMap merges the key-value pairs for the execution.

func (*RunnerConfig) Script ΒΆ

func (c *RunnerConfig) Script(content string) *RunnerConfig

Script sets the script content for the execution.

func (*RunnerConfig) Starbox ΒΆ

func (c *RunnerConfig) Starbox(b *Starbox) *RunnerConfig

Starbox sets the Starbox instance for the execution.

func (*RunnerConfig) String ΒΆ

func (c *RunnerConfig) String() string

String returns a string representation of the RunnerConfig.

func (*RunnerConfig) Timeout ΒΆ

func (c *RunnerConfig) Timeout(timeout time.Duration) *RunnerConfig

Timeout sets the timeout for the execution.

type Starbox ΒΆ

type Starbox struct {
	// contains filtered or unexported fields
}

Starbox is a wrapper of starlet.Machine with additional features.

func New ΒΆ

func New(name string) *Starbox

New creates a new Starbox instance with default settings.

func NewWithPolicy ΒΆ added in v0.2.0

func NewWithPolicy(name string, p Policy) *Starbox

NewWithPolicy creates a Starbox whose loadable modules are constrained by a host-side, default-deny Policy (the A4 load gate). The policy is deep-copied in (the caller cannot mutate grants afterwards) and only ever TIGHTENS what SetModuleSet/AddNamedModules/custom/dynamic modules would otherwise load β€” a module loads iff it is both requested AND permitted by the policy. Modules the policy withholds raise a ModuleWithheldError (for builtins) or are simply absent (custom/dynamic). New (no policy) behaviour is unchanged.

func (*Starbox) AddBuiltin ΒΆ

func (s *Starbox) AddBuiltin(name string, starFunc StarlarkFunc)

AddBuiltin adds a builtin function with name to the global environment before execution. If the name already exists, it will be overwritten. It panics if called after execution.

func (*Starbox) AddHTTPContext ΒΆ

func (s *Starbox) AddHTTPContext(req *http.Request) *libhttp.ServerResponse

AddHTTPContext adds HTTP request and response data wrapper to the global environment before execution. It takes an HTTP request and returns the response data wrapper for setting response headers and body. It panics if called after execution.

func (*Starbox) AddKeyStarlarkValue ΒΆ

func (s *Starbox) AddKeyStarlarkValue(key string, value starlark.Value)

AddKeyStarlarkValue adds a key-value pair to the global environment before execution, the value is a Starlark value. If the key already exists, it will be overwritten. It panics if called after execution.

func (*Starbox) AddKeyValue ΒΆ

func (s *Starbox) AddKeyValue(key string, value interface{})

AddKeyValue adds a key-value pair to the global environment before execution. If the key already exists, it will be overwritten. It panics if called after execution.

func (*Starbox) AddKeyValues ΒΆ

func (s *Starbox) AddKeyValues(keyValues starlet.StringAnyMap)

AddKeyValues adds key-value pairs to the global environment before execution. Usually for output of Run()*. For each key-value pair, if the key already exists, it will be overwritten. It panics if called after execution.

func (*Starbox) AddModuleData ΒΆ

func (s *Starbox) AddModuleData(moduleName string, moduleData starlark.StringDict)

AddModuleData creates a module for the given module data along with a module loader, and adds it to the preload and lazyload registry. The given module data can be accessed in script via load("module_name", "key1") or module_name.key1. It panics if called after execution.

func (*Starbox) AddModuleFunctions ΒΆ

func (s *Starbox) AddModuleFunctions(name string, funcs FuncMap)

AddModuleFunctions adds a module with the given module functions along with a module loader, and adds it to the preload and lazyload registry. The given module function can be accessed in script via load("module_name", "func1") or module_name.func1. It works like AddModuleData() but allows only functions as values. It panics if called after execution.

func (*Starbox) AddModuleLoader ΒΆ

func (s *Starbox) AddModuleLoader(moduleName string, moduleLoader starlet.ModuleLoader)

AddModuleLoader adds a custom module loader to the preload and lazyload registry. It will not load the module until the first run, and load result can be accessed in script via load("module_name", "key1") or key1 directly. It panics if called after execution.

func (*Starbox) AddModuleScript ΒΆ

func (s *Starbox) AddModuleScript(moduleName, moduleScript string)

AddModuleScript creates a module with given module script in virtual filesystem, and adds it to the preload and lazyload registry. The given module script can be accessed in script via load("module_name", "key1") or load("module_name.star", "key1") if module name has no ".star" suffix. All the module scripts added by this method would be overridden by SetFS() if it's not nil. It panics if called after execution.

func (*Starbox) AddModulesByName ΒΆ added in v0.1.2

func (s *Starbox) AddModulesByName(moduleNames ...string)

AddModulesByName is an alias of AddNamedModules().

func (*Starbox) AddNamedModules ΒΆ

func (s *Starbox) AddNamedModules(moduleNames ...string)

AddNamedModules adds builtin and custom modules by name to the preload and lazyload registry. It will not load the modules until the first run. It panics if called after execution.

func (*Starbox) AddResultBuiltin ΒΆ added in v0.2.0

func (s *Starbox) AddResultBuiltin(name string)

AddResultBuiltin registers a builtin with the given name (e.g. "output") that a script calls once to set its single structured result. A second call within a run is an error, so a script cannot ambiguously "return" twice. Retrieve the captured value after a run with GetResult.

It panics (DPanic) if called after execution.

func (*Starbox) AddStarlarkValues ΒΆ

func (s *Starbox) AddStarlarkValues(keyValues starlark.StringDict)

AddStarlarkValues adds key-value pairs to the global environment before execution, the values are already converted to Starlark values. For each key-value pair, if the key already exists, it will be overwritten. It panics if called after execution.

func (*Starbox) AddStructData ΒΆ

func (s *Starbox) AddStructData(structName string, structData starlark.StringDict)

AddStructData creates a module for the given struct data along with a module loader, and adds it to the preload and lazyload registry. The given struct data can be accessed in script via load("struct_name", "key1") or struct_name.key1. It panics if called after execution.

func (*Starbox) AddStructFunctions ΒΆ

func (s *Starbox) AddStructFunctions(name string, funcs FuncMap)

AddStructFunctions adds a module with the given struct functions along with a module loader, and adds it to the preload and lazyload registry. The given struct function can be accessed in script via load("struct_name", "func1") or struct_name.func1. It works like AddStructData() but allows only functions as values. It panics if called after execution.

func (*Starbox) AttachMemory ΒΆ

func (s *Starbox) AttachMemory(name string, memory *dataconv.SharedDict)

AttachMemory adds a shared dictionary to the global environment before execution.

func (*Starbox) CallStarlarkFunc ΒΆ added in v0.1.1

func (s *Starbox) CallStarlarkFunc(name string, args ...interface{}) (interface{}, error)

CallStarlarkFunc executes a function defined in Starlark with arguments and returns the converted output.

func (*Starbox) Check ΒΆ added in v0.2.0

func (s *Starbox) Check(script string) ([]Diagnostic, error)

Check parses and resolves a script against the Box's configured environment WITHOUT executing it, returning the problems found (syntax errors, undefined names). A nil result means the script compiles cleanly against this Box.

Check is side-effect free: it inspects only the configured names and the known-pure builtin module loaders to learn which globals exist; it never runs the script and never invokes an opaque (AddModuleLoader) custom loader. It catches resolve-time problems only - load() of a missing or withheld module is a run-time concern (see the R7 withheld-module work), not a resolve error.

func (*Starbox) Console ΒΆ added in v0.2.0

func (s *Starbox) Console() *Console

Console returns the capture buffer set up by EnableConsoleCapture, or nil if console capture was never enabled on this Box.

func (*Starbox) CreateMemory ΒΆ

func (s *Starbox) CreateMemory(name string) *dataconv.SharedDict

CreateMemory creates a new shared dictionary for la mΓ©moire collective with the given name, and adds it to the global environment before execution.

func (*Starbox) CreateRunConfig ΒΆ

func (s *Starbox) CreateRunConfig() *RunnerConfig

CreateRunConfig creates a new RunnerConfig instance from a given Starbox instance.

func (*Starbox) DescribeSurface ΒΆ added in v0.2.0

func (s *Starbox) DescribeSurface() (Surface, error)

DescribeSurface enumerates the configured surface of the Box without running a script (and without requiring a prior run). See Surface for the contract.

func (*Starbox) EnableConsoleCapture ΒΆ added in v0.2.0

func (s *Starbox) EnableConsoleCapture() *Console

EnableConsoleCapture routes the script's console output into an in-memory, drainable Console instead of stderr: print() becomes a LevelPrint entry, and the log module's calls (when log is loaded) become leveled entries with their keyword arguments preserved as structured Fields. It returns the Console; call Console.Drain after each run to collect that run's output.

It replaces both the print function and the log module's logger, so it takes precedence over SetPrintFunc and SetLogger - enable capture last, or do not mix them. It panics if called after execution.

func (*Starbox) GetMachine ΒΆ

func (s *Starbox) GetMachine() *starlet.Machine

GetMachine returns the underlying starlet.Machine instance.

func (*Starbox) GetModuleNames ΒΆ

func (s *Starbox) GetModuleNames() []string

GetModuleNames returns the names of the modules loaded after execution.

func (*Starbox) GetResult ΒΆ added in v0.2.0

func (s *Starbox) GetResult() (starlark.Value, bool)

GetResult returns the value captured by the result builtin and whether it was set during a run. The value is the raw Starlark value the script passed.

func (*Starbox) GetSteps ΒΆ

func (s *Starbox) GetSteps() uint64

GetSteps returns the computation steps executed by the underlying Starlark thread.

func (*Starbox) REPL ΒΆ

func (s *Starbox) REPL() error

REPL starts a REPL session.

func (*Starbox) Reset ΒΆ

func (s *Starbox) Reset()

Reset replaces the underlying Starlet machine with a fresh one while keeping the Box's configuration (name, globals, module set, script modules, policy, limits, ...), so the same Box can be run again from a clean per-run state.

Reset is for SERIAL reuse of a single Box. There is deliberately no Clone and no Box pool: per-run state (globals injected during a run, the Starlark step counter) lives on the machine, so sharing or hand-pooling a Box would leak that state between runs. For a hot path or concurrent workload, construct a fresh New(...) per run and share only the compiled-program cache across them via SetScriptCache - that keeps compilation shared while keeping per-run state isolated.

func (*Starbox) Run ΒΆ

func (s *Starbox) Run(script string) (starlet.StringAnyMap, error)

Run executes a script and returns the converted output.

func (*Starbox) RunFile ΒΆ added in v0.1.2

func (s *Starbox) RunFile(file string) (starlet.StringAnyMap, error)

RunFile executes a script file and returns the converted output.

func (*Starbox) RunInspect ΒΆ

func (s *Starbox) RunInspect(script string) (starlet.StringAnyMap, error)

RunInspect executes a script and then REPL with result and returns the converted output.

func (*Starbox) RunInspectIf ΒΆ

func (s *Starbox) RunInspectIf(script string, cond InspectCondFunc) (starlet.StringAnyMap, error)

RunInspectIf executes a script and then REPL with result and returns the converted output, if the condition is met. The condition function is called with the converted output and the error from Run*(), and returns true if REPL is needed.

func (*Starbox) RunTimeout ΒΆ

func (s *Starbox) RunTimeout(script string, timeout time.Duration) (starlet.StringAnyMap, error)

RunTimeout executes a script and returns the converted output.

func (*Starbox) SetDynamicModuleLoader ΒΆ added in v0.1.2

func (s *Starbox) SetDynamicModuleLoader(loader DynamicModuleLoader)

SetDynamicModuleLoader sets the dynamic module loader for preload and lazyload modules. It panics if called after execution.

func (*Starbox) SetFS ΒΆ

func (s *Starbox) SetFS(hfs fs.FS)

SetFS sets the virtual filesystem for module scripts. If it's not nil, it'll override all the scripts added by AddModuleScript(). It panics if called after execution.

func (*Starbox) SetLogger ΒΆ added in v0.1.2

func (s *Starbox) SetLogger(sl *zap.SugaredLogger)

SetLogger sets the logger for user-defined log output.

func (*Starbox) SetMaxExecutionSteps ΒΆ added in v0.2.0

func (s *Starbox) SetMaxExecutionSteps(steps uint64)

SetMaxExecutionSteps sets the per-run budget of Starlark computation steps; 0 (the default) means unlimited. When a run exceeds the budget, Run/Call fail with a starlet.MaxStepsExceededError reachable via errors.As β€” the standard guard against a runaway loop that a wall-clock timeout cannot stop. The step counter resets at the start of every run. It panics if called after execution.

func (*Starbox) SetMaxOutputEntries ΒΆ added in v0.2.0

func (s *Starbox) SetMaxOutputEntries(n uint)

SetMaxOutputEntries sets the maximum number of top-level entries a run's result may contain; 0 (the default) means unlimited. A run that produces more is aborted with an OutputLimitExceededError (reachable via errors.As) and its result is withheld. This is a post-hoc policy gate on result size, not a memory guard - use SetMaxExecutionSteps to bound resource use. It panics if called after execution.

func (*Starbox) SetModuleSet ΒΆ

func (s *Starbox) SetModuleSet(modSet ModuleSetName)

SetModuleSet sets the module set to be loaded before execution. It panics if called after execution.

func (*Starbox) SetPrintFunc ΒΆ

func (s *Starbox) SetPrintFunc(printFunc starlet.PrintFunc)

SetPrintFunc sets the print function for Starlark. It panics if called after execution.

func (*Starbox) SetScriptCache ΒΆ added in v0.1.2

func (s *Starbox) SetScriptCache(cache starlet.ByteCache)

SetScriptCache sets a custom cache provider for compiled script content; a nil provider disables the script cache. It panics if called after execution.

Hot-path / concurrency recommendation: a single starlet.MemoryCache (NewMemoryCache, which is safe for concurrent use) shared across many per-run New(...) boxes lets each distinct script compile once and be reused, while every Box keeps its own isolated per-run state. Prefer this over reusing or pooling a single Box (see Reset).

func (*Starbox) SetStructTag ΒΆ

func (s *Starbox) SetStructTag(tag string)

SetStructTag sets the custom tag of Go struct fields for Starlark. It panics if called after execution.

func (*Starbox) String ΒΆ

func (s *Starbox) String() string

String returns the name of the Starbox instance.

type StarlarkFunc ΒΆ

type StarlarkFunc func(thread *starlark.Thread, fn *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error)

StarlarkFunc is a function that can be called from Starlark.

type Surface ΒΆ added in v0.2.0

type Surface struct {
	// Modules are the loadable modules, sorted by Name.
	Modules []ModuleSurface
	// Globals are the injected globals/builtins, sorted by Name.
	Globals []GlobalSurface
}

Surface is the inventory of everything a Box exposes to a script, derived from the Box's configuration WITHOUT running the script. It is the authoritative answer to "what can this script see", so callers need no hand-maintained registry that can drift from the real configuration.

DescribeSurface is side-effect free: it reads configuration and inspects the known-pure builtin module loaders, but it never invokes an opaque (AddModuleLoader) loader, never resolves a dynamic module, and never runs the user script. Members that would require any of those are reported as nil.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL