ContainedCore is Contained's standalone backend/orchestration package. It
contains no SwiftUI, app state, Sparkle, SwiftTerm, app persistence, or
product-specific presentation policy.
Core.Orchestrator, the app-facing backend facade.Core.Runtimedescriptors, capabilities, runtime-scoped checks, and typed unsupported-operation errors.Core.Runtime.Module, the adapter contract used by built-in runtime modules to provide descriptors, CLI lookup, readiness, command previews, terminal invocations, schema support profiles, and runtime clients.Runtime/ModuleRegistry.swift, the shared default registry. Concrete adapter implementation files stay underRuntimes/<RuntimeName>/.Core.Containersemantic create/edit/import/export models.Core.Composeimport/export plans and Compose YAML parsing/writing internals.Core.Commandcommand previews, command execution, and host invocations.- Core-internal runtime adapters for Apple container and Docker CLI runtimes.
- Metrics, stats normalization, decoded resources, registry helpers, and display-neutral package errors.
- A separate
ContainedCoreFixturesproduct for deterministic semantic samples used by tests, previews, and sandbox-only targets.
- Product navigation, onboarding, toasts, alerts, and other app-owned copy.
- SwiftUI views, app routing, settings, stores, or Activity presentation.
- UI/UX packages, Sparkle, SwiftTerm, SwiftData, or app persistence.
ContainedCore may own display-neutral semantic localization for schema labels,
validation messages, runtime capability reasons, and typed package-error fallback
descriptions. Downstream consumers can override or wrap those strings; Contained
uses the Core-owned semantic strings directly because the app and package live in
the same repo.
import ContainedCore
let result = await Core.Orchestrator.bootstrap(
configuration: Core.Configuration(
runtimes: [
.appleContainer: .init(cliPathOverride: nil),
]
)
)
let core: Core.Orchestrator
switch result {
case .ready(let orchestrator, _):
core = orchestrator
case .cliMissing:
throw Core.Error.Command.cliNotFound(searched: ["PATH"])
}
let descriptors = core.availableRuntimeDescriptors
let containers = try await core.listRuntimeContainers(all: true)var document = Core.Schema.Document.containerCreate(runtimeKind: .appleContainer)
document.set(.containerName, .string("web"))
document.set(.imageReference, .string("nginx:latest"))
document.set(.networkPorts, .portList([.init(hostPort: "8080", containerPort: "80")]))
let preview = try core.previewCreateCommand(for: document)
let command = preview.commandContainer edits supply both the requested replacement and a document derived from the current runtime configuration:
let result = try await core.recreateContainer(
originalID: snapshot.id,
replacement: editedDocument,
rollback: .containerEdit(from: snapshot.configuration)
)Core validates both documents before deletion. If replacement creation fails
after the original was deleted, Core attempts the rollback and throws
Core.Container.RecreateFailure with its phase and recovery state.
let project = try Core.Compose.parse(composeText, projectName: "stack")
let plan = try core.translateCompose(project,
baseDirectory: composeDirectory,
runtimeKind: .appleContainer)
let documents = plan.items.map(\.document)Compose is a Core-level interchange format. Core.Compose.YAML is the only
place that imports Yams; no public Core API exposes Yams types.
Docker projection support exists for direct adapter tests and future provider
work, but the Docker module is not in the default registry yet.
Run/edit documents pass through Core.Schema.DocumentMigrator before validation
or execution. The migrator reads the selected runtime's schema descriptors,
maps descriptor-published legacy paths, coerces simple value-kind drift, and
leaves unresolved deviations as field-keyed validation issues.
let document = Core.Container.Document(
canonical: .init(createRequest: request)
)
let plan = try core.planMigration(document, to: .docker)
if !plan.isAvailable {
// The app maps the typed reason/context to localized Activity or alert copy.
}Core fixtures are available only by depending on the separate
ContainedCoreFixtures product. They are not linked by the normal app target or
distributable bundles.
import ContainedCore
import ContainedCoreFixtures
let container = Core.Fixtures.AppleContainer.webContainer
let history = Core.Fixtures.Generic.metricHistoryUse Core.Fixtures.AppleContainer.* for Apple-container-specific samples and
Core.Fixtures.Generic.* only for runtime-neutral values. App previews and UI
tests map these semantic samples into app-owned localization, presentation, and
view state.
swift build --package-path Packages/ContainedCore
swift test --package-path Packages/ContainedCore
swift build --package-path Packages/ContainedCore --product ContainedCoreFixtures