vibes

package
v0.70.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package vibes is the embedder API for the Vibescript scripting language. Hosts compile a .vibe source into a Script and invoke its functions through an Engine:

engine, _ := vibes.NewEngine(vibes.Config{StepQuota: 50_000})
script, _ := engine.Compile(source)
result, _ := script.Call(
    ctx,
    "greet",
    []value.Value{value.NewString("world")},
    vibes.CallOptions{},
)

Runtime values live in github.com/mgomes/vibescript/vibes/value. Host-provided capability contracts live under github.com/mgomes/vibescript/vibes/capability. This package provides the Engine/Script execution surface, capability adapter constructors, runtime errors, and the per-call Execution handle that builtins receive. Engine execution is bounded by Config (step and memory quotas, recursion limit, strict-effects mode, module allow/deny policies).

See ../README.md for the language reference and ../docs/architecture.md for the runtime design. The stability tiers of the embedding API — which exported symbols are supported and which are internal plumbing with no compatibility promise — are declared in ../docs/embedding-api-stability.md.

Example (SimpleScript)

Example_simpleScript shows the full compile-and-call cycle a host embedder uses to drive a Vibescript program.

package main

import (
	"context"
	"fmt"

	"github.com/mgomes/vibescript/vibes"
	"github.com/mgomes/vibescript/vibes/value"
)

func main() {
	engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
	script, err := engine.Compile(`def greet(name)
  "hello " + name
end`)
	if err != nil {
		panic(err)
	}
	result, err := script.Call(
		context.Background(),
		"greet",
		[]value.Value{value.NewString("world")},
		vibes.CallOptions{},
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.String())
}
Output:
hello world

Index

Examples

Constants

View Source
const (
	// ParamNormal is an ordinary positional parameter (def f(a)).
	ParamNormal = runtime.ParamNormal
	// ParamKeyword is a keyword parameter (def f(a:)), filled from
	// CallOptions.Keywords or a script-side keyword argument.
	ParamKeyword = runtime.ParamKeyword
	// ParamRest is a splat parameter (def f(*rest)) that collects the
	// remaining positional arguments into an array.
	ParamRest = runtime.ParamRest
	// ParamKeywordRest is a double-splat parameter (def f(**opts)) that
	// collects the remaining keyword arguments into a hash.
	ParamKeywordRest = runtime.ParamKeywordRest
)
View Source
const Unlimited = runtime.Unlimited

Unlimited disables a quota when supplied as a Config quota value. It is distinct from a zero value, which selects the built-in default.

Variables

View Source
var (
	ProfileLow    = runtime.ProfileLow
	ProfileMedium = runtime.ProfileMedium
	ProfileHigh   = runtime.ProfileHigh
	ProfileXHigh  = runtime.ProfileXHigh
)

The named quota profiles, in ascending order of generosity. The lower rungs model a constrained sandbox budget; xhigh runs a script like a normal interpreter (unlimited steps and memory, a high but finite recursion cap).

Functions

func DeclareNonMutating added in v0.60.0

func DeclareNonMutating(v value.Value) value.Value

DeclareNonMutating records a builtin's promise that no invocation of it writes to any container reachable from its receiver, arguments, keyword arguments, block, or from any execution's roots, and returns it. Allocating a container and filling it in is not such a write: the promise covers only state something else can already reach, so building a result and returning it keeps it. Script code the builtin drives through a block is not covered and does not need to be.

This is a safety promise, not a performance hint. The runtime stops invalidating its memoized memory-estimator walk around calls to a builtin that makes it, so a declaration that is not true leaves an execution accounting for less memory than it actually holds, and that execution then allocates past the MemoryQuotaBytes it was configured with. A builtin that declares nothing keeps the existing conservative behavior, which is slower and correct; omission costs speed, never correctness.

The promise is between an embedder and itself rather than between the sandbox and untrusted script. A host builtin already runs arbitrary Go in the embedding process and can allocate without bound and ignore every quota today, so declaring grants no capability a host lacked, and script code can neither observe the declaration nor reach it. It widens no sandbox boundary. What it does is switch off a backstop the host then has to honor itself.

Apply it to a builtin whose whole body is known, and re-check it when that body changes.

func DeclareNonRetaining added in v0.60.0

func DeclareNonRetaining(v value.Value) value.Value

DeclareNonRetaining records a builtin's promise that no invocation of it stores, anywhere that outlives the invocation, a reference to any Value it receives (receiver, arguments, keyword arguments, block) or returns, or to any container reachable from one -- and, symmetrically, that no value it returns or yields shares storage the host already holds (a wrapper built over a package-level map or an adapter field is a retained reference even though the invocation itself stored nothing). It returns the value. Package-level variables, fields on the adapter, closure captures, channels, caches and anything handed to another goroutine all count as outliving the invocation. So does keeping a container reached through an argument rather than the argument itself.

