cfg

package
v0.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0 Imports: 22 Imported by: 0

Documentation

Overview

Package cfg defines the TOML configuration schema for devcell projects and workspaces.

Index

Constants

View Source
const (
	// LLMProviderDefault means no rerouting: each agent uses its own vendor's
	// backend and login (Claude Code → Anthropic, Codex → OpenAI).
	LLMProviderDefault    = "default"
	LLMProviderOllama     = "ollama"
	LLMProviderOpenRouter = "openrouter"
	LLMProviderLMStudio   = "lmstudio"
)

LLM providers that route agent traffic; empty means LLMProviderDefault.

View Source
const DefaultNixImage = "docker.io/nixos/nix:2.34.9"

DefaultNixImage is the pinned nixos/nix image for thin builds. Pinned because nixos/nix symlinks /etc files into /nix/store; upgrading changes the store hash and breaks when a shared volume is mounted over /nix.

View Source
const DefaultRegistry = "ghcr.io/devcell-sh/devcell"

DefaultRegistry is the default container registry for devcell images. Must match docker.DefaultRegistry.

View Source
const DefaultSchemaVersion = "v0.0.0"

DefaultSchemaVersion is the version published from main (unreleased).

View Source
const DefaultTartOCIImage = "ghcr.io/cirruslabs/macos-tahoe-base:latest"

DefaultTartOCIImage is the default macOS base image for tart VMs.

View Source
const SchemaBase = "https://devcell.sh/schema"

SchemaBase is the site path under which every schema version is served. Each version lives in its own directory, so configs can pin the schema matching their cell binary:

https://devcell.sh/schema/<version>/devcell.json             the config schema
https://devcell.sh/schema/<version>/devcell-sh/home/*.json   the home catalog

Astro copies web/public/ verbatim, so web/public/schema/<version>/ is the on-disk mirror. DefaultSchemaVersion is what main commits (regenerated by the schema-generate pre-commit hook and cell:build); a release can publish its own tag alongside it later. Reference it from a config with `#:schema https://devcell.sh/schema/v0.0.0/devcell.json` (taplo / Even Better TOML).

Variables

View Source
var Deprecations = []Deprecation{
	{
		Path:        []string{"cell", "thin"},
		Name:        "[cell] thin",
		Replacement: "(none)",
		Message:     "remove it; thin is the only build mode",
	},
	{
		Path:        []string{"cell", "libvirt_uri"},
		Name:        "[cell] libvirt_uri",
		Replacement: "(none)",
		Message:     "remove it; the libvirt engine was retired, run `cell --engine winkit` on the macOS host instead",
	},
	{
		Path:        []string{"cell", "libvirt_path_map"},
		Name:        "[cell] libvirt_path_map",
		Replacement: "(none)",
		Message:     "remove it; the libvirt engine was retired, run `cell --engine winkit` on the macOS host instead",
	},
	{
		Path:        []string{"cell", "vagrant_provider"},
		Name:        "[cell] vagrant_provider",
		Replacement: "(none)",
		Message:     `remove it; the vagrant engine was removed, use [cell] os = "macos" for a Tart VM`,
	},
	{
		Path:        []string{"cell", "vagrant_box"},
		Name:        "[cell] vagrant_box",
		Replacement: "(none)",
		Message:     `remove it; the vagrant engine was removed, use [cell] os = "macos" for a Tart VM`,
	},
	{
		Path:        []string{"cell", "qemu_project_sync"},
		Name:        "[cell] qemu_project_sync",
		Replacement: "(none)",
		Message:     "remove it; the libvirt engine was retired and it was the only engine that synced the project",
	},
	{
		Path:        []string{"cell", "qemu_disk_size_gb"},
		Name:        "[cell] qemu_disk_size_gb",
		Replacement: "(none)",
		Message:     "remove it; it has no effect",
	},
	{
		Path:        []string{"cell", "qemu_display"},
		Name:        "[cell] qemu_display",
		Replacement: "(none)",
		Message:     "remove it; it has no effect",
	},
	{
		Path:        []string{"cell", "qemu_ssh_host"},
		Name:        "[cell] qemu_ssh_host",
		Replacement: "(none)",
		Message:     "remove it; it has no effect",
	},
	{
		Path:        []string{"cell", "qemu_ssh_port"},
		Name:        "[cell] qemu_ssh_port",
		Replacement: "[cell] winkit_ssh_port",
		Message:     "use [cell] winkit_ssh_port = 2222 instead",
	},
	{
		Path:        []string{"cell", "qemu_windows_iso"},
		Name:        "[cell] qemu_windows_iso",
		Replacement: "[cell] winkit_windows_iso",
		Message:     `use [cell] winkit_windows_iso = "~/Downloads/Win11_ARM64.iso" instead`,
	},
	{
		Path:        []string{"cell", "qemu_cpus"},
		Name:        "[cell] qemu_cpus",
		Replacement: "[cell] winkit_cpus",
		Message:     "use [cell] winkit_cpus = 4 instead",
	},
	{
		Path:        []string{"cell", "qemu_memory_gb"},
		Name:        "[cell] qemu_memory_gb",
		Replacement: "[cell] winkit_memory_gb",
		Message:     "use [cell] winkit_memory_gb = 8 instead",
	},
	{
		Path:        []string{"cell", "gui"},
		Name:        "[cell] gui",
		Replacement: "[gui] enabled",
		Message:     "use [gui] enabled = false instead",
	},
	{
		Path:        []string{"cell", "nixhome"},
		Name:        "[cell] nixhome",
		Replacement: "[nix] nixhome",
		Message:     `use [nix] nixhome = "~/dev/home" instead`,
	},
	{
		Path:        []string{"packages", "npm"},
		Name:        "[packages.npm]",
		Replacement: "[packages.node]",
		Message:     `use [packages.node] "prettier" = "^3" instead`,
	},
	{
		Path:        []string{"packages", "nix", "stable"},
		Name:        "[packages.nix] stable",
		Replacement: "[cell] packages",
		Message:     `use [cell] packages = ["htop"] instead`,
	},
	{
		Path:        []string{"volumes"},
		Name:        "[[volumes]]",
		Replacement: "[cell] volumes",
		Message:     `use [cell] volumes = ["/host:/container:ro"] instead`,
	},
	{
		Path:        []string{"ports", "forward"},
		Name:        "[ports] forward",
		Replacement: "[cell] ports",
		Message:     `use [cell] ports = ["3000", "8080:3000"] instead`,
	},
	{
		Path:        []string{"mcp", "enabled"},
		Name:        "[mcp] enabled",
		Replacement: "[cell] mcps",
		Message:     `use [cell] mcps = ["playwright"] instead`,
	},
	{
		Path:        []string{"op"},
		Name:        "[op]",
		Replacement: "[secrets.onepassword]",
		Message:     `use [secrets.onepassword] documents = ["prod-api-keys"] instead`,
	},
	{
		Path:        []string{"llm", "use_ollama"},
		Name:        "[llm] use_ollama",
		Replacement: "[llm] provider",
		Message:     `use [llm] provider = "ollama" instead`,
	},
	{
		Path:        []string{"llm", "use_openrouter"},
		Name:        "[llm] use_openrouter",
		Replacement: "[llm] provider",
		Message:     `use [llm] provider = "openrouter" instead`,
	},
	{
		Path:        []string{"llm", "models", "default"},
		Name:        "[llm.models] default",
		Replacement: "[llm] model",
		Message:     `use [llm] provider = "openrouter" and model = "deepseek/deepseek-v4-pro" instead`,
	},
	{
		Path:        []string{"llm", "models", "providers"},
		Name:        "[llm.models.providers]",
		Replacement: "[llm.providers]",
		Message:     `use [llm.providers.ollama] models = ["qwen3:8b"] instead`,
	},
}

