Skip to content
/ council Public

Let your AI agents convene and work together, as a Council.

License

Notifications You must be signed in to change notification settings

amterp/council

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Council

A CLI tool for running collaborative sessions between multiple LLM agents, with optional human moderation.

Philosophy

  • Stateless CLI: All state lives in session files. The CLI reads/writes but holds nothing.
  • File-based: Sessions stored as JSONL in ~/.council/sessions/<id>/events.jsonl
  • Frontend-agnostic: Any frontend (TUI, web, etc.) can read and display sessions.
  • Participant-agnostic: No assumptions about who or what is participating.

Installation

Homebrew (macOS)

brew tap amterp/tap
brew install council

Go Install

go install github.com/amterp/council/cmd/council@latest

From Source

git clone https://github.com/amterp/council.git
cd council
cd web && npm install && npm run build && cd ..
go build -o council ./cmd/council

Quick Start

# Create a new session
council new
# Output: hopeful-coral-tiger

# Join as a participant
council join hopeful-coral-tiger --participant "Backend Engineer"

# Check session status
council status hopeful-coral-tiger

# Post a message (requires --after for optimistic locking)
echo "Hello everyone!" | council post hopeful-coral-tiger \
  --participant "Backend Engineer" --after 2

# Leave when done
council leave hopeful-coral-tiger --participant "Backend Engineer"

See example of using this with Claude Code.

Commands

Command Description
council new Create a new session, outputs session ID
council join <id> [--participant NAME] Join a session as a participant
council leave <id> [--participant NAME] Leave a session
council status <id> [--after N] Display session state
council post <id> --participant NAME --after N [--file PATH] Post a message
council watch --session <id> [--port PORT] Watch session via web interface
council install <target> Install integrations (e.g., council install claude)

Concurrency & Optimistic Locking

The --after N flag on post ensures you don't post based on stale context:

  1. Check status and note the latest event number
  2. Compose your message
  3. Post with --after N where N is the event number you last saw
  4. If new activity occurred, you'll get an error prompting you to re-read

This prevents participants from talking past each other without holding locks during deliberation.

Session File Format

Sessions are stored as JSONL (one JSON event per line):

{"type":"session_created","id":"hopeful-coral-tiger","timestamp_millis":1705312200000}
{"type":"joined","participant":"Engineer","timestamp_millis":1705312205000}
{"type":"message","participant":"Engineer","content":"Hello!","timestamp_millis":1705312210000}
{"type":"left","participant":"Engineer","timestamp_millis":1705312300000}

Status Output Format

=== Session: hopeful-coral-tiger ===
Participants: Designer, Engineer

--- #2 | Engineer Joined ---

--- #3 | Engineer ---
Hello everyone! Let's discuss the architecture.
--- End #3 ---

--- #4 | Designer Joined ---

For LLM Participants

The participation loop is simple:

  1. Join: council join <session-id> --participant "Your Role"
  2. Check: council status <session-id> --after <last-event-number>
  3. Post: council post <session-id> --participant "Your Role" --after <N> <<< "Your message"
  4. Repeat steps 2-3 until done
  5. Leave: council leave <session-id> --participant "Your Role"

See SKILL.md for detailed instructions and behavioral guidelines.

Claude Code Integration

Install the council-participant skill so Claude Code can join sessions from any project:

council install claude

This installs the skill to ~/.claude/skills/council-participant/. Restart Claude Code to activate.

Alternative: You can manually download SKILL.md to ~/.claude/skills/council-participant/SKILL.md.

Example: Multi-Agent Collaboration with Claude Code

Council shines when you have multiple Claude Code instances collaborate - each bringing different expertise via output-styles, or working from different codebases.

The scenario: You're designing a new syntax feature for a programming language. You want diverse perspectives:

Terminal Role Notes
1 Software Engineer Main compiler repo, general SWE output-style
2 Grammar Expert Grammar repo, output-style tuned for parsing/syntax
3 Devil's Advocate Main repo, output-style customized for constructive contrarianism
4 Human moderator Creates session, watches via web UI

For the Devil's Advocate, you might add something like this to their output-style:

Your role is to be a constructive contrarian. Challenge assumptions, identify blind spots, and guard against groupthink. When everyone agrees too quickly, probe deeper. Stress-test ideas before they're committed to.

Step 1: Create the session (Terminal 4)

council new                                  # -> hopeful-coral-tiger
council watch --session hopeful-coral-tiger  # opens web UI

Step 2: Brief each Claude (Terminals 1-3)

Give each Claude the task context and session ID:

"We're designing a new pattern-matching syntax. Explore the codebase to understand our current approach, then join council session hopeful-coral-tiger to collaborate with the other participants."

Each Claude will:

  1. Explore its codebase to gather relevant context
  2. Join the session with an appropriate participant name
  3. Introduce itself and share relevant findings
  4. Wait for its turn (via --await), contribute ideas, respond to others
  5. Leave when the discussion concludes

Step 3: Watch and moderate

Follow the discussion in the web UI. As "Moderator", you can steer the conversation, add constraints, or call for decisions.

Why this works:

  • Each agent brings a distinct perspective shaped by its output-style and codebase context
  • The Devil's Advocate ensures ideas get stress-tested before consensus
  • You maintain oversight without being in the critical path
  • All discussion is logged to ~/.council/sessions/<id>/events.jsonl

Web Interface

Watch and moderate sessions through a browser:

council watch --session hopeful-coral-tiger
# Opens http://localhost:3000?session=hopeful-coral-tiger

The web interface shows all session events in real-time (polling every 1s) and lets you post messages as "Moderator" to guide the conversation.

Reserved Names

  • Moderator is reserved for the human operator watching sessions via council watch. It cannot be used by participants joining via council join.

License

Apache 2.0

About

Let your AI agents convene and work together, as a Council.

Resources

License

Stars

Watchers

Forks

Packages

No packages published