The boundary consults this promise (#1210): a declaring builtin's inputs skip the retention marking, its return skips the detach copy, and blocks it drives through Execution.CallBlock exchange values without boundary copies -- which is exactly why an untrue declaration is a live aliasing channel, not just an accounting error. A later change will also use it to scope the memory estimator's walk memo across a host call (#1199).

It is stated as a safety promise rather than a hint because of what it will mean once consulted: an execution calling a builtin that makes it keeps accounting for memory privately, so an untrue declaration would let a container the host kept be mutated afterwards without that execution observing the change, and its quota would then admit allocations it should have refused. Declare it only where that is true, not on the reasoning that it currently costs nothing.

It is a separate promise from DeclareNonMutating and neither implies the other. A builtin that only reads its arguments but files one away for later is non-mutating and not non-retaining; one that overwrites a slot in its receiver and keeps nothing is the reverse.

func MemberCompletionNames added in v0.50.0

func MemberCompletionNames() map[string][]string

MemberCompletionNames returns the builtin member-method names per receiver type (string, array, hash, int, float, money, duration, time), for editor tooling such as LSP completion.

func NewAutoBuiltin

func NewAutoBuiltin(name string, fn BuiltinFunc) value.Value

NewAutoBuiltin returns a builtin function Value that auto-invokes without parentheses.

Example
package main

import (
	"context"
	"fmt"

	"github.com/mgomes/vibescript/vibes"
	"github.com/mgomes/vibescript/vibes/value"
)

func main() {
	engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
	script, err := engine.Compile(`def run()
  tenant
end`)
	if err != nil {
		panic(err)
	}
	tenant := vibes.NewAutoBuiltin("tenant", func(_ *vibes.Execution, _ value.Value, _ []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
		return value.NewString("acme"), nil
	})
	result, err := script.Call(
		context.Background(),
		"run",
		nil,
		vibes.CallOptions{
			Globals: map[string]value.Value{"tenant": tenant},
		},
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.String())
}
Output:
acme

func NewBuiltin

func NewBuiltin(name string, fn BuiltinFunc) value.Value

NewBuiltin returns a builtin function Value.

Example
package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/mgomes/vibescript/vibes"
	"github.com/mgomes/vibescript/vibes/value"
)