Deprecations lists every deprecated TOML key. Remove an entry together with its struct field when the old key is dropped.

View Source
var EmbeddedSchema []byte
View Source
var ErrReadOnly = errors.New("file is read-only")

ErrReadOnly marks a MigrateFile error for a file that has changes but cannot be written (a read-only bind mount inside a cell, say). Nothing is written and no backup is made; callers can skip the file with a hint instead of failing.

View Source
var Presets = map[string][]string{
	"claude": {
		"api.anthropic.com",
		"claude.ai",
		"claude.com",
		"platform.claude.com",
		"mcp-proxy.anthropic.com",
		"downloads.claude.ai",
		"code.claude.com",
		"storage.googleapis.com",
	},
	"codex": {
		"api.openai.com",
		"chatgpt.com",
		"auth.openai.com",
		"*.oaistatic.com",
		"*.oaiusercontent.com",
		"platform.openai.com",
	},
	"gemini": {
		"generativelanguage.googleapis.com",
		"oauth2.googleapis.com",
		"accounts.google.com",
	},
	"opencode": {
		"opencode.ai",
		"models.dev",
	},
	"openrouter": {
		"openrouter.ai",
	},
	"github": {
		"github.com",
		"api.github.com",
		"codeload.github.com",
		"*.githubusercontent.com",
		"ghcr.io",
	},
	"npm": {
		"registry.npmjs.org",
	},
	"pypi": {
		"pypi.org",
		"files.pythonhosted.org",
	},
	"go": {
		"proxy.golang.org",
		"sum.golang.org",
		"storage.googleapis.com",
	},
	"cargo": {
		"index.crates.io",
		"static.crates.io",
	},
	"nix": {
		"cache.nixos.org",
		"channels.nixos.org",
	},
	"mise": {
		"mise-versions.jdx.dev",
		"nodejs.org",
	},
	"docker": {
		"registry-1.docker.io",
		"auth.docker.io",
		"production.cloudflare.docker.com",
		"hub.docker.com",
	},
	"devcell": {
		"devcell.sh",
		"host.docker.internal",
	},
	"1password": {
		"*.1password.com",
		"*.1passwordservices.com",
		"*.1passwordusercontent.com",
	},
}

Presets maps preset names to their domain lists.

Functions

func ApplyEnv

func ApplyEnv(c *CellConfig, getenv func(string) string)

ApplyEnv overrides scalar fields from environment variables.

func CatalogURLFor

func CatalogURLFor(version string) string

CatalogURLFor returns the published directory of the home flake's module/stack/package catalog for a version (see internal/nixhome.CatalogPath).

func ConfigDrift

func ConfigDrift(old, new CellConfig) string

ConfigDrift describes what changed between two configs. Returns a human-readable summary, or "" if nothing drift-relevant changed.

func ConfigHash

func ConfigHash(c CellConfig) string

ConfigHash returns a short hex digest of the config fields that affect the running container. When the hash changes between launches, the container must be restarted to pick up the new config.

func ExpandPresets

func ExpandPresets(names []string) ([]string, error)

ExpandPresets expands a list of preset names into a deduplicated, sorted domain list. Returns an error if any preset name is unknown.

func FieldComments

func FieldComments(src []byte) (map[string]string, error)

FieldComments extracts struct field comments from Go source as a "StructName.FieldName" → text map. A trailing line comment wins over the doc comment above the field; fields with neither are absent.

func Getenv

func Getenv(name string) string

Getenv is os.Getenv for an env var that replaced a deprecated name: when name is unset it falls back to the deprecated one. It does not warn; ApplyEnv does, once per invocation.

func HMOptionsNix

func HMOptionsNix() string

HMOptionsNix renders the home-manager option declarations for the devcell.toml schema by reflecting over CellConfig. The generated file (nix/home-manager/options.nix, written by `task hm:generate`) is what keeps `devcell.*` options in lockstep with the Go schema — hand-editing it would reintroduce drift, hence the DO NOT EDIT header.

Mapping rules:

  • string → types.str, int → types.int, bool / *bool → types.bool
  • []string → listOf str, map[string]string → attrsOf str
  • struct field → plain nested attrset (a TOML table the user sets directly: devcell.llm.system_prompt = "...")
  • []struct / map[string]struct → listOf/attrsOf (submodule { ... })

Every leaf is nullOr with default null: unset options never reach the rendered TOML, so absence semantics (e.g. modules unset vs modules = []) match a hand-written devcell.toml.

func JSONSchema

func JSONSchema(opts SchemaOptions) ([]byte, error)

JSONSchema renders the devcell.toml JSON Schema (draft 2020-12) by reflecting over CellConfig, the same source of truth HMOptionsNix uses for nix/home-manager/options.nix. `task schema:generate` (a dep of cell:build) writes web/public/schema/devcell.json from it.

opts.Descriptions maps "StructName.FieldName" to a description; FieldComments builds it from the source comments in cfg.go. Catalog names become non-strict completions (examples, never enum: a custom home can add modules and stacks the published catalog does not know), and package lists carry the loader's nix attribute pattern with a link to search.nixos.org.

Mapping rules:

  • string → string, int → integer, float → number, bool / *bool → boolean
  • []T → array of T, map[string]T → object with additionalProperties T
  • struct → closed object (additionalProperties: false), so unknown keys get flagged in the editor the way checkUnknownKeys flags them at load
  • a key listed in Deprecations is marked deprecated, with the migration message appended to its description

Fields tagged toml:"-" are not user-facing and are skipped. The hm:"-" tag is nix-specific and ignored here: those keys are still valid TOML.

func NetworkProxyEnabled

func NetworkProxyEnabled(c CellConfig) bool

NetworkProxyEnabled reports whether the network proxy is enabled in the merged config. Either layer setting enabled = true is enough.

func QualifyImage

func QualifyImage(ref string) string

