# bridged configuration (example). Copy to bridged.yaml and adjust. # # bridged is the sole gateway between primary/worker Claude sessions and herdr. # It is NOT a Claude process and must never carry ANTHROPIC_BASE_URL. # REST + MCP listen address. Keep it on loopback — bridged is same-host in Stage-1. bind: host: 127.0.0.1 port: 8765 # herdr Unix socket. Omit to use the client default # (${HERDR_SOCKET_PATH:-~/.config/herdr/herdr.sock}). herdrSocket: ~/.config/herdr/herdr.sock # How worker sessions are spawned. Define one or more named profiles (backends) under # `workers`; each key is the profile name (also the ccs profile). `defaultWorker` picks # which one a no-argument spawn uses (bridge_spawn with no profile / POST /workers). # # Shared knobs (placement/workspace/tabLabel) can be repeated per profile; they usually match. # placement: tab → each worker lands in its OWN tab in a dedicated worker space (default). # Use `pane` for the legacy behaviour (split the focused tab). # mcpUrl → bridged mounts the bridge MCP (--mcp-config, inline) + reply charter # (--append-system-prompt) as launch flags; nothing is written to the profile. # tokenEnv → host env var holding the worker's auth token (value never stored in config); # omit for a backend that needs no token (e.g. a local ollama). # cwd → pin this profile's working directory (CB-112). Omit to inherit the primary's # cwd on an MCP spawn, else the daemon's cwd — never $HOME. See # docs/Worker-Startup-and-Trust.md. # Put `defaultMode: "auto"` in each ccs profile so the worker runs autonomously. workers: gx10: # ccs profile name (NOT a hostname) kind: claude-code # which adapter spawns this profile (default; may omit) baseUrl: http://gx01.gw:8000 # the vLLM host this profile targets (gx00.gw / gx01.gw) model: coder placement: tab workspace: bridged-workers tabLabel: "worker: {profile} #{n}" # {profile}/{model}/{n} substituted; {n} keeps sibling tabs distinct mcpUrl: http://127.0.0.1:8765/mcp tokenEnv: BRIDGED_WORKER_TOKEN argv: ["ccs", "gx10"] ollama: baseUrl: http://ollama.ltms.dev # local/self-hosted; usually no token placement: tab workspace: bridged-workers tabLabel: "worker: {profile} #{n}" mcpUrl: http://127.0.0.1:8765/mcp argv: ["ccs", "ollama"] # CB-402: a second coding-agent kind, proving the PeerLauncher SPI is provider-neutral. # opencode is provider-agnostic and uses NONE of Claude's private seams: no ANTHROPIC_BASE_URL / # SubscriptionGuard (so it needs no `guard` host entry), no --mcp-config / --append-system-prompt. # The bridge MCP + reply charter mount via a generated OPENCODE_CONFIG file, and the model is a # `provider/model` selector. Placement, tabs, cwd, and the readiness gate are shared with Claude. # opencode-gemini: # kind: opencode # model: google/gemini-2.5-pro # opencode `provider/model` selector, injected as `-m` # placement: tab # workspace: bridged-workers # tabLabel: "opencode: {model} #{n}" # mcpUrl: http://127.0.0.1:8765/mcp # argv: ["opencode"] defaultWorker: gx10 # Subscription boundary. A worker's base_url host MUST be one of these; the primary # must carry none. Every profile above must have its host listed here. guard: offSubscriptionHosts: - gx00.gw - gx01.gw - ollama.ltms.dev # Spawn-readiness gate (CB-306). The launcher blocks until the worker's herdr status is # injectable (IDLE/BLOCKED/DONE) or the timeout elapses. 0 disables the gate. # spawn_ready_timeout_ms: 20000 # spawn_ready_poll_ms: 300 # Session lifecycle limits (CB-303). All knobs are opt-in; omit or set to null to keep # the feature disabled. By default the daemon never reaps, caps, or drains sessions. # idleTtlSeconds → reap READY/DONE sessions idle longer than this (never BUSY/SPAWNING) # contextCap → force-release a session after this many delegated turns # drainTimeoutSeconds → seconds to wait for BUSY sessions on shutdown before forced teardown # lifecycle: # idleTtlSeconds: 300 # contextCap: 10 # drainTimeoutSeconds: 5 # Durable reply delivery (CB-307 Stage 2). OMIT this block entirely to keep the default # in-memory, soft-state reply inbox (late worker replies are held only until a daemon bounce). # Set a broker uri to swap in the AMQP-backed inbox: worker replies with no open send are held # on a durable per-target queue (agent..inbox) and survive a restart — the broker # redelivers anything the primary had not yet drained. Production default is LavinMQ; a stock # RabbitMQ speaks the same AMQP 0-9-1, so it is a URI-only swap. # uri → AMQP connection URI. No trailing slash ⇒ the default vhost "/"; an empty path ("/") # is vhost "" and will NOT connect. Encode a named vhost as .../%2Fmyvhost. # broker: # uri: amqp://guest:guest@127.0.0.1:5672