func main() {
	engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
	script, err := engine.Compile(`def shout(word)
  upcase(word)
end`)
	if err != nil {
		panic(err)
	}
	upcase := vibes.NewBuiltin("upcase", func(_ *vibes.Execution, _ value.Value, args []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
		return value.NewString(strings.ToUpper(args[0].String())), nil
	})
	result, err := script.Call(
		context.Background(),
		"shout",
		[]value.Value{value.NewString("hi")},
		vibes.CallOptions{
			Globals: map[string]value.Value{"upcase": upcase},
		},
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(result.String())
}
Output:
HI

func NewTypedBuiltin added in v0.60.0

func NewTypedBuiltin(name string, fn BuiltinFunc, sig Signature) (value.Value, error)

NewTypedBuiltin returns a builtin function Value that publishes sig to the checker and validates calls against it at runtime. The value can be registered as an engine builtin, passed as a call-option global, or exposed as a capability method.

func QuotaProfileNames added in v0.60.0

func QuotaProfileNames() []string

QuotaProfileNames returns the profile names in ascending order of generosity.

Types

type Builtin

type Builtin = runtime.Builtin

Builtin represents a built-in function callable from Vibescript.

type BuiltinFunc

type BuiltinFunc = runtime.BuiltinFunc

BuiltinFunc is the Go function signature for built-in Vibescript functions.

type Builtins added in v0.29.0

type Builtins = map[string]value.Value

Builtins maps builtin function names to their Value implementations.

type CallOptions

type CallOptions = runtime.CallOptions

CallOptions configures globals, capabilities, and other settings for a script invocation.

type CapabilityAdapter

type CapabilityAdapter = runtime.CapabilityAdapter

CapabilityAdapter binds host capabilities into a script invocation.

func MustNewContextCapability added in v0.15.0

func MustNewContextCapability(name string, resolver contextcap.Resolver) CapabilityAdapter

MustNewContextCapability constructs a context CapabilityAdapter or panics when name is empty or resolver is a nil implementation.

func MustNewDBCapability added in v0.15.0

func MustNewDBCapability(name string, impl db.Database) CapabilityAdapter

MustNewDBCapability constructs a database CapabilityAdapter or panics when name is empty or impl is a nil implementation.

func MustNewEventsCapability added in v0.15.0

func MustNewEventsCapability(name string, publisher events.Publisher) CapabilityAdapter

MustNewEventsCapability constructs an events CapabilityAdapter or panics when name is empty or publisher is a nil implementation.

func MustNewJobQueueCapability added in v0.6.0

func MustNewJobQueueCapability(name string, impl jobqueue.JobQueue) CapabilityAdapter

MustNewJobQueueCapability constructs a job-queue CapabilityAdapter or panics when name is empty or impl is a nil implementation.

func NewContextCapability added in v0.15.0

func NewContextCapability(name string, resolver contextcap.Resolver) (CapabilityAdapter, error)

NewContextCapability constructs a data-only context CapabilityAdapter from the provided resolver. The adapter exposes the resolved attributes as a global on each script invocation.

func NewDBCapability added in v0.15.0

func NewDBCapability(name string, impl db.Database) (CapabilityAdapter, error)

NewDBCapability constructs a database CapabilityAdapter bound to the provided script-facing name. The adapter wraps a *db.Capability built from impl and dispatches the db.find/query/update/sum/each builtins. Use db.NewCapability directly when you only need the per-method dispatchers and intend to build a custom adapter.

func NewEventsCapability added in v0.15.0

func NewEventsCapability(name string, publisher events.Publisher) (CapabilityAdapter, error)

NewEventsCapability constructs an events CapabilityAdapter bound to the provided script-facing name. The adapter wraps an *events.Capability built from publisher and dispatches the publish builtin.

func NewJobQueueCapability

func NewJobQueueCapability(name string, impl jobqueue.JobQueue) (CapabilityAdapter, error)

NewJobQueueCapability constructs a job-queue CapabilityAdapter bound to the provided script-facing name. The adapter wraps a *jobqueue.Capability built from impl and dispatches the enqueue builtin (and the retry builtin when impl satisfies jobqueue.JobQueueWithRetry).

type CapabilityBinding

type CapabilityBinding = runtime.CapabilityBinding

CapabilityBinding provides execution context for adapters during binding.

type CapabilityContractProvider added in v0.13.0

type CapabilityContractProvider = runtime.CapabilityContractProvider

CapabilityContractProvider exposes per-method contracts for capability adapters.

type CapabilityMethodContract added in v0.13.0

type CapabilityMethodContract = runtime.CapabilityMethodContract

CapabilityMethodContract validates capability method calls at the boundary.

type CheckWarning added in v0.60.0

type CheckWarning = runtime.CheckWarning

CheckWarning is a statically detected contract issue reported by the checker (see Script.CheckWarnings and the docs/typing.md gradual-typing contract). It is the stable public name for the diagnostic type: Function names the containing function, Pos carries the source position, Message is the human-readable diagnostic, and Source is the file path of the required module the warning originates in (empty for the checked script itself).

The type is an alias for the internal checker representation, so values returned by Script.CheckWarnings, CheckWarningsWithOptions, and CheckWarningsForFunction can be stored and named through this type without importing implementation packages.

type Config

type Config = runtime.Config

Config controls interpreter execution bounds and enforcement modes.

Example (StrictEffects)

ExampleConfig_strictEffects shows that strict-effects mode rejects callable globals so hosts can be sure side effects flow through declared capabilities.

package main

import (
	"context"
	"fmt"
	"strings"

	"github.com/mgomes/vibescript/vibes"
	"github.com/mgomes/vibescript/vibes/value"
)

func main() {
	engine := vibes.MustNewEngine(vibes.Config{StrictEffects: true})
	script, err := engine.Compile(`def run()
  notify("hi")
end`)
	if err != nil {
		panic(err)
	}
	_, err = script.Call(
		context.Background(),
		"run",
		nil,
		vibes.CallOptions{
			Globals: map[string]value.Value{
				"notify": vibes.NewBuiltin("notify", func(_ *vibes.Execution, _ value.Value, _ []value.Value, _ map[string]value.Value, _ value.Value) (value.Value, error) {
					return value.NewNil(), nil
				}),
			},
		},
	)
	if err == nil {
		fmt.Println("expected strict-effects rejection")
		return
	}
	if strings.Contains(err.Error(), "strict effects") {
		fmt.Println("rejected callable global")
		return
	}
	fmt.Println("unexpected error:", err)
}
Output:
rejected callable global

type Engine

type Engine = runtime.Engine

Engine executes Vibescript programs with deterministic limits.

func MustNewEngine added in v0.6.0

func MustNewEngine(cfg Config) *Engine

MustNewEngine is like NewEngine but panics if cfg is invalid. Intended for package-level variable initialization and tests where invalid input is a programmer error and recovery is not meaningful. In production code prefer NewEngine and handle the error.

Example
package main

import (
	"fmt"

	"github.com/mgomes/vibescript/vibes"
)

func main() {
	engine := vibes.MustNewEngine(vibes.Config{StepQuota: 50_000})
	_ = engine
	fmt.Println("engine ready")
}
Output:
engine ready

func NewEngine

func NewEngine(cfg Config) (*Engine, error)

NewEngine constructs an Engine with sane defaults and registers built-ins.

Example
package main

import (
	"fmt"

	"github.com/mgomes/vibescript/vibes"
)

func main() {
	engine, err := vibes.NewEngine(vibes.Config{StepQuota: 50_000})
	if err != nil {
		panic(err)
	}
	_ = engine
	fmt.Println("engine ready")
}
Output:
engine ready

type Execution

type Execution = runtime.Execution

Execution holds the runtime state for a single script evaluation. It is the per-call handle passed to builtin functions and capability adapters. Embedders should not rely on its internal shape; treat it as opaque and use the exported methods (Context, Step, CallBlock).

type MemberContract added in v0.60.0

type MemberContract = runtime.MemberContract

MemberContract is the registered contract of one builtin member method: receiver kind, name and aliases, call shape, and effect metadata.

func MemberContracts added in v0.60.0

func MemberContracts() []MemberContract

MemberContracts returns the registered builtin member contracts, for editor tooling such as LSP completion. The runtime registry backing it also drives the static checker's member call validation.

type MemberParam added in v0.60.0

type MemberParam = runtime.MemberParam

MemberParam is one positional parameter of a builtin member contract.

type ParamKind added in v0.60.0

type ParamKind = runtime.ParamKind

ParamKind identifies how a function parameter receives values.

type ParseIssue added in v0.50.0

type ParseIssue = runtime.ParseIssue

ParseIssue is one structured parse failure extracted from an Engine.Compile error. Pos is the 1-indexed start position; End is the exclusive end of the offending token, or the zero Position when the parser could not determine a span.

func ParseIssues added in v0.50.0

func ParseIssues(err error) []ParseIssue

ParseIssues extracts the structured parse failures carried by a Compile error, in source order. It returns nil when err is nil or carries no parse positions, so callers can fall back to err.Error() for non-parse compile failures.

type Position

type Position = source.Position

Position is the public source-location type exposed on RuntimeError and related public surfaces. It is an alias for source.Position so the AST (in internal/ast) and the public error surface share a single definition without forcing AST consumers to import vibes.

type QuotaProfile added in v0.60.0

type QuotaProfile = runtime.QuotaProfile

QuotaProfile is a named bundle of the step, memory, and recursion quotas. ApplyTo writes every one of them, so a host layering its own override on a profile must set it after applying, not before.

func QuotaProfileByName added in v0.60.0

func QuotaProfileByName(name string) (QuotaProfile, bool)

QuotaProfileByName returns the profile with the given name, matched case-insensitively, and reports whether one was found.

type RuntimeError

type RuntimeError = runtime.RuntimeError

RuntimeError describes a script-level error raised during execution.

type Script

type Script = runtime.Script

Script represents a parsed Vibescript module ready for execution.

type Signature added in v0.60.0

type Signature = runtime.Signature

Signature is the opt-in static contract a host callable publishes to the checker; the same contract is enforced at runtime. See NewTypedBuiltin and Engine.RegisterBuiltinWithSignature.

type SignatureParam added in v0.60.0

type SignatureParam = runtime.SignatureParam

SignatureParam declares one positional parameter of a host callable's published Signature.

type StackFrame

type StackFrame = runtime.StackFrame

StackFrame describes a single frame in a RuntimeError stack trace.

Directories

Path Synopsis
capability
contextcap
Package contextcap provides a data-only capability adapter that resolves call-scoped context values into a script-visible hash or object.
Package contextcap provides a data-only capability adapter that resolves call-scoped context values into a script-visible hash or object.
db
Package db provides the host-side database capability adapter for Vibescript.
Package db provides the host-side database capability adapter for Vibescript.
events
Package events defines the host-facing contract for the events capability that Vibescript exposes to scripts.
Package events defines the host-facing contract for the events capability that Vibescript exposes to scripts.
jobqueue
Package jobqueue defines the host-facing contract for the job-queue capability that Vibescript exposes to scripts.
Package jobqueue defines the host-facing contract for the job-queue capability that Vibescript exposes to scripts.
internal
capabilitycontract
Package capabilitycontract centralizes the helper utilities shared by the carved vibes/capability/* subpackages.
Package capabilitycontract centralizes the helper utilities shared by the carved vibes/capability/* subpackages.
Package source contains stable source-location types shared between the AST (internal) and the public error surface.
Package source contains stable source-location types shared between the AST (internal) and the public error surface.
Package value defines the runtime Value type and its supporting domain-shaped types (Money, Duration, Range, time helpers) used throughout Vibescript.
Package value defines the runtime Value type and its supporting domain-shaped types (Money, Duration, Range, time helpers) used throughout Vibescript.

Jump to

Keyboard shortcuts

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