QualifyImage ensures an image reference is fully qualified for Podman compatibility. Docker implicitly prepends docker.io, but Podman requires explicit registry prefixes.

  • "alpine" → "docker.io/library/alpine"
  • "alpine:3.20" → "docker.io/library/alpine:3.20"
  • "nixos/nix:2.34.7" → "docker.io/nixos/nix:2.34.7"
  • "ghcr.io/foo/bar:v1" → unchanged (already qualified)

func SchemaURLFor

func SchemaURLFor(version string) string

SchemaURLFor returns the published URL of the config schema for a version.

func ValidateDefaultCommand

func ValidateDefaultCommand(cmd string) error

ValidateDefaultCommand checks that default_command is a known subcommand name. Empty is valid (no default, shows help).

func ValidateModulesAgainstCatalog

func ValidateModulesAgainstCatalog(userModules, catalogNames []string) error

ValidateModulesAgainstCatalog checks that every name in `userModules` exists in `catalogNames`. Returns nil on success, or a user-friendly error listing all unknown names and the available catalog for hinting.

Used by the CLI at TOML-parse time to catch typos like `yahoo-finanace` before the nix subprocess gets invoked.

func ValidateNetworkProxy

func ValidateNetworkProxy(c CellConfig) error

ValidateNetworkProxy checks [network.proxy] config for errors.

func ValidateNixPackageNames

func ValidateNixPackageNames(np NixPackages) error

ValidateNixPackageNames checks that every package name in every channel is a syntactically valid nix attribute name. Returns nil if all names are valid.

func ValidateNixPackages

func ValidateNixPackages(np NixPackages) error

ValidateNixPackages runs all nix package validations.

func ValidateStack

func ValidateStack(stack string) error

ValidateStack checks that stack is a known stack name. Empty is valid (defaults to ultimate).

func ValidateWireguard

func ValidateWireguard(c CellConfig) error

ValidateWireguard checks that every enabled [[wireguard]] entry has a non-empty name, config, valid WireGuard syntax, at least one peer with a valid PublicKey, and an interface Address. An inline PresharedKey, when present, must be a valid 32-byte base64 key, and all peers must share the same one: at runtime a single WG_PRESHARED_KEY is applied to every peer.

func WireguardEnabled

func WireguardEnabled(c CellConfig) bool

WireguardEnabled reports whether any [[wireguard]] entry is enabled.

Types

type AwsSection

type AwsSection struct {
	ReadOnly *bool `toml:"read_only"` // default: false (nil = not set → full access)
}

AwsSection holds [aws] config for AWS credential scoping.

func (AwsSection) ResolvedReadOnly

func (a AwsSection) ResolvedReadOnly() bool

ResolvedReadOnly returns false unless explicitly set to true.

type BuildSection

type BuildSection struct {
	Memory  string `toml:"memory"`   // docker --memory ceiling (e.g. "16g"); "0" = uncapped; env: DEVCELL_BUILD_MEMORY
	CPUs    string `toml:"cpus"`     // docker --cpus quota (e.g. "8"); "0" = no quota; env: DEVCELL_BUILD_CPUS
	MaxJobs int    `toml:"max_jobs"` // nix max-jobs; 0 = derived from ceiling; env: DEVCELL_NIX_MAX_JOBS
	Cores   int    `toml:"cores"`    // nix cores (make -j per job); 0 = derived; env: DEVCELL_NIX_CORES
	Threads int    `toml:"threads"`  // nix download threads (max-substitution-jobs + http-connections); 0 = 128; env: DEVCELL_BUILD_THREADS
}

BuildSection holds [build] config for thin-build resource ceilings. Values feed the same resolution chain as the env vars; an explicit env var always wins over TOML (env > toml > derived default).

type CellConfig

type CellConfig struct {
	Cell      CellSection
	Docker    DockerSection  `toml:"docker"`
	Build     BuildSection   `toml:"build"`
	Nix       NixSection     `toml:"nix"`
	LLM       LLMSection     `toml:"llm"`
	Git       GitSection     `toml:"git"`
	Ports     PortsSection   `toml:"ports"`
	Op        OpSection      `toml:"op"`
	Secrets   SecretsSection `toml:"secrets"`
	Aws       AwsSection     `toml:"aws"`
	Mcp       McpSection     `toml:"mcp"`
	Stealth   StealthSection `toml:"stealth"`
	GUI       GUISection     `toml:"gui"`
	Theme     ThemeSection   `toml:"theme"`
	Network   NetworkSection `toml:"network"`
	Env       map[string]string
	Mise      map[string]string `toml:"mise"` // [mise] — keys map to MISE_<UPPER_KEY> env vars
	Volumes   []VolumeMount
	Packages  PackagesSection
	Wireguard []WireguardEntry `toml:"wireguard"`

	DeprecatedUses []DeprecatedUse `toml:"-"` // deprecated keys found while loading, in file order
}

CellConfig is the merged configuration from all TOML layers.

func LoadFile

func LoadFile(path string) (CellConfig, error)

LoadFile parses a TOML file into CellConfig. Returns zero value + nil error if the file does not exist.

func LoadFromOS

func LoadFromOS(configDir, cwd string) CellConfig

LoadFromOS loads the layered config using real XDG paths and os.Getenv. Parse errors are logged to stderr and the file is skipped.

func LoadFromOSWithDirs

func LoadFromOSWithDirs(configDir, cwd string) (CellConfig, error)

LoadFromOSWithDirs loads the layered config using explicit directories and os.Getenv. Both devcell.toml and .devcell.toml are valid project configs. When both exist, devcell.toml loads first and .devcell.toml merges on top (wins). Returns an error if a config file exists but has a parse error.

func LoadLayered

func LoadLayered(globalPath string, getenv func(string) string, projectPaths ...string) (CellConfig, error)

LoadLayered loads global + project files, merges them, then applies env overrides. Multiple project paths are merged left-to-right: each successive layer wins. Returns an error if any file exists but has a parse error (missing files are fine).

func Merge

func Merge(global, project CellConfig) CellConfig

Merge returns a new CellConfig with project overriding global for scalars; slices accumulate (Volumes, Ports.Forward, Op documents, [cell].modules). For [cell].modules: explicit empty list in project ([]) clears global as escape hatch; otherwise project values are unioned with global, deduped.

type CellSection

