Compare commits

..

1 Commits

Author SHA1 Message Date
didericis-claude 0cc9a0d24c docs(prd): add PRD 0051 (named/labelled agents, renumbered from 0049)
test / unit (pull_request) Successful in 35s
test / integration (pull_request) Successful in 43s
2026-06-04 01:46:57 +00:00
@@ -1,4 +1,4 @@
# PRD 0049: Named / Labelled Agents
# PRD 0051: Named / Labelled Agents
- **Status:** Draft
- **Author:** didericis
@@ -53,9 +53,10 @@ which breaks the moment they switch windows.
label substring is rendered in that color.
6. `BottleSpec` carries `label` and `color`; the docker backend's `prepare`
step copies them into `BottleMetadata`.
7. `agent_provider.py` writes `label``"name"` and `color``"color"` into
the generated `claude.json`, alongside the existing fields. Fields are
omitted when empty.
7. `ClaudeAgentProvider.provision_plan()` in
`bot_bottle/contrib/claude/agent_provider.py` writes `label``"name"` and
`color``"color"` into the generated `claude.json`, alongside the existing
fields. Fields are omitted when empty.
8. The dashboard's `_new_agent_flow` (PRD 0020) includes the label+color step
between agent selection and the backend picker.
9. `cmd_start` (CLI) includes the label+color step after argument validation
@@ -90,8 +91,8 @@ BottleSpec.label, BottleSpec.color
├─► docker/prepare.py → BottleMetadata.label / .color → metadata.json
└─► agent_provider.py → claude.json {"name": label, "color": color}
(omitted when empty)
└─► contrib/claude/agent_provider.py → claude.json {"name": label, "color": color}
(omitted when empty)
dashboard refresh
@@ -231,8 +232,18 @@ Both use `read_tty_line()` (already in `start.py`) for the read.
### Claude Code config injection
In `agent_provider.py`, where `claude_config.write_text(...)` is called,
expand the JSON dict conditionally:
Per PRD 0050, the `claude.json` trust-marker file is written by
`ClaudeAgentProvider.provision_plan()` in
`bot_bottle/contrib/claude/agent_provider.py`. Add `label: str = ""` and
`color: str = ""` keyword parameters to `provision_plan()` on both the
`AgentProvider` ABC and `ClaudeAgentProvider`, and to the
`agent_provision_plan()` shim in `agent_provider.py`. The docker and
smolmachines `prepare.py` modules pass `spec.label` / `spec.color` when
calling `agent_provision_plan()`; other providers accept the params and ignore
them.
In `ClaudeAgentProvider.provision_plan()`, expand the JSON payload
conditionally:
```python
payload = {
@@ -241,17 +252,13 @@ payload = {
"bypassPermissionsModeAccepted": True,
"projects": claude_projects,
}
if spec.label:
payload["name"] = spec.label
if spec.color:
payload["color"] = spec.color
if label:
payload["name"] = label
if color:
payload["color"] = color
claude_config.write_text(json.dumps(payload, indent=2) + "\n")
```
`spec` here is the `AgentProvisionSpec` (or equivalent) that `agent_provider`
already receives; it needs `label` and `color` threaded in from `BottleSpec`
through whatever plan/provision object the provider operates on.
## Implementation chunks
Two PRs, each independently mergeable.
@@ -263,8 +270,12 @@ Two PRs, each independently mergeable.
- `docker/prepare.py`: copy `spec.label` / `spec.color` into `BottleMetadata`.
- `docker/enumerate.py`: copy `metadata.label` / `metadata.color` into
`ActiveAgent`.
- `agent_provider.py` (or the plan object it reads): thread label/color through
to `claude.json` write.
- Add `label: str = ""` and `color: str = ""` keyword params to
`AgentProvider.provision_plan()` (ABC), `ClaudeAgentProvider.provision_plan()`
(uses them in the `claude.json` write), and the `agent_provision_plan()` shim.
Other providers (`CodexAgentProvider`) accept the params and ignore them.
- `docker/prepare.py` and `smolmachines/prepare.py`: pass `spec.label` /
`spec.color` to `agent_provision_plan()`.
- Smolmachines backend: parallel changes to metadata read/write and
`ActiveAgent` construction.
- No prompt changes; no UI changes. All existing behavior is identical.