refactor(agent): use agent-neutral runtime names
Assisted-by: Codex
This commit is contained in:
@@ -62,7 +62,7 @@ The feature is **done** when all of the following ship:
|
||||
`Bottle`) plus a `bot_bottle/backend/docker/` subpackage
|
||||
containing the `DockerBottleBackend` implementation.
|
||||
- `DockerBottleBackend.launch(plan)` returns a context manager
|
||||
yielding a `Bottle` handle exposing `exec_claude(argv, *, tty=True)`,
|
||||
yielding a `Bottle` handle exposing `exec_agent(argv, *, tty=True)`,
|
||||
`cp_in(host, ctr)`, and teardown on context exit.
|
||||
- Every existing `subprocess.run(["docker", ...])` call in
|
||||
`cli/start.py`, `pipelock.py`, `network.py`, `ssh.py`, and
|
||||
@@ -205,7 +205,7 @@ and a Docker subpackage:
|
||||
- **`bot_bottle/cli/start.py`** — replace the inline docker
|
||||
orchestration with `backend = get_bottle_backend(); plan =
|
||||
backend.prepare(spec, stage_dir=...); with backend.launch(plan) as
|
||||
bottle: bottle.exec_claude(...)`. The y/N preflight is rendered by
|
||||
bottle: bottle.exec_agent(...)`. The y/N preflight is rendered by
|
||||
`plan.print(...)`.
|
||||
- **`bot_bottle/manifest.py`** — drop the `runtime` field from the
|
||||
Bottle dataclass and its validation. Existing manifests with
|
||||
|
||||
@@ -312,7 +312,7 @@ existing prefix scan as a fallback for one release.
|
||||
|
||||
2. **How does `claude` reach the agent's TTY?** Decided: keep
|
||||
today's `docker exec -it` model. Agent runs `sleep infinity`
|
||||
under compose; `DockerBottle.exec_claude` runs
|
||||
under compose; `DockerBottle.exec_agent` runs
|
||||
`docker exec -it bot-bottle-<slug> claude ...` exactly like
|
||||
today. Compose owns the lifecycle (so `compose logs` includes
|
||||
the agent's stdout, `compose down` tears it down), but the
|
||||
|
||||
@@ -154,7 +154,7 @@ Today's flow:
|
||||
```
|
||||
./cli.py start agent
|
||||
└─ with backend.launch(plan) as bottle: ← bottle alive while inside `with`
|
||||
bottle.exec_claude([...], tty=True) ← blocks until claude exits
|
||||
bottle.exec_agent([...], tty=True) ← blocks until claude exits
|
||||
# context exits → compose down → state cleanup
|
||||
```
|
||||
|
||||
@@ -171,7 +171,7 @@ The proposed dashboard-driven flow:
|
||||
|
||||
# operator interacts via:
|
||||
curses.endwin()
|
||||
bottle.exec_claude([...], tty=True) ← blocks; returns on Ctrl-D
|
||||
bottle.exec_agent([...], tty=True) ← blocks; returns on Ctrl-D
|
||||
stdscr.refresh()
|
||||
# bottle is STILL ALIVE — only the claude process exited
|
||||
|
||||
@@ -265,7 +265,7 @@ if modal proves fiddly.
|
||||
Same handoff pattern the new-agent flow uses. For an agent the
|
||||
dashboard started this session, the dashboard holds the
|
||||
`DockerBottle` handle in its `bottles` dict and calls
|
||||
`bottle.exec_claude(...)`. For an agent it discovered via
|
||||
`bottle.exec_agent(...)`. For an agent it discovered via
|
||||
`list_active_slugs` (previous-dashboard or external start),
|
||||
the dashboard synthesizes a one-shot `DockerBottle` from the
|
||||
slug — container name is `bot-bottle-<slug>`, no prompt
|
||||
@@ -304,17 +304,17 @@ acting surface, not a lifetime owner.
|
||||
|
||||
Sized for one PR each.
|
||||
|
||||
1. **Refactor `_launch_bottle` so the launch + exec_claude
|
||||
1. **Refactor `_launch_bottle` so the launch + exec_agent
|
||||
pieces are separable.** Today's `cli/start.py` runs both
|
||||
inside one function. Extract `prepare_with_preflight(spec,
|
||||
*, render_preflight, prompt_yes)` and `attach_claude(bottle,
|
||||
*, render_preflight, prompt_yes)` and `attach_agent(bottle,
|
||||
*, remote_control)`. The CLI's existing one-shot use binds
|
||||
them as before; the dashboard binds them with curses-aware
|
||||
render + prompt callables. No behavior change.
|
||||
2. **Agent picker modal + new-agent flow.** New key `n` opens
|
||||
the picker; `prepare_with_preflight` runs against the
|
||||
selected agent; on Y, `backend.launch(plan)` enters the
|
||||
dashboard's ExitStack; handoff invokes `attach_claude`.
|
||||
dashboard's ExitStack; handoff invokes `attach_agent`.
|
||||
3. **Re-attach via Enter on owned agents-pane row.** Looks up
|
||||
the slug in the dashboard's `bottles` map; if present →
|
||||
handoff; else → status-line hint pointing at `./cli.py
|
||||
@@ -390,7 +390,7 @@ Sized for one PR each.
|
||||
- PRD 0019 — active-agents pane + selection model (the
|
||||
agents-pane row the re-attach + stop verbs hook into)
|
||||
- `docs/research/claude-code-pane-in-dashboard.md` — option 1
|
||||
(handoff) is what `attach_claude` implements here; options 2
|
||||
(handoff) is what `attach_agent` implements here; options 2
|
||||
/ 3 are out of scope for this PRD
|
||||
- `bot_bottle/cli/start.py:_launch_bottle` — the function
|
||||
chunk 1 extracts the prepare + attach pieces out of
|
||||
|
||||
@@ -163,7 +163,7 @@ def _attach_in_tmux(bottle, slug, *, resume) -> str:
|
||||
|
||||
The non-tmux path is unchanged from PRD 0020 — `_attach_via_
|
||||
handoff` is what those two flows already do today (curses.
|
||||
endwin → attach_claude → stdscr.refresh).
|
||||
endwin → attach_agent → stdscr.refresh).
|
||||
|
||||
### Pane creation
|
||||
|
||||
@@ -230,10 +230,10 @@ def _tmux_pane_exists(pane_id) -> bool:
|
||||
|
||||
The tmux helpers need the full docker-exec argv for claude —
|
||||
specifically including the `--append-system-prompt-file <path>`
|
||||
flag that `DockerBottle.exec_claude` appends today when the
|
||||
bottle has a prompt path. Refactor: split `exec_claude` into a
|
||||
flag that `DockerBottle.exec_agent` appends today when the
|
||||
bottle has a prompt path. Refactor: split `exec_agent` into a
|
||||
pure `claude_docker_argv(args, *, tty)` that returns the argv
|
||||
and a thin `exec_claude` that calls `subprocess.run` on it.
|
||||
and a thin `exec_agent` that calls `subprocess.run` on it.
|
||||
Both the tmux path AND the existing foreground path use the
|
||||
same argv builder.
|
||||
|
||||
@@ -272,7 +272,7 @@ Three failure modes worth handling:
|
||||
Sized small.
|
||||
|
||||
1. **`claude_docker_argv` refactor.** Pure-ish split of
|
||||
`DockerBottle.exec_claude` so both foreground and tmux
|
||||
`DockerBottle.exec_agent` so both foreground and tmux
|
||||
paths build on the same argv. No behavior change for the
|
||||
existing tests.
|
||||
2. **tmux helpers + pane state.** Add `_in_tmux`,
|
||||
|
||||
@@ -176,7 +176,7 @@ bottle so the suite is ~15s wall-clock total instead of
|
||||
bottle: dev
|
||||
---
|
||||
|
||||
(no prompt — exec_claude isn't called)
|
||||
(no prompt — exec_agent isn't called)
|
||||
```
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -317,7 +317,7 @@ The feature is **done** when all of the following ship:
|
||||
bot_bottle/backend/smolmachines/
|
||||
__init__.py re-exports SmolmachinesBottleBackend
|
||||
backend.py SmolmachinesBottleBackend façade
|
||||
bottle.py SmolmachinesBottle (exec_claude / exec / cp_in / close)
|
||||
bottle.py SmolmachinesBottle (exec_agent / exec / cp_in / close)
|
||||
bottle_plan.py SmolmachinesBottlePlan + .print()
|
||||
bottle_cleanup_plan.py SmolmachinesBottleCleanupPlan
|
||||
prepare.py resolve_plan(spec, stage_dir, ...) -> SmolmachinesBottlePlan
|
||||
@@ -436,7 +436,7 @@ Three changes vs. the Docker backend:
|
||||
layer enforces it.
|
||||
3. Provisioning: CA install → prompt → skills → git → supervise
|
||||
config, each via `smolvm machine exec` / `smolvm machine cp`.
|
||||
4. Yield a `SmolmachinesBottle` whose `exec_claude` / `exec` /
|
||||
4. Yield a `SmolmachinesBottle` whose `exec_agent` / `exec` /
|
||||
`cp_in` all funnel through `smolvm machine exec` /
|
||||
`smolvm machine cp`.
|
||||
5. Teardown: stop and delete the VM → stop + remove the bundle
|
||||
|
||||
Reference in New Issue
Block a user