type CellSection struct {
	ImageTag         string            `toml:"image_tag"`
	Registry         string            `toml:"registry"`                // container registry; default: DefaultRegistry; env: DEVCELL_REGISTRY
	GUI              *bool             `toml:"gui"`                     // default: true (nil = not set → true)
	Timezone         string            `toml:"timezone"`                // IANA tz (e.g. "Europe/Prague"); default: host $TZ
	Locale           string            `toml:"locale"`                  // POSIX locale (e.g. "en_US.UTF-8"); default: "en_US.UTF-8"
	Stack            string            `toml:"stack"`                   // nix stack name (e.g. "go", "python"); default: "base" (see ResolvedStack)
	Modules          []string          `toml:"modules"`                 // extra nix modules to compose on top of stack
	NixhomePath      string            `toml:"nixhome"`                 // deprecated: use [nix] nixhome instead
	OS               string            `toml:"os"`                      // guest OS: "linux" (default), "macos", "windows" or "winpe"; derives engine when [cell].engine is unset
	Engine           string            `toml:"engine"`                  // execution engine: "docker" (default), "tart" or "winkit"
	VagrantProvider  string            `toml:"vagrant_provider"`        // retired vagrant engine; parsed only so the deprecation warning fires
	VagrantBox       string            `toml:"vagrant_box"`             // retired vagrant engine; parsed only so the deprecation warning fires
	KVM              *bool             `toml:"kvm"`                     // pass the daemon host's /dev/kvm into the container so QEMU gets hardware accel instead of TCG; default: false; env: DEVCELL_KVM
	PerCellImage     *bool             `toml:"per_cell_image"`          // tag user image per cell instead of per stack; default: false
	Hostname         string            `toml:"hostname"`                // override container hostname; default: computed "devcell-<cellname>"; env: DEVCELL_HOSTNAME
	MacAddress       string            `toml:"mac_address"`             // MAC for the container's NIC (XX:XX:XX:XX:XX:XX); pinned across restarts for infra-side identity persistence. Honored on user-defined bridge networks (devcell uses --network devcell-network). Empty → docker auto-assigns a random MAC per launch.
	Thin             *bool             `toml:"thin"`                    // thin image mode; default: true; disable with thin=false or DEVCELL_THIN=0
	StaleWarning     *bool             `toml:"stale_warning"`           // CELL-391 "cell is behind — parallel reality" nudge at start; default: true; env: DEVCELL_STALE_WARN
	Background       *bool             `toml:"background"`              // keep VM/container running after shell exit; default: false; env: DEVCELL_BACKGROUND
	Experimental     StringList        `toml:"experimental"`            // opt-in experimental features, e.g. ["ui-cage", "ui-boot-popup"]; flag: --experimental=a,b; env: DEVCELL_EXPERIMENTAL=a,b; names and the gate live in internal/experiments
	TartSSHPort      int               `toml:"tart_ssh_port"`           // SSH port for tart engine; default: 22; env: DEVCELL_TART_SSH_PORT
	TartSSHHost      string            `toml:"tart_ssh_host"`           // SSH host for tart engine; default: "localhost"; env: DEVCELL_TART_SSH_HOST
	TartSSHUser      string            `toml:"tart_ssh_user"`           // SSH user for tart engine; default: "admin"; env: DEVCELL_TART_SSH_USER
	TartSSHKey       string            `toml:"tart_ssh_key"`            // path to SSH private key for tart; env: DEVCELL_TART_SSH_KEY
	TartOCIImage     string            `toml:"tart_oci_image"`          // OCI base image for tart VMs; default: DefaultTartOCIImage; env: DEVCELL_TART_OCI_IMAGE
	WinkitSSHPort    int               `toml:"winkit_ssh_port"`         // SSH port for winkit engine; default: allocated per cell ID; env: DEVCELL_WINKIT_SSH_PORT
	WinkitWindowsISO string            `toml:"winkit_windows_iso"`      // path to Windows ARM64 ISO for winkit engine; env: DEVCELL_WINKIT_WINDOWS_ISO
	WinkitCPUs       int               `toml:"winkit_cpus"`             // winkit VM vCPUs; default: 4; env: DEVCELL_WINKIT_CPUS
	WinkitMemoryGB   int               `toml:"winkit_memory_gb"`        // winkit VM RAM in GB; default: 4; env: DEVCELL_WINKIT_MEMORY_GB
	QemuSSHPort      int               `toml:"qemu_ssh_port" hm:"-"`    // deprecated spelling of winkit_ssh_port; merged into it by LoadFile
	QemuSSHHost      string            `toml:"qemu_ssh_host"`           // deprecated, no effect; parsed only so the deprecation warning fires
	QemuWindowsISO   string            `toml:"qemu_windows_iso" hm:"-"` // deprecated spelling of winkit_windows_iso; merged into it by LoadFile
	QemuCPUs         int               `toml:"qemu_cpus" hm:"-"`        // deprecated spelling of winkit_cpus; merged into it by LoadFile
	QemuMemoryGB     int               `toml:"qemu_memory_gb" hm:"-"`   // deprecated spelling of winkit_memory_gb; merged into it by LoadFile
	QemuDiskSizeGB   int               `toml:"qemu_disk_size_gb"`       // no effect; parsed only so the deprecation warning fires
	QemuDisplay      string            `toml:"qemu_display"`            // deprecated, no effect; parsed only so the deprecation warning fires
	LibvirtURI       string            `toml:"libvirt_uri"`             // retired libvirt engine; parsed only so the deprecation warning fires
	LibvirtPathMap   map[string]string `toml:"libvirt_path_map"`        // container prefix -> host prefix rewrites for domain XML paths (CELL-375); empty = CLI runs on the host
	QemuProjectSync  string            `toml:"qemu_project_sync"`       // retired with the libvirt engine; parsed only so the deprecation warning fires
	DefaultCommand   string            `toml:"default_command"`         // subcommand to run when `cell` is invoked with no args; env: DEVCELL_DEFAULT_COMMAND
	DockerSocket     *bool             `toml:"docker_socket"`           // mount /var/run/docker.sock into the container; default: true; env: DEVCELL_DOCKER_SOCKET
	Flake            *bool             `toml:"flake"`                   // enable project-level flake.nix install; default: false (opt-in); env: DEVCELL_FLAKE
	Packages         []string          `toml:"packages"`                // nix packages from the stable channel, baked into the image at build time
	Volumes          []string          `toml:"volumes"`                 // shorthand volume list: "/path", "/host:/container", "/host:/container:ro"
	Ports            []string          `toml:"ports"`                   // shorthand port forwards: "3000", "8080:3000" (merged into [ports] forward)
	Mcps             []string          `toml:"mcps"`                    // shorthand MCP servers to enable: ["playwright", "aws-api"] (merged into [mcp] enabled)
}

CellSection holds [cell] config.

func (CellSection) DescribeModulesSource

func (c CellSection) DescribeModulesSource() string

DescribeModulesSource classifies how the effective module set is sourced — stack-only, explicit-modules-only, both merged, or default — so the cell startup banner can tell the user at a glance what's about to load (CELL-48).

default (base stack, no extra modules)  // neither set
stack=<name>                            // only stack
modules=[a,b,c]                         // only explicit modules
stack=<name> + modules=[a,b,c] (merged) // both

func (CellSection) FlakeEnabled

func (c CellSection) FlakeEnabled() bool

FlakeEnabled returns whether project-level flake.nix install is enabled: env > toml > false.

func (CellSection) KVMExplicitlyDisabled

