@armstrng/council
v0.1.6
Published
Consensus-oriented CLI that asks Codex, Claude, and Gemini in parallel and synthesizes their answers.
Maintainers
Readme
council
council is a tiny CLI that asks multiple coding CLIs the same question and then synthesizes their answers into one final response.
Today it supports:
codexclaudegemini
If one of them is not installed, council skips it and keeps going.
Prerequisites
- Node
>=22 - At least one of
codex,claude, orgeminiinstalled locally - At least one installed CLI already authenticated in a normal terminal session
If every configured CLI is missing or unauthenticated, council can still run but it will return a failure result rather than a synthesized answer.
Why this exists
Agent CLIs are useful, but each one has different strengths, safety controls, and output conventions. council gives you one wrapper that:
- fans out a prompt to several tools in parallel
- keeps the primary interaction read-only by default
- synthesizes the responses with one final model
- supports human-friendly interactive output and automation-friendly headless output
Install
Install globally to get a council command on your PATH:
npm install -g @armstrng/council
council "How should I structure this TypeScript CLI?"Or run it directly without installing via npx:
npx @armstrng/council "How should I structure this TypeScript CLI?"The rest of this README uses the bare council command. If you prefer not to install globally, swap any example for npx @armstrng/council.
If you are developing from a git checkout instead of using the published npm package:
npm install
npm run build
./bin/council.js "How should I structure this TypeScript CLI?"Quick start
Ask all available tools and show the full council:
council "How should I structure this TypeScript CLI?"Ask only a subset:
council --no-gemini "Review this migration plan"Pick a specific summarizer:
council --summarizer claude "Compare these two designs"Run against another project directory:
council --cwd ../my-repo "Review the current architecture"Output modes
Interactive human output:
council "What is the cleanest implementation?"Summary-only output:
council --summary-only "What should we do?"Structured JSON:
council --json "Explain the bug" | jqStreaming JSONL events for automation:
council --json-stream "Compare these approaches"Headless automation mode:
council --headless "Summarize the tradeoffs"--headless suppresses the banner and progress UI and defaults to summary-only text unless you also request --json or --json-stream.
Interactive terminal behavior
In a real TTY, council uses a live dashboard:
- each member row updates in place instead of appending new lines
- running members show a live seconds counter
- completed members show a 2-line preview of their result
- press the number shown next to a row to expand or collapse the full result
- just start typing to ask a follow-up in the same session
- press
qorEscto exit the interactive view
Tool selection
Enable or disable members individually:
council --codex --claude --no-gemini "Review this plan"Or use an explicit member list:
council --members codex,gemini "Compare these responses"--members preserves the order you pass. If you later re-enable another member with a toggle such as --claude, it is appended after that explicit list.
Safe defaults
council intentionally runs the upstream tools in consultation-oriented modes:
codex:codex exec --skip-git-repo-check --sandbox read-only --ephemeralclaude:claude --bare -p --permission-mode plan --verbose --output-format stream-json --include-partial-messages --no-session-persistencegemini:gemini -p "" --skip-trust --approval-mode plan --output-format json
That keeps the default behavior closer to analysis than autonomous mutation.
Exit codes
0: at least one member responded and synthesis succeeded2: usage error3: no member produced a response4: synthesis failed after at least one member responded
Environment variables
COUNCIL_CODEX_BIN: override thecodexexecutable pathCOUNCIL_CLAUDE_BIN: override theclaudeexecutable pathCOUNCIL_GEMINI_BIN: override thegeminiexecutable path
Programmatic use
The package also exports a small JS API:
import { runCouncil } from '@armstrng/council';
const result = await runCouncil({
query: 'Compare these two implementation strategies'
});The package ships d.ts declarations for this API.
Development
Run the tests:
npm testBuild the distributable JS output:
npm run buildRun the TypeScript check:
npm run typecheckThe suite uses fake codex, claude, and gemini binaries, so it does not require real vendor CLIs or credentials.
Contributing
See CONTRIBUTING.md.
Releases
@armstrng/council releases are automated with release-please. The release workflow watches commits merged to main, updates CHANGELOG.md, bumps package.json, creates the GitHub release tag, and publishes the package from GitHub Actions.
Before the first automated publish, configure npm trusted publishing for the seeARMS/council repository and the .github/workflows/release-please.yml workflow.
