refactor(dashboard): discover via docker compose ls #37

Merged
didericis merged 1 commits from chunk-5-dashboard into main 2026-05-26 00:24:44 -04:00
Owner

Summary

PRD 0018 chunk 5 (the last one). The dashboard's operator-edit verbs (routes edit, pipelock edit) enumerated running sidecars via docker ps --filter name=... prefix scans. Switch to docker compose ls-driven discovery so the dashboard, cleanup CLI, and launch step all agree on what's running.

Mechanics

claude_bottle/backend/docker/compose.py grows three shared helpers:

  • list_compose_projects(*, include_stopped=True) — the JSON parse that used to live in cleanup.py, now reusable.
  • slug_from_compose_project(project) — inverse of compose_project_name; returns "" for projects that don't start with the claude-bottle- prefix (defends against unrelated compose projects on the host).
  • list_active_slugs(*, include_stopped=False) — sugar for the common "what's running?" question.

cleanup.py drops its private _list_compose_projects + _PROJECT_PREFIX in favor of the shared ones; list_active simplifies to one compose ls call instead of two.

dashboard.py's _discover_sidecar_slugs becomes _discover_active_with_service: cross-references the active slug list with a label-filtered docker ps so only bottles whose given service container is actually up surface in the edit menu. Bottles without an egress sidecar (no bottle.egress.routes) no longer appear for routes edit.

Status

  • 426 unit tests pass (3 new for the slug ↔ project naming contract)
  • Manual probe with a fake compose project confirms both discover_egress_slugs and discover_pipelock_slugs return the expected slug
## Summary PRD 0018 chunk 5 (the last one). The dashboard's operator-edit verbs (`routes edit`, `pipelock edit`) enumerated running sidecars via `docker ps --filter name=...` prefix scans. Switch to `docker compose ls`-driven discovery so the dashboard, cleanup CLI, and launch step all agree on what's running. ## Mechanics **`claude_bottle/backend/docker/compose.py` grows three shared helpers:** - `list_compose_projects(*, include_stopped=True)` — the JSON parse that used to live in cleanup.py, now reusable. - `slug_from_compose_project(project)` — inverse of `compose_project_name`; returns `""` for projects that don't start with the `claude-bottle-` prefix (defends against unrelated compose projects on the host). - `list_active_slugs(*, include_stopped=False)` — sugar for the common "what's running?" question. **cleanup.py** drops its private `_list_compose_projects` + `_PROJECT_PREFIX` in favor of the shared ones; `list_active` simplifies to one `compose ls` call instead of two. **dashboard.py**'s `_discover_sidecar_slugs` becomes `_discover_active_with_service`: cross-references the active slug list with a label-filtered `docker ps` so only bottles whose given service container is actually up surface in the edit menu. Bottles without an egress sidecar (no `bottle.egress.routes`) no longer appear for `routes edit`. ## Status - 426 unit tests pass (3 new for the slug ↔ project naming contract) - Manual probe with a fake compose project confirms both `discover_egress_slugs` and `discover_pipelock_slugs` return the expected slug
didericis added 1 commit 2026-05-26 00:14:31 -04:00
refactor(dashboard): discover via docker compose ls
test / unit (pull_request) Successful in 17s
test / integration (pull_request) Successful in 1m8s
1fa3745832
PRD 0018 chunk 5. The dashboard's operator-edit verbs
(`routes edit`, `pipelock edit`) enumerated running sidecars
via `docker ps --filter name=...` prefix scans. Switch to
`docker compose ls`-based discovery so the dashboard, cleanup
CLI, and launch step all agree on what's running.

Mechanics:

  - `claude_bottle/backend/docker/compose.py` grows three shared
    helpers: `list_compose_projects` (the JSON parse moved out
    of cleanup), `slug_from_compose_project` (inverse of
    `compose_project_name`), and `list_active_slugs` (sugar over
    the first two for the common "what's running?" question).
  - cleanup.py drops its private `_list_compose_projects` +
    `_PROJECT_PREFIX` in favor of the shared ones; `list_active`
    simplifies (one compose-ls call, not two).
  - dashboard.py's `_discover_sidecar_slugs` becomes
    `_discover_active_with_service`: cross-references the active
    slug list with a label-filtered `docker ps` so only bottles
    whose given service container is actually up surface in the
    edit menu. Bottles without an egress sidecar (no
    bottle.egress.routes) no longer appear for `routes edit`.

3 new unit tests cover the slug ↔ compose-project naming
contract; manual probe with a fake compose project confirms
both `discover_egress_slugs` and `discover_pipelock_slugs`
return the expected slug.
didericis merged commit 6babfcc656 into main 2026-05-26 00:24:44 -04:00
Sign in to join this conversation.