func (c CellSection) KVMExplicitlyDisabled() bool

KVMExplicitlyDisabled returns true when the user has explicitly opted out of KVM passthrough via DEVCELL_KVM=0 or [cell] kvm = false. When true, the engine must not auto-detect KVM even if the daemon host has /dev/kvm.

func (CellSection) ResolvedBackground

func (c CellSection) ResolvedBackground() bool

ResolvedBackground returns the effective background setting: default OFF, enabled by env/toml.

func (CellSection) ResolvedDefaultCommand

func (c CellSection) ResolvedDefaultCommand() string

ResolvedDefaultCommand returns the effective default command: env > toml > "".

func (CellSection) ResolvedDockerSocket

func (c CellSection) ResolvedDockerSocket() bool

ResolvedDockerSocket returns the effective docker socket mount setting: env > toml > default ON. Set docker_socket=false or DEVCELL_DOCKER_SOCKET=0 to prevent mounting /var/run/docker.sock into the container.

func (CellSection) ResolvedExperimental

func (c CellSection) ResolvedExperimental() []string

ResolvedExperimental is the experimental features named in [cell] experimental plus DEVCELL_EXPERIMENTAL (comma-separated), unioned, trimmed and deduplicated, in that order. Validation and the --experimental flag are internal/experiments' job (see experiments.Resolve).

func (CellSection) ResolvedGUI

func (c CellSection) ResolvedGUI() bool

ResolvedGUI returns the effective GUI setting: true unless explicitly set to false.

func (CellSection) ResolvedHostname

func (c CellSection) ResolvedHostname(computed string) string

ResolvedHostname returns the effective container hostname. Precedence: DEVCELL_HOSTNAME env > [cell] hostname in TOML > computed default (typically "devcell-<cellname>" assembled by config.Load).

func (CellSection) ResolvedKVM

func (c CellSection) ResolvedKVM() bool

ResolvedKVM returns the effective KVM passthrough setting: env > toml > default OFF. When no explicit setting exists, the docker engine auto-detects by probing the daemon host; see RunSpec.KVMAutoDetected in the engine layer.

func (CellSection) ResolvedPerCellImage

func (c CellSection) ResolvedPerCellImage() bool

ResolvedPerCellImage returns true only when explicitly enabled.

func (CellSection) ResolvedRegistry

func (c CellSection) ResolvedRegistry() string

ResolvedRegistry returns the effective registry: env > toml > default.

func (CellSection) ResolvedStack

func (c CellSection) ResolvedStack() string

ResolvedStack returns Stack if set, else "base".

func (CellSection) ResolvedTartOCIImage

func (c CellSection) ResolvedTartOCIImage() string

ResolvedTartOCIImage returns the effective tart OCI base image: env > toml > default.

func (CellSection) ResolvedTartSSHHost

func (c CellSection) ResolvedTartSSHHost() string

ResolvedTartSSHHost returns the effective SSH host: env > toml > default "localhost".

func (CellSection) ResolvedTartSSHKey

func (c CellSection) ResolvedTartSSHKey() string

ResolvedTartSSHKey returns the effective SSH key path: env > toml > "".

func (CellSection) ResolvedTartSSHPort

func (c CellSection) ResolvedTartSSHPort() int

ResolvedTartSSHPort returns the effective SSH port: env > toml > default 22.

func (CellSection) ResolvedTartSSHUser

func (c CellSection) ResolvedTartSSHUser() string

ResolvedTartSSHUser returns the effective SSH user: env > toml > default "admin". Cirrus Labs OCI images ship with user "admin"; our init flow provisions into that account rather than creating a separate user.

func (CellSection) ResolvedThin

func (c CellSection) ResolvedThin() bool

ResolvedThin returns the effective thin setting: default ON, disabled by env/toml.

func (CellSection) ResolvedWinkitCPUs

func (c CellSection) ResolvedWinkitCPUs() int

ResolvedWinkitCPUs returns the effective winkit vCPU count: DEVCELL_WINKIT_CPUS > toml > default 4.

func (CellSection) ResolvedWinkitMemoryGB

func (c CellSection) ResolvedWinkitMemoryGB() int

ResolvedWinkitMemoryGB returns the effective winkit memory in GB: DEVCELL_WINKIT_MEMORY_GB > toml > default 4.

func (CellSection) ResolvedWinkitSSHPort

func (c CellSection) ResolvedWinkitSSHPort() int

ResolvedWinkitSSHPort returns the effective winkit SSH port: DEVCELL_WINKIT_SSH_PORT > toml > default 2222. The winkit engine only uses it when one of them is set; otherwise it allocates a port per cell ID.

func (CellSection) ResolvedWinkitWindowsISO

func (c CellSection) ResolvedWinkitWindowsISO() string

ResolvedWinkitWindowsISO returns the Windows ISO path: DEVCELL_WINKIT_WINDOWS_ISO > toml > "".

func (CellSection) StackExplicit

func (c CellSection) StackExplicit() bool

StackExplicit reports whether the user opted into a specific stack via TOML (`[cell] stack = "..."`). Drives the build progress label — when false, the "stack=..." qualifier is suppressed (CELL-43). CLI/env overrides are handled at the call site by OR'ing the override into this flag.

func (CellSection) StaleWarningEnabled

func (c CellSection) StaleWarningEnabled() bool

StaleWarningEnabled reports whether the CELL-391 stale-cell nudge should fire at cell start. Default (unset) is enabled — it's a read-only nudge with a proceed-by-default prompt, so opting out is the explicit act.

type DeprecatedUse

type DeprecatedUse struct {
	Deprecation
	File string
}

DeprecatedUse records a deprecated key found in a specific config file.

func (DeprecatedUse) Warning

func (u DeprecatedUse) Warning() string

Warning is the user-facing line for this use. File is the config file the deprecated key was read from; env var deprecations have no file, so the prefix is omitted.

type Deprecation

type Deprecation struct {
	Path        []string // old TOML key path, e.g. {"ports", "forward"}
	Name        string   // old key as users write it, e.g. "[ports] forward"
	Replacement string   // new key, e.g. "[cell] ports"
	Message     string   // what the user should do, shown verbatim, e.g. `use [cell] ports = ["3000"] instead`
}

Deprecation is a TOML key that was renamed. The old key keeps working (its value is merged into the replacement) but warns on every load.

type DockerPolicy

type DockerPolicy interface {
	Policy
	DropAllCaps() bool
	SafeCaps() []string
	DeniedCaps() map[string]bool
	DenyPrivileged() bool
	DenyDockerSock() bool
	DenyUserVolumes() bool
	DeniedMountPaths() []string
	DenyOpRun() bool
	DenyInheritEnv() bool
	DenyWireguard() bool
	DenyKVM() bool
	DenyTUN() bool
}

DockerPolicy extends Policy with container-specific isolation controls.

type DockerSection

