Skip to content
Alexander Holbreich
Field Notes

Proper agent names with Beads

Table of Contents

Open Table of Contents

Why this is useful

Beads records who created, claimed, updated or closed an issue. By default this can be a bit too generic when several tools run on the same machine.

If I have Claude in one tmux pane, Codex in another, and maybe Pi somewhere else, I want the Beads history to show something better than just my Unix user. I want names like:

claude-blog-w0-p1
codex-blog-w0-p2
pi-blog-w1-p0

That makes it much easier to understand later who did what.

The trick is simple: set BEADS_ACTOR before starting the agent.

File structure

I keep the Beads actor helpers outside .bashrc and only source them from there:

~/.bashrc
~/.config/beads/actors.bash

Create the directory first:

mkdir -p ~/.config/beads

The actor helper script

Create ~/.config/beads/actors.bash:

cat > ~/.config/beads/actors.bash <<'EOF'
# >>> beads actors >>>
#
# Beads actor identity for humans and AI agents.
#
# Beads uses BEADS_ACTOR for the audit trail and claim ownership.
# These helpers give every agent process a useful actor name, especially
# when multiple agents run in different tmux panes or terminals.

# Human default. Plain bd commands use this unless overridden.
export BEADS_ACTOR=Alex

# Build a stable suffix for the current terminal context.
#
# In tmux:
#   session/window/pane, e.g. blog-w0-p2
#
# Outside tmux:
#   shell PID, e.g. pid-48231
_beads_actor_suffix() {
  if [[ -n "${TMUX:-}" ]] && command -v tmux >/dev/null 2>&1; then
    tmux display-message -p '#S-w#I-p#P' 2>/dev/null | tr -c '[:alnum:]_.-' '-'
  else
    printf 'pid-%s' "$$"
  fi
}

# Run an agent with a Beads actor identity.
#
# Arguments:
#   $1 = actor prefix, e.g. claude, codex, gemini, pi
#   $2 = command to execute, e.g. claude, codex, gemini, pi
#   remaining args are passed through to the command.
#
# Override example:
#   BEADS_AGENT_ACTOR=codex-reviewer codex-bd
_beads_run_agent() {
  local agent_name="$1"
  local command_name="$2"
  shift 2

  local actor="${BEADS_AGENT_ACTOR:-${agent_name}-$(_beads_actor_suffix)}"

  echo "Starting $command_name with BEADS_ACTOR=$actor" >&2
  BEADS_ACTOR="$actor" "$command_name" "$@"
}

claude-bd() {
  _beads_run_agent "claude" "claude" "$@"
}

codex-bd() {
  _beads_run_agent "codex" "codex" "$@"
}

gemini-bd() {
  _beads_run_agent "gemini" "gemini" "$@"
}

pi-bd() {
  _beads_run_agent "pi" "pi" "$@"
}

# Human role helpers.
#
# Useful when I want to run one bd command under a more specific role
# without changing the default shell identity.
developer-bd() {
  BEADS_ACTOR="developer-$(_beads_actor_suffix)" "$@"
}

maintainer-bd() {
  BEADS_ACTOR="maintainer-$(_beads_actor_suffix)" "$@"
}

human-bd() {
  BEADS_ACTOR="human-$(_beads_actor_suffix)" "$@"
}

# Debug helper.
beads-actor() {
  echo "BEADS_ACTOR=${BEADS_ACTOR:-}"
  echo "BEADS_AGENT_ACTOR=${BEADS_AGENT_ACTOR:-}"
  echo "computed suffix=$(_beads_actor_suffix)"
}
# <<< beads actors <<<
EOF

Source it from .bashrc

Add this block to ~/.bashrc, but only if it is not already there:

grep -q 'actors.bash' ~/.bashrc || cat >> ~/.bashrc <<'EOF'

# Beads actor helpers
if [[ -f "$HOME/.config/beads/actors.bash" ]]; then
  source "$HOME/.config/beads/actors.bash"
fi
EOF

Reload the shell:

source ~/.bashrc

Or just open a new terminal.

Usage

Start agents through the helper functions:

claude-bd
codex-bd
gemini-bd
pi-bd

Arguments are passed through, so this also works:

pi-bd --model claude-sonnet-4.5
codex-bd --help

Check the current actor setup:

beads-actor

Inside tmux, this should print a suffix based on the tmux session, window and pane. Outside tmux it falls back to the shell PID.

Manual actor names

Sometimes I want a more meaningful actor name for a specific session:

BEADS_AGENT_ACTOR=codex-reviewer codex-bd
BEADS_AGENT_ACTOR=claude-migration claude-bd
BEADS_AGENT_ACTOR=pi-docs pi-bd

That override is only used for that command.

Human roles

For one-off human commands:

developer-bd bd update <id> --claim
maintainer-bd bd close <id> --reason "Rejected"
human-bd bd create "Task" --description "..." --type task --priority 2

These helpers are intentionally boring. They just set BEADS_ACTOR and run the command.

What shows up in Beads

After using one of these wrappers, Beads history and ownership should use the computed actor. For example:

claude-bd
# inside Claude/pi/codex/etc.
bd update aholbreich-blog-123 --claim

The claim should now belong to something like:

claude-blog-w0-p1

instead of a generic local username.

zsh note

I use bash here. For zsh the idea is the same, but source the file from ~/.zshrc instead of ~/.bashrc:

if [[ -f "$HOME/.config/beads/actors.bash" ]]; then
  source "$HOME/.config/beads/actors.bash"
fi

The functions themselves should work in zsh too, but I keep the file named actors.bash because my primary shell setup is bash.

Small caveats

Feedback

I appreciate feedback to all of this. Maybe there is better way?


Share this post on: