Skip to content

Add bbox agents import/export manifest files (#203)#215

Merged
JAORMX merged 4 commits into
mainfrom
add-agents-import-export-203
Jul 3, 2026
Merged

Add bbox agents import/export manifest files (#203)#215
JAORMX merged 4 commits into
mainfrom
add-agents-import-export-203

Conversation

@JAORMX

@JAORMX JAORMX commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Closes #203. Follow-up to #191 (epic); builds on the declarative custom-agent model from #200 (Phase 1) and the bbox agents add/init CLI from #210 (Phase 2).

What's new

  • bbox agents import <manifest> — reads a standalone agent manifest (a YAML file with a top-level name plus the same fields as an agents:<name> block), validates it with the existing ValidateCustomAgent, and appends it to the global config (~/.config/broodbox/config.yaml, or --config). Refuses to overwrite a built-in or an existing custom agent unless --force. Flags: --config, --force/-f, --json.
  • bbox agents export <name> — emits a standalone manifest to stdout for an existing custom agent. Refuses built-ins and unknown agents.

Manifest format

Same fields as an agents:<name> entry, with a top-level name:

# broodbox-agent.yaml
name: aider
image: ghcr.io/acme/aider-bbox:latest
command: ["aider"]
env_forward: [OPENAI_API_KEY]
env_required: [OPENAI_API_KEY]
mcp:
  mode: env
egress_profile: standard
egress_hosts:
  standard:
    - { name: api.openai.com, ports: [443] }

Design notes

  • Reuse, don't reinvent. import reuses ValidateCustomAgent + UpsertAgent + the buildAddReceipt/emitAddResult receipt infra from agents add — same validation, same comment-preserving write, same --force/--config/--json flags, same JSON receipt (with Command: "agents import" to distinguish it). The new code is CLI (cmd/bbox) + manifest file I/O (internal/infra/config) + a thin domain mapping (pkg/domain/config).
  • AgentManifest domain type (pkg/domain/config/manifest.go, pure) inlines AgentOverride + adds a top-level Name, so manifest fields exactly track the agents:<name> block with no second field list to drift.
  • LoadManifest/MarshalManifest (internal/infra/config/manifest.go) reuse configfile.ReadFile (size cap, regular-file check) and DecodeStrict (strict unknown-field checking) so a malformed or oversized manifest fails loudly rather than being silently dropped.
  • Env values never leave the host. export strips default_env (host-supplied values) before marshalling; only env names/patterns (env_forward, env_required) are emitted — consistent with agents inspect/doctor.
  • Round-trip is a no-op. export then import of the same agent reproduces equivalent fields (verified by test).
  • Custom agents remain global-only. import writes only to the global config, never a workspace .broodbox.yaml. Import paths are operator-supplied (like --config), so symlinks are accepted, matching the global config loader.
  • DDD layering respected. Manifest type in domain (no I/O), file I/O in infra, CLI in cmd/bbox.

Acceptance criteria — verified end to end

```
bbox agents import ./broodbox-agent.yaml && bbox agents doctor # PASS
bbox agents export # produces a manifest that re-imports cleanly
```

Tests

task fmt clean, task lint 0 issues, task test (race) all 34 packages pass. New tests cover: import end-to-end (import → doctor PASS), export → re-import round-trip, --force overwrite, built-in refusal, missing-name rejection, invalid-manifest rejection, strict unknown-field rejection, default_env value stripping on export, built-in/unknown export refusal, and the domain manifest struct's inline-field YAML round-trip.

Implements #203 (BYO agents Phase 4): lets a reusable agent definition
live as a standalone, shareable YAML manifest instead of only inline
under agents: in the global config.

- bbox agents import <manifest>: reads a standalone manifest (top-level
  name + the same fields as an agents:<name> block), validates it with
  the existing ValidateCustomAgent, and appends it to the global config.
  Reuses the agents add path: same UpsertAgent write (comment-preserving),
  --force/--config/--json flags, and JSON receipt (Command: agents
@JAORMX JAORMX requested a review from jhrozek July 3, 2026 05:54
jhrozek added 3 commits July 3, 2026 10:44
agents add checked --egress-profile and --mcp-authz-profile flag
values before calling ValidateCustomAgent, but agents import (and the
plain config loader) skipped those checks entirely, so a typo'd
profile name could be written to config and pass doctor. Move both
checks into the shared validator so add, import, doctor, and the
loader are all strict uniformly.
Cover the two gaps a review found: credentials.persist and settings
entries weren't exercised through export/import, and exporting
against a missing config file had no test locking in the "not
declared" error path.
Follows the same-commit precedent set by the two prior PRs that added
agent subcommands.
@jhrozek

jhrozek commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Ran a multi-agent review of this PR (architecture/DDD layering, security, Go code quality/tests, and docs sync) and pushed three follow-up commits addressing what came out of it:

896a166 — Validate egress and MCP authz profile names in ValidateCustomAgent
bbox agents add checked --egress-profile and --mcp-authz-profile flag values before ever calling ValidateCustomAgent, but bbox agents import (and the plain config loader) skipped those checks entirely. A manifest with egress_profile: bogus or mcp.authz.profile: totally-wrong would import cleanly and even pass bbox agents doctor, only failing later at VM start. Not a security hole — egress.Resolve/mcp.ResolveProfile already reject unknown profiles at runtime — but a confusing DX gap where add and import disagreed on the same input. Moved both checks into the shared ValidateCustomAgent gate so add, import, doctor, and the loader are all strict uniformly.

0b427ca — Round-trip test coverage for credentials/settings and missing-config export
The existing export/import tests only round-tripped image/command/env_forward/egress_hosts/mcp. Added a case covering credentials.persist and settings entries (the two fields validated by safeRelPath, so worth locking down explicitly), plus a test for bbox agents export against a nonexistent --config path to pin down the "not declared" error message.

c6fa125 — Document import/export in CLAUDE.md
The custom-agent management line still listed list|inspect|doctor|add|init; the two prior PRs that added agent subcommands each updated this line in the same commit, so this was a doc-sync gap against that precedent.

Everything else in the review came back clean — domain purity, secret handling on export (only default_env is stripped, correctly the only field with host secret values), workspace-isolation on export, and the DDD layer boundaries all checked out. task fmt && task lint && task test pass on the full suite.

@JAORMX JAORMX merged commit fed340c into main Jul 3, 2026
8 checks passed
@JAORMX JAORMX deleted the add-agents-import-export-203 branch July 3, 2026 09:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BYO agents Phase 4: bbox agents import / export manifest files

2 participants