From 236c4fa50cd64715c9b25dd476d04e785491bb8a Mon Sep 17 00:00:00 2001 From: didericis Date: Sun, 10 May 2026 22:40:19 -0400 Subject: [PATCH] refactor(bottles): rename DockerBottleSpec to BottleSpec MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The spec is intent-only and platform-agnostic — only the plan carries Docker-specific fields. Drop the 'Docker' prefix and re-export from claude_bottle.bottles so callers see it as cross-platform. --- claude_bottle/bottles/__init__.py | 4 +++- claude_bottle/bottles/docker.py | 13 +++++++------ claude_bottle/cli/start.py | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/claude_bottle/bottles/__init__.py b/claude_bottle/bottles/__init__.py index 0654ed2..bc8203e 100644 --- a/claude_bottle/bottles/__init__.py +++ b/claude_bottle/bottles/__init__.py @@ -25,7 +25,9 @@ from dataclasses import dataclass from typing import Callable, Protocol from ..log import die -from .docker import launch_docker_bottle, prepare_docker_bottle +from .docker import BottleSpec, launch_docker_bottle, prepare_docker_bottle + +__all__ = ["Bottle", "BottlePlatform", "BottleSpec", "get_bottle_platform"] class Bottle(Protocol): diff --git a/claude_bottle/bottles/docker.py b/claude_bottle/bottles/docker.py index 0a0b614..751b1c1 100644 --- a/claude_bottle/bottles/docker.py +++ b/claude_bottle/bottles/docker.py @@ -55,10 +55,11 @@ def runsc_available() -> bool: @dataclass(frozen=True) -class DockerBottleSpec: - """CLI-supplied inputs to the Docker factory. Small and intent-only; - everything else (image names, container name, scratch file paths, - runsc availability) is resolved by prepare_docker_bottle.""" +class BottleSpec: + """CLI-supplied intent. Platform-agnostic — each platform's prepare + step consumes it and produces its own platform-specific plan. + Resolved values (image names, container name, scratch paths, runsc + availability) live on the plan, not the spec.""" manifest: Manifest agent_name: str @@ -72,7 +73,7 @@ class DockerBottlePlan: """Output of prepare_docker_bottle. Frozen; the launch step consumes it without further resolution. show_plan reads from it directly.""" - spec: DockerBottleSpec + spec: BottleSpec slug: str container_name: str container_name_pinned: bool @@ -130,7 +131,7 @@ class _DockerBottle: # --- Prepare --------------------------------------------------------------- -def prepare_docker_bottle(spec: DockerBottleSpec, *, stage_dir: Path) -> DockerBottlePlan: +def prepare_docker_bottle(spec: BottleSpec, *, stage_dir: Path) -> DockerBottlePlan: """Resolve names, validate, write scratch files. No Docker resources are created; the only side effects are host-side files under stage_dir and a probe of `docker info`.""" diff --git a/claude_bottle/cli/start.py b/claude_bottle/cli/start.py index c63a3c9..8c7168c 100644 --- a/claude_bottle/cli/start.py +++ b/claude_bottle/cli/start.py @@ -11,8 +11,8 @@ import sys import tempfile from pathlib import Path -from ..bottles import get_bottle_platform -from ..bottles.docker import DockerBottlePlan, DockerBottleSpec +from ..bottles import BottleSpec, get_bottle_platform +from ..bottles.docker import DockerBottlePlan from ..log import info from ..manifest import Manifest from ._common import PROG, USER_CWD, read_tty_line @@ -72,7 +72,7 @@ def cmd_start(argv: list[str]) -> int: dry_run = args.dry_run or os.environ.get("CLAUDE_BOTTLE_DRY_RUN") == "1" manifest = Manifest.resolve(USER_CWD) - spec = DockerBottleSpec( + spec = BottleSpec( manifest=manifest, agent_name=args.name, copy_cwd=args.cwd,