Compare commits

..

1 Commits

Author SHA1 Message Date
didericis-claude 3997a0a721 docs(prd): add PRD 0049 — named/labelled agents
test / unit (pull_request) Successful in 39s
test / integration (pull_request) Successful in 53s
Draft PRD for prompting operators for a custom label and optional
ANSI color at agent launch time, storing both in metadata.json, and
surfacing the label (in color) in the dashboard's active-agents pane.

Closes #171
2026-06-03 21:38:38 -04:00
@@ -1,4 +1,4 @@
# PRD 0051: Named / Labelled Agents
# PRD 0049: Named / Labelled Agents
- **Status:** Draft
- **Author:** didericis
@@ -53,10 +53,9 @@ 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. `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.
7. `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
@@ -91,8 +90,8 @@ BottleSpec.label, BottleSpec.color
├─► docker/prepare.py → BottleMetadata.label / .color → metadata.json
└─► contrib/claude/agent_provider.py → claude.json {"name": label, "color": color}
(omitted when empty)
└─► agent_provider.py → claude.json {"name": label, "color": color}
(omitted when empty)
dashboard refresh
@@ -232,18 +231,8 @@ Both use `read_tty_line()` (already in `start.py`) for the read.
### Claude Code config injection
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:
In `agent_provider.py`, where `claude_config.write_text(...)` is called,
expand the JSON dict conditionally:
```python
payload = {
@@ -252,13 +241,17 @@ payload = {
"bypassPermissionsModeAccepted": True,
"projects": claude_projects,
}
if label:
payload["name"] = label
if color:
payload["color"] = color
if spec.label:
payload["name"] = spec.label
if spec.color:
payload["color"] = spec.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.
@@ -270,12 +263,8 @@ 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`.
- 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()`.
- `agent_provider.py` (or the plan object it reads): thread label/color through
to `claude.json` write.
- Smolmachines backend: parallel changes to metadata read/write and
`ActiveAgent` construction.
- No prompt changes; no UI changes. All existing behavior is identical.