Documentation
¶
Overview ¶
Package cfg defines the TOML configuration schema for devcell projects and workspaces.
Index ¶
- Constants
- Variables
- func ApplyEnv(c *CellConfig, getenv func(string) string)
- func CatalogURLFor(version string) string
- func ConfigDrift(old, new CellConfig) string
- func ConfigHash(c CellConfig) string
- func ExpandPresets(names []string) ([]string, error)
- func FieldComments(src []byte) (map[string]string, error)
- func Getenv(name string) string
- func HMOptionsNix() string
- func JSONSchema(opts SchemaOptions) ([]byte, error)
- func NetworkProxyEnabled(c CellConfig) bool
- func QualifyImage(ref string) string
- func SchemaURLFor(version string) string
- func ValidateDefaultCommand(cmd string) error
- func ValidateModulesAgainstCatalog(userModules, catalogNames []string) error
- func ValidateNetworkProxy(c CellConfig) error
- func ValidateNixPackageNames(np NixPackages) error
- func ValidateNixPackages(np NixPackages) error
- func ValidateStack(stack string) error
- func ValidateWireguard(c CellConfig) error
- func WireguardEnabled(c CellConfig) bool
- type AwsSection
- type BuildSection
- type CellConfig
- func LoadFile(path string) (CellConfig, error)
- func LoadFromOS(configDir, cwd string) CellConfig
- func LoadFromOSWithDirs(configDir, cwd string) (CellConfig, error)
- func LoadLayered(globalPath string, getenv func(string) string, projectPaths ...string) (CellConfig, error)
- func Merge(global, project CellConfig) CellConfig
- type CellSection
- func (c CellSection) DescribeModulesSource() string
- func (c CellSection) FlakeEnabled() bool
- func (c CellSection) KVMExplicitlyDisabled() bool
- func (c CellSection) ResolvedBackground() bool
- func (c CellSection) ResolvedDefaultCommand() string
- func (c CellSection) ResolvedDockerSocket() bool
- func (c CellSection) ResolvedExperimental() []string
- func (c CellSection) ResolvedGUI() bool
- func (c CellSection) ResolvedHostname(computed string) string
- func (c CellSection) ResolvedKVM() bool
- func (c CellSection) ResolvedPerCellImage() bool
- func (c CellSection) ResolvedRegistry() string
- func (c CellSection) ResolvedStack() string
- func (c CellSection) ResolvedTartOCIImage() string
- func (c CellSection) ResolvedTartSSHHost() string
- func (c CellSection) ResolvedTartSSHKey() string
- func (c CellSection) ResolvedTartSSHPort() int
- func (c CellSection) ResolvedTartSSHUser() string
- func (c CellSection) ResolvedThin() bool
- func (c CellSection) ResolvedWinkitCPUs() int
- func (c CellSection) ResolvedWinkitMemoryGB() int
- func (c CellSection) ResolvedWinkitSSHPort() int
- func (c CellSection) ResolvedWinkitWindowsISO() string
- func (c CellSection) StackExplicit() bool
- func (c CellSection) StaleWarningEnabled() bool
- type DeprecatedUse
- type Deprecation
- type DockerPolicy
- type DockerSection
- type GUISection
- type GitSection
- type LLMModelsSection
- type LLMProvider
- type LLMSection
- type McpSection
- type MigrationChange
- type MigrationResult
- type MissingEnvError
- type NetworkProxySection
- type NetworkSection
- type NixPackages
- type NixSection
- type OnePasswordSecrets
- type OpSection
- type PackagesSection
- type Policy
- type PortsSection
- type ReadOnlySymlinkError
- type SchemaOptions
- type SecretsSection
- type StealthSection
- type StringList
- type ThemeSection
- type VMPolicy
- type VolumeMount
- type WireguardEntry
Constants ¶
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.
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.
const DefaultRegistry = "ghcr.io/devcell-sh/devcell"
DefaultRegistry is the default container registry for devcell images. Must match docker.DefaultRegistry.
const DefaultSchemaVersion = "v0.0.0"
DefaultSchemaVersion is the version published from main (unreleased).
const DefaultTartOCIImage = "ghcr.io/cirruslabs/macos-tahoe-base:latest"
DefaultTartOCIImage is the default macOS base image for tart VMs.
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 ¶
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.
var EmbeddedSchema []byte
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.
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 ¶
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 ¶
ExpandPresets expands a list of preset names into a deduplicated, sorted domain list. Returns an error if any preset name is unknown.
func FieldComments ¶
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 ¶
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 ¶
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 ¶
SchemaURLFor returns the published URL of the config schema for a version.
func ValidateDefaultCommand ¶
ValidateDefaultCommand checks that default_command is a known subcommand name. Empty is valid (no default, shows help).
func ValidateModulesAgainstCatalog ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.