refactor!: rename project to bot-bottle
Assisted-by: Codex
This commit is contained in:
@@ -7,7 +7,7 @@ an interactive claude session). Instead, this test stages the
|
||||
minimum the orchestrator interacts with:
|
||||
|
||||
- A lightweight `alpine:latest sleep infinity` container named
|
||||
`claude-bottle-<slug>` (matches the agent container name pattern)
|
||||
`bot-bottle-<slug>` (matches the agent container name pattern)
|
||||
on the per-bottle internal network.
|
||||
- A marker file under `/home/node/.claude/` so we can assert the
|
||||
transcript snapshot path actually transferred bytes.
|
||||
@@ -31,15 +31,15 @@ import time
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle import supervise
|
||||
from claude_bottle.backend.docker import bottle_state, capability_apply
|
||||
from claude_bottle.backend.docker.capability_apply import apply_capability_change
|
||||
from claude_bottle.backend.docker.network import (
|
||||
from bot_bottle import supervise
|
||||
from bot_bottle.backend.docker import bottle_state, capability_apply
|
||||
from bot_bottle.backend.docker.capability_apply import apply_capability_change
|
||||
from bot_bottle.backend.docker.network import (
|
||||
network_create_egress,
|
||||
network_create_internal,
|
||||
network_remove,
|
||||
)
|
||||
from claude_bottle.backend.docker.sidecar_bundle import (
|
||||
from bot_bottle.backend.docker.sidecar_bundle import (
|
||||
sidecar_bundle_container_name,
|
||||
)
|
||||
from tests._docker import skip_unless_docker
|
||||
@@ -61,21 +61,21 @@ class TestCapabilityApply(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.slug = f"cb-test-cap-{os.getpid()}-{int(time.time())}"
|
||||
self.agent_name = f"claude-bottle-{self.slug}"
|
||||
self.agent_name = f"bot-bottle-{self.slug}"
|
||||
self.sidecar_names: list[str] = []
|
||||
self.internal_net = ""
|
||||
self.egress_net = ""
|
||||
# Fake home so tests don't touch ~/.claude-bottle/.
|
||||
# Fake home so tests don't touch ~/.bot-bottle/.
|
||||
self._tmp = tempfile.TemporaryDirectory(prefix="cap-apply-int.")
|
||||
self._original_root = supervise.claude_bottle_root
|
||||
self._original_root = supervise.bot_bottle_root
|
||||
|
||||
def fake_root() -> Path:
|
||||
return Path(self._tmp.name) / ".claude-bottle"
|
||||
return Path(self._tmp.name) / ".bot-bottle"
|
||||
|
||||
supervise.claude_bottle_root = fake_root # type: ignore[assignment]
|
||||
supervise.bot_bottle_root = fake_root # type: ignore[assignment]
|
||||
|
||||
def tearDown(self):
|
||||
supervise.claude_bottle_root = self._original_root # type: ignore[assignment]
|
||||
supervise.bot_bottle_root = self._original_root # type: ignore[assignment]
|
||||
for name in [self.agent_name, *self.sidecar_names]:
|
||||
subprocess.run(
|
||||
["docker", "rm", "-f", name],
|
||||
|
||||
@@ -13,7 +13,7 @@ import os
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
from claude_bottle.backend.docker.network import (
|
||||
from bot_bottle.backend.docker.network import (
|
||||
network_create_egress,
|
||||
network_create_internal,
|
||||
network_remove,
|
||||
@@ -40,7 +40,7 @@ class TestOrphanCleanup(unittest.TestCase):
|
||||
|
||||
def test_remove_missing_is_noop(self):
|
||||
# Returning True == idempotent success.
|
||||
self.assertTrue(network_remove(f"claude-bottle-net-{self.slug}-does-not-exist"))
|
||||
self.assertTrue(network_remove(f"bot-bottle-net-{self.slug}-does-not-exist"))
|
||||
|
||||
@unittest.skipIf(
|
||||
os.environ.get("GITEA_ACTIONS") == "true",
|
||||
|
||||
@@ -20,7 +20,7 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from tests._docker import skip_unless_docker
|
||||
from tests.fixtures import fixture_minimal
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from tests._docker import skip_unless_docker
|
||||
from tests.fixtures import fixture_minimal
|
||||
|
||||
|
||||
@@ -26,29 +26,29 @@ import time
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend.docker.bottle_state import pipelock_state_dir
|
||||
from claude_bottle.backend.docker.network import (
|
||||
from bot_bottle.backend.docker.bottle_state import pipelock_state_dir
|
||||
from bot_bottle.backend.docker.network import (
|
||||
network_create_egress,
|
||||
network_create_internal,
|
||||
network_remove,
|
||||
)
|
||||
from claude_bottle.backend.docker.pipelock import (
|
||||
from bot_bottle.backend.docker.pipelock import (
|
||||
PIPELOCK_CA_CERT_IN_CONTAINER,
|
||||
PIPELOCK_CA_KEY_IN_CONTAINER,
|
||||
pipelock_tls_init,
|
||||
)
|
||||
from claude_bottle.pipelock import PipelockProxy
|
||||
from claude_bottle.backend.docker.pipelock_apply import (
|
||||
from bot_bottle.pipelock import PipelockProxy
|
||||
from bot_bottle.backend.docker.pipelock_apply import (
|
||||
PipelockApplyError,
|
||||
apply_allowlist_change,
|
||||
fetch_current_allowlist,
|
||||
fetch_current_yaml,
|
||||
)
|
||||
from claude_bottle.backend.docker.sidecar_bundle import (
|
||||
from bot_bottle.backend.docker.sidecar_bundle import (
|
||||
SIDECAR_BUNDLE_IMAGE,
|
||||
sidecar_bundle_container_name,
|
||||
)
|
||||
from claude_bottle.yaml_subset import parse_yaml_subset
|
||||
from bot_bottle.yaml_subset import parse_yaml_subset
|
||||
from tests._docker import skip_unless_docker
|
||||
from tests.fixtures import fixture_minimal
|
||||
|
||||
@@ -77,7 +77,7 @@ class TestPipelockApply(unittest.TestCase):
|
||||
if n:
|
||||
network_remove(n)
|
||||
shutil.rmtree(self.work_dir, ignore_errors=True)
|
||||
# Clean up the per-slug state dir under ~/.claude-bottle/state/
|
||||
# Clean up the per-slug state dir under ~/.bot-bottle/state/
|
||||
# (apply_allowlist_change writes there; _bring_up calls
|
||||
# proxy.prepare with the same path so the bind-mount and the
|
||||
# hot-reload write target stay coherent).
|
||||
@@ -123,7 +123,7 @@ class TestPipelockApply(unittest.TestCase):
|
||||
["docker", "create",
|
||||
"--name", self.sidecar_name,
|
||||
"--network", self.internal_net,
|
||||
"-e", "CLAUDE_BOTTLE_SIDECAR_DAEMONS=pipelock",
|
||||
"-e", "BOT_BOTTLE_SIDECAR_DAEMONS=pipelock",
|
||||
"-v", f"{prep.yaml_path}:/etc/pipelock.yaml:ro",
|
||||
"-v", f"{ca_cert_host}:{PIPELOCK_CA_CERT_IN_CONTAINER}:ro",
|
||||
"-v", f"{ca_key_host}:{PIPELOCK_CA_KEY_IN_CONTAINER}:ro",
|
||||
|
||||
@@ -17,7 +17,7 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from tests._docker import skip_unless_docker
|
||||
from tests.fixtures import fixture_minimal
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ asserts each one is blocked:
|
||||
|
||||
The suite is backend-agnostic — it goes through `get_bottle_backend()`
|
||||
so a future smolmachines backend can be tested by setting
|
||||
`CLAUDE_BOTTLE_BACKEND=smolmachines` without touching this file.
|
||||
`BOT_BOTTLE_BACKEND=smolmachines` without touching this file.
|
||||
|
||||
PRD 0022 chunk 1 (this commit): fixture + setUpClass +
|
||||
tearDownClass + preflight tool check. Attack tests land in
|
||||
@@ -28,9 +28,9 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.backend.docker.bottle_state import cleanup_state
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.backend.docker.bottle_state import cleanup_state
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
@@ -78,16 +78,16 @@ class TestSandboxEscape(unittest.TestCase):
|
||||
# already covers that. Smolmachines additionally needs smolvm on
|
||||
# PATH and is macOS-only in v1 (libkrun/TSI). Skip cleanly when
|
||||
# those are missing rather than die-ing inside backend.prepare.
|
||||
backend_name = os.environ.get("CLAUDE_BOTTLE_BACKEND", "docker")
|
||||
backend_name = os.environ.get("BOT_BOTTLE_BACKEND", "docker")
|
||||
if backend_name == "smolmachines":
|
||||
if sys.platform != "darwin":
|
||||
raise unittest.SkipTest(
|
||||
"CLAUDE_BOTTLE_BACKEND=smolmachines is macOS-only in "
|
||||
"BOT_BOTTLE_BACKEND=smolmachines is macOS-only in "
|
||||
"v1 (libkrun TSI)"
|
||||
)
|
||||
if shutil.which("smolvm") is None:
|
||||
raise unittest.SkipTest(
|
||||
"CLAUDE_BOTTLE_BACKEND=smolmachines requires `smolvm` "
|
||||
"BOT_BOTTLE_BACKEND=smolmachines requires `smolvm` "
|
||||
"on PATH: curl -sSL https://smolmachines.com/install.sh | sh"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Integration: end-to-end smoke for the PRD 0024 bundle shape.
|
||||
|
||||
Verifies that flipping `CLAUDE_BOTTLE_SIDECAR_BUNDLE=1` produces a
|
||||
Verifies that flipping `BOT_BOTTLE_SIDECAR_BUNDLE=1` produces a
|
||||
working bottle: `docker compose up` brings the agent + bundle pair
|
||||
online, the four daemons inside the bundle bind their ports, and
|
||||
the agent can reach pipelock + supervise via the bundle's network
|
||||
@@ -21,8 +21,8 @@ import unittest
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class TestSidecarBundleCompose(unittest.TestCase):
|
||||
def test_bottle_up_with_bundle_flag_on(self):
|
||||
stage_dir = Path(tempfile.mkdtemp(prefix="cb-bundle-smoke."))
|
||||
try:
|
||||
with patch.dict(os.environ, {"CLAUDE_BOTTLE_SIDECAR_BUNDLE": "1"}):
|
||||
with patch.dict(os.environ, {"BOT_BOTTLE_SIDECAR_BUNDLE": "1"}):
|
||||
backend = get_bottle_backend()
|
||||
spec = BottleSpec(
|
||||
manifest=_manifest(),
|
||||
|
||||
@@ -28,7 +28,7 @@ import unittest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
_IMAGE = "claude-bottle-sidecars-test:chunk1"
|
||||
_IMAGE = "bot-bottle-sidecars-test:chunk1"
|
||||
_DOCKERFILE = "Dockerfile.sidecars"
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ class TestSidecarBundleImage(unittest.TestCase):
|
||||
# ENTRYPOINT wiring works.
|
||||
proc = subprocess.run(
|
||||
["docker", "run", "--rm",
|
||||
"-e", "CLAUDE_BOTTLE_SIDECAR_DAEMONS=nothing",
|
||||
"-e", "BOT_BOTTLE_SIDECAR_DAEMONS=nothing",
|
||||
_IMAGE],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
timeout=10.0,
|
||||
|
||||
@@ -18,7 +18,7 @@ import subprocess
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from claude_bottle.backend.smolmachines.sidecar_bundle import (
|
||||
from bot_bottle.backend.smolmachines.sidecar_bundle import (
|
||||
BundleLaunchSpec,
|
||||
bundle_container_name,
|
||||
bundle_network_name,
|
||||
@@ -47,13 +47,13 @@ class TestBundleBringup(unittest.TestCase):
|
||||
remove_bundle_network(self.network)
|
||||
|
||||
def _bundle_image_built(self) -> bool:
|
||||
"""The bundle image (`claude-bottle-sidecars:latest`) is
|
||||
"""The bundle image (`bot-bottle-sidecars:latest`) is
|
||||
built lazily by the docker backend's compose. If a
|
||||
smolmachines-only operator hasn't run the docker backend
|
||||
first, the image won't exist locally. Skip rather than
|
||||
fail."""
|
||||
r = subprocess.run(
|
||||
["docker", "image", "inspect", "claude-bottle-sidecars:latest"],
|
||||
["docker", "image", "inspect", "bot-bottle-sidecars:latest"],
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
@@ -62,7 +62,7 @@ class TestBundleBringup(unittest.TestCase):
|
||||
def test_create_network_then_start_bundle_pins_ip(self):
|
||||
if not self._bundle_image_built():
|
||||
self.skipTest(
|
||||
"claude-bottle-sidecars:latest not built; run a docker "
|
||||
"bot-bottle-sidecars:latest not built; run a docker "
|
||||
"bottle first or `docker build -f Dockerfile.sidecars .`"
|
||||
)
|
||||
|
||||
@@ -85,7 +85,7 @@ class TestBundleBringup(unittest.TestCase):
|
||||
# Only run the pipelock daemon for this smoke — it's
|
||||
# the lightest of the four and doesn't need bind
|
||||
# mounts beyond what we'd skip without
|
||||
# CLAUDE_BOTTLE_SIDECAR_DAEMONS. (The init
|
||||
# BOT_BOTTLE_SIDECAR_DAEMONS. (The init
|
||||
# supervisor will exit if pipelock fails to find its
|
||||
# yaml — that's expected here; we just need the
|
||||
# container to land on the network at the right IP.)
|
||||
|
||||
@@ -32,9 +32,9 @@ import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from claude_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from claude_bottle.backend.smolmachines.smolvm import is_available as _smolvm_available
|
||||
from claude_bottle.manifest import Manifest
|
||||
from bot_bottle.backend import BottleSpec, get_bottle_backend
|
||||
from bot_bottle.backend.smolmachines.smolvm import is_available as _smolvm_available
|
||||
from bot_bottle.manifest import Manifest
|
||||
from tests._docker import skip_unless_docker
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class TestSmolmachinesLaunch(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.stage = Path(tempfile.mkdtemp(prefix="cb-smol-launch."))
|
||||
os.environ["CLAUDE_BOTTLE_BACKEND"] = "smolmachines"
|
||||
os.environ["BOT_BOTTLE_BACKEND"] = "smolmachines"
|
||||
backend = get_bottle_backend()
|
||||
spec = BottleSpec(
|
||||
manifest=_minimal_manifest(),
|
||||
@@ -94,7 +94,7 @@ class TestSmolmachinesLaunch(unittest.TestCase):
|
||||
cls._launch.__exit__(None, None, None)
|
||||
finally:
|
||||
shutil.rmtree(cls.stage, ignore_errors=True)
|
||||
os.environ.pop("CLAUDE_BOTTLE_BACKEND", None)
|
||||
os.environ.pop("BOT_BOTTLE_BACKEND", None)
|
||||
|
||||
def test_smoke_exec_echo(self):
|
||||
# The plumbing-verifies-end-to-end smoke: a shell command
|
||||
@@ -152,10 +152,10 @@ class TestSmolmachinesLaunch(unittest.TestCase):
|
||||
|
||||
def test_prompt_file_lands_in_guest(self):
|
||||
# provision_prompt copies the host-side prompt.txt into the
|
||||
# guest at /root/.claude-bottle-prompt.txt. The content
|
||||
# guest at /root/.bot-bottle-prompt.txt. The content
|
||||
# must match what the manifest declared so claude-code's
|
||||
# --append-system-prompt-file reads the right text.
|
||||
r = self.bottle.exec("cat /root/.claude-bottle-prompt.txt")
|
||||
r = self.bottle.exec("cat /root/.bot-bottle-prompt.txt")
|
||||
self.assertEqual(0, r.returncode, msg=r.stderr)
|
||||
self.assertEqual(_AGENT_PROMPT, r.stdout.rstrip("\n"))
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import platform
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
from claude_bottle.backend.smolmachines.smolvm import is_available
|
||||
from bot_bottle.backend.smolmachines.smolvm import is_available
|
||||
|
||||
|
||||
@unittest.skipIf(
|
||||
|
||||
Reference in New Issue
Block a user