type DockerSection struct {
	Privileged bool     `toml:"privileged"` // run container with --privileged; default: false
	CapAdd     []string `toml:"cap_add"`    // extra Linux capabilities (e.g. ["SYS_ADMIN"]); default: none
	MemLimit   string   `toml:"mem_limit"`  // docker --memory ceiling (e.g. "4g"); "0" = uncapped; env: DEVCELL_DOCKER_MEM_LIMIT
	CPULimit   string   `toml:"cpu_limit"`  // docker --cpus quota (e.g. "2"); "0" = no quota; env: DEVCELL_DOCKER_CPU_LIMIT
	ShmSize    string   `toml:"shm_size"`   // docker --shm-size (e.g. "1g"); env: DEVCELL_DOCKER_SHM_SIZE
}

DockerSection holds [docker] config for runtime container resource limits. Values follow the same env > toml > default resolution chain as other sections.

func (DockerSection) ResolvedCPULimit

func (d DockerSection) ResolvedCPULimit() string

ResolvedCPULimit returns the effective CPU limit: env > toml > default "2".

func (DockerSection) ResolvedMemLimit

func (d DockerSection) ResolvedMemLimit() string

ResolvedMemLimit returns the effective memory limit: env > toml > default "4g".

func (DockerSection) ResolvedShmSize

func (d DockerSection) ResolvedShmSize() string

ResolvedShmSize returns the effective shm size: env > toml > default "1g".

type GUISection

type GUISection struct {
	Enabled    *bool  `toml:"enabled"`    // default: true (nil = not set → true)
	WM         string `toml:"wm"`         // "icewm" (default) or "fluxbox"
	Resolution string `toml:"resolution"` // logical resolution; default: "1920x1080x24"
	Scale      int    `toml:"scale"`      // display scale factor (1=96dpi, 2=192dpi HiDPI); default: 1
}

GUISection holds [gui] config for desktop/window-manager settings.

func (GUISection) ResolvedDPI

func (g GUISection) ResolvedDPI() int

ResolvedDPI returns the X server DPI: 96 * scale.

func (GUISection) ResolvedEnabled

func (g GUISection) ResolvedEnabled() bool

ResolvedEnabled returns the effective GUI setting: true unless explicitly set to false.

func (GUISection) ResolvedFramebufferResolution

func (g GUISection) ResolvedFramebufferResolution() string

ResolvedFramebufferResolution returns the physical Xvfb framebuffer size: logical resolution multiplied by scale factor.

func (GUISection) ResolvedResolution

func (g GUISection) ResolvedResolution() string

ResolvedResolution returns the logical resolution: "1920x1080x24" unless explicitly set.

func (GUISection) ResolvedScale

func (g GUISection) ResolvedScale() int

ResolvedScale returns the display scale factor: 1 unless explicitly set.

func (GUISection) ResolvedWM

func (g GUISection) ResolvedWM() string

ResolvedWM returns the effective window manager: "icewm" unless explicitly set.

type GitSection

type GitSection struct {
	AuthorName     string `toml:"author_name"`
	AuthorEmail    string `toml:"author_email"`
	CommitterName  string `toml:"committer_name"`
	CommitterEmail string `toml:"committer_email"`
}

GitSection holds [git] config for git identity inside the container.

func (GitSection) HasIdentity

func (g GitSection) HasIdentity() bool

HasIdentity reports whether any git identity field is set.

func (GitSection) ResolvedCommitterEmail

func (g GitSection) ResolvedCommitterEmail() string

ResolvedCommitterEmail returns CommitterEmail if set, else falls back to AuthorEmail.

func (GitSection) ResolvedCommitterName

func (g GitSection) ResolvedCommitterName() string

ResolvedCommitterName returns CommitterName if set, else falls back to AuthorName.

type LLMModelsSection

type LLMModelsSection struct {
	Default   string                 `toml:"default"`
	Providers map[string]LLMProvider `toml:"providers"`
}

LLMModelsSection pairs the default model with the provider catalog. It is also the shape of the deprecated [llm.models] table.

type LLMProvider

type LLMProvider struct {
	BaseURL string   `toml:"base_url"`
	Models  []string `toml:"models"`
}

LLMProvider holds a single provider entry under [llm.providers.<name>].

type LLMSection

type LLMSection struct {
	SystemPrompt           string `toml:"system_prompt"`
	SystemPromptFile       string `toml:"system_prompt_file"`
	AppendSystemPrompt     string `toml:"append_system_prompt"`
	AppendSystemPromptFile string `toml:"append_system_prompt_file"`

	Provider  string                 `toml:"provider"`  // default | ollama | openrouter
	Model     string                 `toml:"model"`     // the provider's own model ID, no prefix
	Providers map[string]LLMProvider `toml:"providers"` // per-provider base_url + models

	// Deprecated keys, migrated into the fields above by migrateLLM.
	UseOllama     bool             `toml:"use_ollama" hm:"-"`
	UseOpenRouter bool             `toml:"use_openrouter" hm:"-"`
	Models        LLMModelsSection `toml:"models" hm:"-"`
}

LLMSection holds [llm] config — all AI agent settings in one place.

Two independent layers, each with an inline and a file form:

  • SystemPrompt / SystemPromptFile REPLACE Claude Code's built-in prompt (claude --system-prompt-file). Setting this discards the stock tool guidance and safety instructions — you own the whole prompt.
  • AppendSystemPrompt / AppendSystemPromptFile layer on top of whichever base is in effect (claude --append-system-prompt-file), alongside the container context devcell always contributes.

Within a layer the inline and file forms are mutually exclusive — set one or neither. The resolver in internal/cell.ResolveSystemPrompt validates this and returns an error when both are set, so we don't fail config load for projects where the conflict is harmless (e.g. callers that don't read system prompts).

func (LLMSection) ActiveProvider

func (l LLMSection) ActiveProvider() string

ActiveProvider returns Provider, defaulting to "default".

func (LLMSection) ModelFor

func (l LLMSection) ModelFor(provider string) string

ModelFor returns [llm] model when provider is the configured one, else "". The model ID belongs to its provider; a flag switching providers for one run must not carry it over.

type McpSection

type McpSection struct {
	Enabled []string `toml:"enabled"` // MCP server names to enable (e.g. ["aws-api", "terraform"])
}

McpSection holds [mcp] config for per-repo MCP server enablement.

type MigrationChange

type MigrationChange struct {
	Key    string // the deprecated key as the user wrote it, e.g. "[cell] qemu_ssh_port"
	Action string // what happened to it, e.g. `renamed to [cell] winkit_ssh_port`
}

MigrationChange is one rewrite MigrateTOML applied.

type MigrationResult

type MigrationResult struct {
	Before  string
	After   string
	Changes []MigrationChange
}

MigrationResult is the outcome of MigrateTOML: the rewritten text and what changed. Changes is empty when nothing was deprecated.

func MigrateFile

