From dev-buddy
Conducts multi-AI competitive debates on dev topics by fanning out to configured models and Claude, synthesizing approaches iteratively until consensus or max rounds. Invoke via /dev-buddy-chatroom.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dev-buddy:dev-buddy-chatroomThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
---
Fan out a topic to ALL configured AIs + Claude simultaneously, synthesize the best approach, iterate until consensus.
Usage: /dev-buddy-chatroom <topic or question>
Config: ~/.vcp/dev-buddy-chatroom.json — use /dev-buddy-config web portal or edit manually.
Plan mode: This skill can run in plan mode. Participants are instructed to only read and analyze (not modify files), but this is prompt-level enforcement only — see Known Limitation #1. Use it to gather multi-AI perspectives before finalizing a plan.
Extract the user's topic from the arguments after the skill trigger.
Load and validate the chatroom config:
bun -e "
import { loadChatroomConfig } from '${CLAUDE_PLUGIN_ROOT}/scripts/chatroom-config.ts';
import { readPresets } from '${CLAUDE_PLUGIN_ROOT}/scripts/preset-utils.ts';
import { validateChatroomConfig } from '${CLAUDE_PLUGIN_ROOT}/scripts/chatroom-config.ts';
const config = loadChatroomConfig();
const presets = readPresets();
const err = validateChatroomConfig(config, presets);
if (err) { console.error('CONFIG ERROR: ' + err); process.exit(1); }
console.log(JSON.stringify({
participants: config.participants.map((p, i) => ({
index: i,
system_prompt: p.system_prompt || '',
preset: p.preset,
model: p.model,
type: presets.presets[p.preset]?.type || 'unknown',
timeout_ms: presets.presets[p.preset]?.timeout_ms
})),
max_rounds: config.max_rounds
}));
"
If config error or no participants: report error to user and stop.
Resolve session variables:
Resolve tmpdir:
bun -e "console.log(require('os').tmpdir())"
Store result as {TMPDIR}.
Compute project hash:
bun -e "const c=require('crypto');console.log(c.createHash('sha256').update(process.env.CLAUDE_PROJECT_DIR||process.cwd()).digest('hex').slice(0,8))"
Store result as {PROJHASH}.
Generate random suffix:
bun -e "console.log(require('crypto').randomBytes(2).toString('hex'))"
Store result as {RAND}.
Generate session ID: {PROJHASH}-{Date.now()}-{RAND} → store as {SESSION_ID}
Assign each participant a zero-based index: p0, p1, p2, ...
Ensure output directory exists:
mkdir -p "{TMPDIR}/.vcp/oneshot"
No startup cleanup — stale files from other sessions are harmless.
Display session info to user:
PARALLEL OK — dispatch all participants + generate Claude's position in a single message.
Generate a unique delimiter to prevent heredoc injection:
bun -e "console.log('VCPTASK_' + require('crypto').randomBytes(4).toString('hex'))"
Store result as {DELIM} (e.g., VCPTASK_a3f7b2c1).
For each participant that has a non-empty system_prompt field, resolve the content:
bun -e "
import { getSystemPrompt } from '${CLAUDE_PLUGIN_ROOT}/scripts/system-prompts.ts';
const prompt = getSystemPrompt('{SYSTEM_PROMPT}', '${CLAUDE_PLUGIN_ROOT}/system-prompts/built-in');
console.log(prompt ? prompt.content : '');
"
Store the resolved content for each participant. If the result is empty or the command fails, skip — the participant uses default behavior (no system prompt prepended).
For each participant at index {i}:
Output ID: cr-{SESSION_ID}-p{i}-r1
Opening prompt template:
If the participant has resolved system_prompt content (from Step 2a-bis), prepend it before the debate prompt:
{system_prompt_content}
---
You are a participant in a COMPETITIVE multi-AI debate. {participant_count} other AI systems will also respond. Your goal is to present the STRONGEST position and be prepared to defend it.
TOPIC:
{user_topic}
RESPOND WITH THESE SECTIONS:
**POSITION:** Your core recommendation in 2-3 sentences. Be specific — no fence-sitting.
**ARGUMENTS:** 3-5 key arguments supporting your position, each as a bullet point with concrete evidence or reasoning.
**ANTICIPATED OBJECTIONS:** 2-3 counter-arguments you expect and your preemptive rebuttals.
**BOTTOM LINE:** One sentence — why your approach wins over alternatives.
IMPORTANT: ONLY read and analyze. Do NOT modify any files. Do NOT use Write, Edit, or Bash tools to change anything.
If the participant has no system_prompt (empty or unresolved), use the prompt without the prefix:
You are a participant in a COMPETITIVE multi-AI debate. {participant_count} other AI systems will also respond. Your goal is to present the STRONGEST position and be prepared to defend it.
TOPIC:
{user_topic}
RESPOND WITH THESE SECTIONS:
**POSITION:** Your core recommendation in 2-3 sentences. Be specific — no fence-sitting.
**ARGUMENTS:** 3-5 key arguments supporting your position, each as a bullet point with concrete evidence or reasoning.
**ANTICIPATED OBJECTIONS:** 2-3 counter-arguments you expect and your preemptive rebuttals.
**BOTTOM LINE:** One sentence — why your approach wins over alternatives.
IMPORTANT: ONLY read and analyze. Do NOT modify any files. Do NOT use Write, Edit, or Bash tools to change anything.
Route by participant type:
Subscription: Task(subagent_type: "general-purpose", model: {model}, prompt: {prompt})
API: Bash(run_in_background: true) →
bun "${CLAUDE_PLUGIN_ROOT}/scripts/one-shot-runner.ts" \
--type api --output-id cr-{SESSION_ID}-p{i}-r1 \
--preset "{PRESET}" --model "{MODEL}" \
--cwd "${CLAUDE_PROJECT_DIR}" --task-stdin <<'{DELIM}'
{prompt_text}
{DELIM}
CLI: Bash(run_in_background: true) →
bun "${CLAUDE_PLUGIN_ROOT}/scripts/one-shot-runner.ts" \
--type cli --output-id cr-{SESSION_ID}-p{i}-r1 \
--preset "{PRESET}" --model "{MODEL}" \
--cwd "${CLAUDE_PROJECT_DIR}" --task-stdin <<'{DELIM}'
{prompt_text}
{DELIM}
While background tasks run, generate your own analysis of the topic inline. This is Claude's opening position in the debate.
CRITICAL: Poll background tasks ONE AT A TIME. Do NOT issue multiple TaskOutput calls in the same message — this causes sibling cascade failures.
Subscription participants: Result was returned directly from the Task call in Step 2. Already collected.
API/CLI participants: For each, sequentially:
Derive timeout: min(timeout_ms + 120000, 600000) where timeout_ms is the preset's configured timeout (default 300000 for API, 1200000 for CLI).
Poll for completion:
TaskOutput(task_id: "{id}", block: true, timeout: {computed_timeout})
If TaskOutput returns but task is still running, repeat:
TaskOutput(task_id: "{id}", block: true, timeout: 600000)
Keep repeating until the task completes.
Read the output file:
Read("{TMPDIR}/.vcp/oneshot/cr-{SESSION_ID}-p{i}-r{round}.json")
Parse the JSON. Extract the result field for successful responses. Note error field for failures.
CLI output normalization: Strip ANSI escape sequences (/\x1b\[[0-9;]*[a-zA-Z]/g pattern). The useful content may be mixed with banners or progress output.
Error handling:
Read ALL collected responses (Claude's own + all external participants).
Maintain a running ledger of each participant's state across rounds. After each round, record for each participant:
Also track disagreement resolution events (feeds Step 6 "Points Resolved During Debate"):
"{topic}: resolved in Round {N} — {participant} conceded to {participant}"For participants that failed or timed out this round:
This ledger feeds Steps 4b, 5, and 6. It is Claude's internal state — not sent to participants.
This is shown to the user inline. NOT sent to participants.
## Round {N} — Participant Positions
### Claude
**Core Position:** {2-3 sentence summary}
**Key Arguments:**
- {argument 1}
- {argument 2}
### {preset}/{model} (p0)
**Core Position:** {2-3 sentence summary}
**Key Arguments:**
- {argument 1}
- {argument 2}
### {preset}/{model} (p1) — NO RESPONSE (timeout)
*Carried forward from Round {N-1}: {previous position}*
{...repeat for all participants...}
---
### Conflict Matrix
| Point of Contention | Who Agrees | Who Disagrees |
|---------------------|-----------|---------------|
| {topic 1} | {list} | {list} |
| {topic 2} | {list} | {list} |
**Key Disagreements:**
1. {who} vs {who}: {1-sentence clash summary}
{...list ALL disagreements, not capped...}
**Areas of Universal Agreement:**
- {points all agree on}
Claude MUST generate an updated synthesis every round. This synthesis:
Present the synthesis to the user after the recap.
For rounds 2+, apply CLI output normalization (strip ANSI) and parse each response for verdict keywords:
AGREE — participant accepts the synthesisDISAGREE: <reason> — participant rejects with specific reasonPARTIAL: <accepted> / <contested> — partial agreementConsensus is evaluated only among ACTIVE participants (those who responded this round). ABSENT participants (timed out / errored) are excluded from the consensus count but noted in the final output.
Generate a new heredoc delimiter (same method as Step 2a).
Adversarial debate prompt template:
If the participant has resolved system_prompt content (from Step 2a-bis), prepend it before the debate prompt:
{system_prompt_content}
---
MULTI-AI DEBATE — Round {N}
ORIGINAL TOPIC:
{user_topic}
YOUR PREVIOUS POSITION (Round {N-1}):
{this_participant_position_and_arguments_from_ledger}
---
OTHER PARTICIPANTS' POSITIONS (Round {N-1}):
**NOTE: Showing the most divergent positions. {total_participant_count} total participants.**
**Claude:**
Position: {summary}
Arguments:
- {arg 1}
- {arg 2}
**{preset}/{model} (p{i}):**
Position: {summary}
Arguments:
- {arg 1}
- {arg 2}
{...show up to 4 most divergent participants, not all...}
**Participants aligned with synthesis (not shown in detail):**
- {list any participants who AGREED last round}
---
CURRENT SYNTHESIS (from debate moderator):
{claude_synthesis}
UNRESOLVED DISAGREEMENTS:
1. {participant_A} vs {participant_B}: {clash description} — {1-sentence summary of each side}
2. {participant_C} vs {participant_D}: {clash description} — {1-sentence summary of each side}
{...ALL disagreements, each with participant names and both sides summarized so you can rebut even if the participant's full position is not shown above...}
---
YOUR TASK — respond with ALL sections:
1. **CRITIQUES** — For each disagreement above where you have a view, identify the weakest argument from the opposing side. Name the participant, reference their specific claim, explain why it fails.
2. **DEFENSE** — Address the strongest critique of YOUR position from last round. Concede valid points or explain why they don't apply.
3. **UPDATED POSITION** — Restate your position with any concessions or refinements. If unchanged, explain why others failed to persuade you.
4. **VERDICT:** — One of:
- AGREE — you accept the current synthesis
- DISAGREE: <specific objection and what must change>
- PARTIAL: <what you accept> / <what you contest>
IMPORTANT: ONLY read and analyze. Do NOT modify any files.
If the participant has no system_prompt (empty or unresolved), use the prompt without the {system_prompt_content} prefix (same content starting from "MULTI-AI DEBATE — Round {N}").
Scaling rules (participant positions only — disagreements are NOT capped):
Claude's own round N response: While background tasks run, Claude also produces its own response following the same 4-section structure (CRITIQUES, DEFENSE, UPDATED POSITION, VERDICT) inline.
Dispatch to all participants using the same pattern as Step 2b (parallel fan-out with run_in_background: true).
Output ID for round N: cr-{SESSION_ID}-p{i}-rN
Collect responses using the same sequential pattern as Step 3.
Return to Step 4 with the new responses.
Use the participant ledger built in Step 4a to generate position evolution.
If consensus reached:
## Consensus Reached (Round {N}/{max_rounds})
### Final Synthesis
{final_synthesis}
### Position Evolution
**Claude:**
- Round 1: {original position from ledger}
- Final: {final position from ledger}
- Key Concessions: {from ledger, or "None — held firm"}
**{preset}/{model} (p0):**
- Round 1: {original position from ledger}
- Final: {final position from ledger}
- Key Concessions: {from ledger}
**{preset}/{model} (p2) — ABSENT (timed out Round 3)**
- Round 1: {position}
- Last known: Round 2 — {position}
{...all participants from ledger...}
### Consensus Votes
- Claude: AGREE
- {preset}/{model} (p0): AGREE
- {preset}/{model} (p2): ABSENT
If max rounds exhausted without full consensus:
## Debate Complete — No Full Consensus (Round {max_rounds}/{max_rounds})
### Best Synthesis
{final_synthesis}
### Position Evolution
{same format as above, include Final Verdict per participant from ledger}
### Remaining Disagreements
- {participant}: {their specific objection from last DISAGREE/PARTIAL verdict}
### Points Resolved During Debate
- {topic}: resolved in Round {N} — {participant} conceded to {participant} (from ledger disagreement-resolution events)
### Areas of Universal Agreement
- {what everyone agreed on}
Remove THIS session's output files only:
rm -f "{TMPDIR}/.vcp/oneshot/cr-{SESSION_ID}-"*
Participant repo mutation: Both API participants (via api-task-runner's Write/Edit/Bash tools) and CLI participants (via their native shell access, e.g., Codex --full-auto) retain the ability to modify the repo despite the prompt instruction to only read and analyze. This is prompt-level enforcement only. A structural read-only mode is a follow-up feature.
CLI output noise: CLI tools may emit banners, ANSI sequences, progress output, or debug text alongside the actual response. The SKILL strips ANSI and searches for consensus keywords anywhere in the response, but noisy output may still confuse synthesis.
Web portal: Configuration is available via /dev-buddy-config web portal (Chatroom tab) or manual editing of ~/.vcp/dev-buddy-chatroom.json.
| Scenario | Action |
|---|---|
| No participants configured | Report error, suggest editing ~/.vcp/dev-buddy-chatroom.json |
| Config validation fails | Report the specific error |
| All external participants fail | Report error to user (quorum not met) |
| Single participant fails | Note failure, continue with remaining (if quorum met) |
| Max rounds exhausted | Present best synthesis with disagreements noted |
TASK_EOF — generates a random one per dispatchcr-{SESSION_ID}-*run_in_background: true + TaskOutput pollingtimeout_msnpx claudepluginhub z-m-huang/vcp --plugin dev-buddyOrchestrates structured multi-provider AI debates between Claude and available advisors (Gemini, Codex, etc.) for critical decisions. Dispatches real providers via orchestrate.sh for diverse perspectives.
Orchestrates multi-agent debates with 2-5 dynamic agents in Challenge (select best variant), Strategy (deep analysis with proposals), or Critic (find weaknesses) modes. Triggers on debate, challenge, compare, critique prompts.
Orchestrates structured multi-round adversarial debates with Pro/Contra agents and judge verdict. Supports binary/tetralemma/polarity modes, brief format, and user-joining roles.