Added
- applecontainer — new runtime backend targeting Apple's native
containerruntime on darwin/arm64. Containers are launched directly via a Swift bridge (ACBridge, exposed over a C ABI) and the bridge dylib is embedded into the Go binary anddlopen-ed at runtime, so callers get an Apple-native path without shelling out todocker. IncludesInspectandFindContainerByLabelparity with the docker backend. (#58, #59, #60, #62) - compose — runtime-agnostic compose orchestrator, opt-in via
EngineOptions.ComposeBackend = ComposeBackendNative. Drives compose entirely throughruntime.Runtimeprimitives, with no dependency on thedocker composev2 plugin, and works against backends that lack a Docker-API equivalent — notably the applecontainer runtime, which the orchestrator now drives end-to-end. The shell-out path remains the default; existing callers see no behavior change. (#64) - runtime —
RunSpec.MemoryBytesandRunSpec.NanoCPUslet callers size each container's resources. Maps toHostConfig.Memory/HostConfig.NanoCPUson docker, and toContainerConfiguration.resources.memoryInBytes/.cpuson applecontainer (sizing the per-container VM at boot — Apple takes whole CPUs, so fractional nano-cpus round up). The native compose orchestrator translatesdeploy.resources.limits.{memory,cpus}with the legacy top-levelmem_limit/cpusas fallback, matching docker compose's own precedence. (#68)
Fixed
- compose — preserve container state across docker daemon restarts. The shell-out path now passes
--no-recreatetodocker compose up -dwhen a container is already known for the workspace (mirroring the upstreamdevcontainers/cligate); the native orchestrator nowStartContainers a config-matched stopped container instead of stop+remove+recreating it. Both code paths were treating spurious config-hash drift (or a temporarily-stopped container left behind by a daemon restart) as a recreate signal, which destroyed the container's writable layer — taking~/.claude/projects/,~/.bash_history, install caches, and anything else in$HOMEwith it. (#71, #72) - applecontainer — named volume mounts now resolve to the volume's backing image path. The Swift bridge was treating
MountType=volumeas a virtiofs bind, and Apple's apiserver was resolving the source viaURL(fileURLWithPath:)against the launching process's CWD — yielding non-existent paths like/private/tmp/runner/<project>_<vol>anderrno 2at VM bootstrap. The bridge now callsClientVolume.inspect(name)to fetch the backing image path and constructs a properFilesystem.volume(...), matching apple/container's own CLI. (#67)
Full Changelog: v0.1.4...v0.2.0