func MigrateFile(path string, write bool) (MigrationResult, string, error)

MigrateFile runs MigrateTOML on path. With write set, a changed file is first copied to "<path>.bak-<UTC timestamp>" and then overwritten; the backup path is returned. A missing file, a dry run, or a file with nothing to migrate returns no backup. A file that cannot be opened for writing returns ErrReadOnly (a *ReadOnlySymlinkError when the path is a symlink) before any backup is made; the result still carries the changes so callers can show what the user has to apply by hand.

func MigrateTOML

func MigrateTOML(src string) (MigrationResult, error)

MigrateTOML rewrites every deprecated key in src to its current spelling, keeping comments, ordering and unrelated lines. The result is loaded the same way LoadFile loads a config, and an error is returned (with no result) when it fails to parse or still carries a deprecation, so callers never write a config that is worse than the one they started from.

Rewrites follow the Deprecations table plus the forms it cannot express: [[volumes]] tables collapse into [cell] volumes, use_ollama and use_openrouter become [llm] provider, a "provider/" prefix on [llm] model is split off, and [op], [packages.npm] and [llm.models.providers] are renamed as whole tables. A key already present under its new name wins; arrays under both names are concatenated.

type MissingEnvError

type MissingEnvError struct {
	// Refs maps each missing host var name to the [env].<key> paths that
	// referenced it (the same var may be referenced from multiple [env] keys).
	Refs map[string][]string
}

MissingEnvError reports host env vars referenced from devcell.toml [env] values that are unset (or empty) on the host. Aggregates all misses so the user fixes them in one pass rather than one boot per typo.

func ExpandEnv

func ExpandEnv(env map[string]string, lookup func(string) (string, bool), secrets map[string]string) *MissingEnvError

ExpandEnv resolves two kinds of references in [env] values:

  • ${VAR} and $VAR: resolved against the host environment via lookup (pass os.LookupEnv in production). Set-but-empty is treated as a miss.
  • ${secret:NAME}: resolved against the secrets map (1Password field labels). Only the ${secret:NAME} form is recognized (no $secret:NAME shorthand).

Values are mutated in place. Plain values (no `$`) pass through unchanged and never allocate.

Returns a non-nil *MissingEnvError if any reference could not be resolved.

func (*MissingEnvError) Error

func (e *MissingEnvError) Error() string

type NetworkProxySection

type NetworkProxySection struct {
	Enabled          *bool    `toml:"enabled"`
	Mode             string   `toml:"mode"`
	Presets          []string `toml:"presets"`
	Allow            []string `toml:"allow"`
	Block            []string `toml:"block"`
	AllowHostNetwork *bool    `toml:"allow_host_network"`
	Log              *bool    `toml:"log"`
	Image            string   `toml:"image"`
}

NetworkProxySection holds [network.proxy] config for egress filtering.

func (NetworkProxySection) ResolvedAllowHostNetwork

func (p NetworkProxySection) ResolvedAllowHostNetwork() bool

ResolvedAllowHostNetwork returns false when AllowHostNetwork is nil.

func (NetworkProxySection) ResolvedEnabled

func (p NetworkProxySection) ResolvedEnabled() bool

ResolvedEnabled returns false when Enabled is nil (absent from config).

func (NetworkProxySection) ResolvedImage

func (p NetworkProxySection) ResolvedImage() string

ResolvedImage returns the squid image to use for the gateway sidecar.

func (NetworkProxySection) ResolvedLog

func (p NetworkProxySection) ResolvedLog() bool

ResolvedLog returns true when Log is nil.

func (NetworkProxySection) ResolvedMode

func (p NetworkProxySection) ResolvedMode() string

ResolvedMode returns "allow" when Mode is empty (deny by default).

type NetworkSection

type NetworkSection struct {
	Proxy NetworkProxySection `toml:"proxy"`
}

NetworkSection holds [network] config.

type NixPackages

type NixPackages struct {
	Stable   []string `toml:"stable"`
	Unstable []string `toml:"unstable"`
	Edge     []string `toml:"edge"`
}

NixPackages holds [packages.nix] config: arbitrary nixpkgs packages from three channels matching the flake inputs in nixhome/flake.nix.

func ResolveNixChannels

func ResolveNixChannels(np NixPackages) (resolved NixPackages, overrides []string)

ResolveNixChannels drops a package from older channels when a newer one also lists it: listing a package in unstable or edge is a request for the newer version. overrides describes each such case, e.g. "uv from unstable (overrides stable)".

type NixSection

type NixSection struct {
	Image       string `toml:"image"`   // nix core image for thin builds; default: DefaultNixImage; env: DEVCELL_NIX_IMAGE
	NixhomePath string `toml:"nixhome"` // local nixhome path; overridden by DEVCELL_NIXHOME_PATH env
}

NixSection holds [nix] config for nix image and nixhome settings.

func (NixSection) ResolvedImage

func (n NixSection) ResolvedImage() string

ResolvedImage returns the effective nix image: env > toml > default. The result is always fully qualified (docker.io/ prefix) for Podman compatibility.

type OnePasswordSecrets

type OnePasswordSecrets struct {
	Documents []string `toml:"documents"` // 1Password document names to resolve via `op item get`
}

OnePasswordSecrets holds [secrets.onepassword] (alias [secrets.op]) config.

type OpSection

type OpSection struct {
	Documents []string `toml:"documents"` // 1Password document names to resolve via `op item get`
	Items     []string `toml:"items"`     // deprecated: use documents (kept for backwards compat)
}

OpSection holds the deprecated [op] config; [secrets.onepassword] merges into it.

func (OpSection) ResolvedDocuments

func (o OpSection) ResolvedDocuments() []string

ResolvedDocuments returns the merged list of documents + legacy items (deduped).

type PackagesSection

type PackagesSection struct {
	Node   map[string]string `toml:"node"`   // name → npm version or range; "*" = latest
	Python map[string]string `toml:"python"` // name → mise version: "latest", "0.6", "0.6.9"; "*" = latest
	Nix    NixPackages       `toml:"nix"`

	// Deprecated [packages.npm], merged into Node by mergePackagesNode.
	Npm map[string]string `toml:"npm" hm:"-"`
}

PackagesSection holds [packages] config for npm, python, and nix tools. Nix packages are built into the image; npm and python tools are installed by mise at container start (see MiseTools).

func (PackagesSection) MiseTools

func (p PackagesSection) MiseTools() string

MiseTools renders [packages.python] and [packages.node] as a mise [tools] table (pipx:<name>, one venv per tool; npm:<name>), sorted by key. The container writes it to a mise conf.d file and installs it at start. Returns "" when both tables are empty.

type Policy

type Policy interface {
	Label() string
	ForceProxy() bool
	DenyDirectInternet() bool
	DenyHostAccess() bool
	DenyPorts() bool
	DefaultPresets() []string
}

Policy is the engine-agnostic isolation contract. Every engine reads it to decide what to allow or deny. Engine-specific details are accessed via type assertion to DockerPolicy or VMPolicy.

func OpenPolicy

func OpenPolicy() Policy

func SolitaryPolicy

func SolitaryPolicy() Policy

type PortsSection

type PortsSection struct {
	Forward   []string `toml:"forward"`    // port mappings: "3000", "8080:3000"
	PublishIP string   `toml:"publish_ip"` // host interface for `docker run -p`; default "0.0.0.0". Applies to VNC, RDP, and all forward entries.
}

PortsSection holds [ports] config for port forwarding.

func (PortsSection) ResolvedPublishIP

func (p PortsSection) ResolvedPublishIP() string

ResolvedPublishIP returns the effective host IP for `docker run -p`. Defaults to "0.0.0.0" when unset so cells are reachable from other hosts regardless of dockerd's bind default (some Docker Desktop / rootless setups default to 127.0.0.1, which would silently break remote RDP/VNC). Override in TOML to bind a specific NIC or "127.0.0.1" for loopback-only.

type ReadOnlySymlinkError

type ReadOnlySymlinkError struct {
	Path   string
	Link   string // the first hop, what `readlink` prints
	Target string // the fully resolved file
}

ReadOnlySymlinkError is the ErrReadOnly for a path that is a symlink into a location that cannot be written: home-manager links ~/.config/devcell/devcell.toml into /nix/store, so the file cannot be rewritten in place on the host either. Target names the link's destination so the user can be pointed at the source that generates it.

func (*ReadOnlySymlinkError) Error

func (e *ReadOnlySymlinkError) Error() string

func (*ReadOnlySymlinkError) HomeManaged

func (e *ReadOnlySymlinkError) HomeManaged() bool

HomeManaged reports whether the link goes through a home-manager output in the nix store. home-manager links in two hops, first into <hash>-home-manager-files/ and from there to the per-file store path, so the fully resolved Target does not name home-manager; the first hop does.

func (*ReadOnlySymlinkError) Unwrap

func (e *ReadOnlySymlinkError) Unwrap() error

type SchemaOptions

type SchemaOptions struct {
	Version      string            // published version (release tag); empty means DefaultSchemaVersion
	Descriptions map[string]string // "StructName.FieldName" → text; see FieldComments
	Modules      []string          // module names from the home catalog, offered as completions
	Stacks       []string          // stack names from the home catalog, offered as completions
}

SchemaOptions carries the inputs JSONSchema cannot derive from CellConfig.

func (*SchemaOptions) LoadCatalog

func (o *SchemaOptions) LoadCatalog(dir string) error

LoadCatalog fills Modules and Stacks from a directory holding the published catalog (modules.json, stacks.json). A missing directory or file is not an error: the schema is still valid, just without completions.

type SecretsSection

type SecretsSection struct {
	OnePassword OnePasswordSecrets `toml:"onepassword"`
	Op          OnePasswordSecrets `toml:"op" hm:"-"` // alias for [secrets.onepassword]; TOML-only, not a nix option
}

SecretsSection holds [secrets.*] config, one subtable per secret provider.

type StealthSection

type StealthSection struct {
	Arch     string `toml:"arch"`
	Platform string `toml:"platform"`
}

StealthSection holds [stealth] config for browser fingerprint spoofing.

func (StealthSection) ResolvedArch

func (s StealthSection) ResolvedArch() string

ResolvedArch returns the stealth architecture: explicit > host-detected. Maps runtime.GOARCH to Chrome's getHighEntropyValues().architecture values.

func (StealthSection) ResolvedPlatform

func (s StealthSection) ResolvedPlatform() string

ResolvedPlatform returns the stealth platform: explicit > "Linux" default.

func (StealthSection) ResolvedUserAgent

func (s StealthSection) ResolvedUserAgent() string

ResolvedUserAgent builds a Chrome UA string matching the stealth identity.

type StringList

type StringList []string

StringList is a []string that TOML may spell as a list or as one comma-separated string: experimental = ["a", "b"] or experimental = "a,b".

func (*StringList) UnmarshalTOML

func (l *StringList) UnmarshalTOML(v any) error

UnmarshalTOML implements toml.Unmarshaler.

type ThemeSection

type ThemeSection struct {
	Name        string `toml:"name"`         // preset; default: "devcell" (cool tone)
	BarBG       string `toml:"bar_bg"`       // background of the bar between elements
	BarFG       string `toml:"bar_fg"`       // foreground of the bar between elements
	WorkspaceBG string `toml:"workspace_bg"` // workspace name element
	WorkspaceFG string `toml:"workspace_fg"`
	CellBG      string `toml:"cell_bg"` // cell name element (<project>-<cellID>)
	CellFG      string `toml:"cell_fg"`
	StatusBG    string `toml:"status_bg"` // status panel (clocks), right-aligned
	StatusFG    string `toml:"status_fg"`
	Accent      string `toml:"accent"`    // copy-mode selection and messages
	Separator   string `toml:"separator"` // between status panel blocks; default: " | "
}

ThemeSection holds [theme]: colours of the CELL-655 cage bar. name picks a preset (devcell, brand, nord, catppuccin-mocha, tokyo-night); every other key overrides one colour of that preset. The bar has three elements, each with its own colours: the workspace name, the cell name and the status panel (clocks). Colours are tmux colours: "#rrggbb", "colour0".."colour255", or a name such as "brightblue".

type VMPolicy

type VMPolicy interface {
	Policy
	RestrictNetwork() bool
	IsolatedVNet() bool
	PublishProxyPort() bool
}

VMPolicy extends Policy with hypervisor-specific isolation controls.

type VolumeMount

type VolumeMount struct {
	Mount string `toml:"mount"`
}

VolumeMount holds a single [[volumes]] entry or a [cell] volumes element.

func (VolumeMount) ContainerPath

func (v VolumeMount) ContainerPath() string

ContainerPath returns the container-side mount point with trailing slashes stripped so path comparisons work regardless of how the user wrote the path. For "host:container" or "host:container:mode" it returns "container". For shorthand (no colon) it returns the path itself (identity mount).

func (VolumeMount) Resolved

func (v VolumeMount) Resolved() string

Resolved returns the mount string in `host:container[:mode]` form, expanding the single-path shorthand where a colonless value means "mount this path at the same path inside the container".

Examples:

"/foo/bar"          → "/foo/bar:/foo/bar"
"/foo:/bar"         → "/foo:/bar"      (unchanged)
"/foo:/bar:ro"      → "/foo:/bar:ro"   (unchanged)

type WireguardEntry

type WireguardEntry struct {
	Name    string `toml:"name"`
	Enabled bool   `toml:"enabled"`
	Config  string `toml:"config"`
}

WireguardEntry holds one [[wireguard]] table-array entry.

Jump to

Keyboard shortcuts

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