deep-execution
Executes agent-enhanced council queries as one Workflow of parallel Claude analyst agents that each query a provider, evaluate response quality, ask follow-up questions, and return a schema-enforced analysis with confidence ratings and blind spot analysis. Invoked when the --agents flag is used or when complex architectural decisions are detected.
git clone --depth 1 https://github.com/hex/claude-council /tmp/deep-execution && cp -r /tmp/deep-execution/skills/deep-execution ~/.claude/skills/deep-executionSKILL.md
# Agent-Enhanced Council Execution
Run one Workflow of parallel Claude analyst agents for deeper analysis. Each analyst
queries its provider, evaluates response quality, can ask follow-up questions, and
returns a structured analysis that the workflow enforces against the schema.
## Step 1: Resolve Providers and Write the Questions
One shell call resolves what the workflow needs — each provider's model, its
role, and the question file it will send — with the same helpers the standard
flow uses. Paste the final question into the heredoc verbatim: the quoted
marker means the shell does NOT interpret quotes, backticks or `$()` in it.
The question is emitted once; each provider's role-injected variant is built
in shell, not pasted again.
```bash
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/providers.sh"
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/roles.sh"
PROVIDERS=(<the selected providers, space separated>)
ROLES="<the --roles value, or empty>"
RUN=$(date +%s) # names this run's files; Step 6 reuses it
Q="$PWD/.claude/council-cache/.agents-$RUN"
mkdir -p "$PWD/.claude/council-cache"
# Self-ignoring, as cache.sh and run-council.sh keep it: these files carry the
# question and any --file contents, and must never land in a commit.
[[ -f "$PWD/.claude/council-cache/.gitignore" ]] || printf '*\n' > "$PWD/.claude/council-cache/.gitignore"
cat > "$Q.txt" <<'COUNCIL_Q_EOF'
<the question, verbatim>
COUNCIL_Q_EOF
# --file / auto-context: append the context to the question file here, e.g.
# { printf '\n\nHere is the content of %s:\n\n```\n' "<path>"; cat "<path>"; printf '```\n'; } >> "$Q.txt"
# An unknown role is refused, as the standard flow refuses it; assigning it
# would hand that provider the bare question under a role heading.
[[ -z "$ROLES" ]] || validate_roles "$ROLES" || exit 1
ASSIGNMENTS=""
[[ -n "$ROLES" ]] && ASSIGNMENTS=$(assign_roles_to_providers "$ROLES" "${PROVIDERS[@]}")
echo "run $RUN"
for p in "${PROVIDERS[@]}"; do
role=""
[[ -n "$ASSIGNMENTS" ]] && role=$(get_provider_role "$p" "$ASSIGNMENTS")
qf="$Q.txt"
if [[ -n "$role" ]]; then
qf="$Q-$p.txt"
build_prompt_with_role "$(cat "$Q.txt")" "$role" > "$qf"
fi
printf '%s\t%s\t%s\n' "$p" "$(get_model "$p")" "$qf"
done
```
It prints the run id, then one line per provider: name, model (shown in the
Step 4 header), and the absolute path of that provider's question file.
## Step 2: Run the Analyst Workflow
Agent mode is one Workflow: one analyst agent per provider, in parallel, each
returning its analysis through schema-enforced structured output. The user
asked for agent mode (`--agents`, or yes to the prompt in ask.md Step 1.5),
which is the opt-in the Workflow tool requires.
If the Workflow tool is not available in this session, stop here: tell the
user that `--agents` needs a Claude Code with the Workflow tool, and offer to
run the same question in standard mode instead. Do not fall back to another
way of spawning agents.
Read `${CLAUDE_PLUGIN_ROOT}/schemas/agent-analysis.schema.json` with the Read
tool, then call the Workflow tool with this script, verbatim, via `script`:
```js
export const meta = {
name: 'council-agents',
description: 'One analyst per council provider: query it, judge the answer, follow up, return a structured analysis',
phases: [{ title: 'Analyze', detail: 'one analyst agent per provider, in parallel' }],
}
// The tool's schema validator does not know the draft-2020-12 dialect the
// file declares; without the declaration it validates the same keywords fine.
const schema = { ...args.schema }
delete schema.$schema
const template = `${args.pluginRoot}/skills/deep-execution/agent-prompt-template.md`
// Single stage: there is no later step for a finished analyst to move on to,
// so the barrier costs nothing.
const results = await parallel(args.providers.map(p => () =>
agent(
`You are the council analyst for the provider "${p.name}".\n` +
`Read ${template} and carry out every step in it, with these values:\n` +
`- {PROVIDER} = ${p.name}\n` +
`- {PLUGIN_ROOT} = ${args.pluginRoot}\n` +
`- {QUESTION_FILE} = ${p.questionFile}\n` +
`Your final answer is the Round 3 analysis object, returned through the structured output tool.`,
{ label: p.name, phase: 'Analyze', schema, agentType: 'general-purpose' })))
// parallel() keeps a dead or skipped analyst's slot as null, index-aligned with args.providers.
const failed = args.providers.filter((_, i) => !results[i]).map(p => p.name)
if (failed.length) log(`no analysis from: ${failed.join(', ')}`)
return {
// The label goes last so an analyst that emits its own "provider" key cannot rename itself.
analyses: results.map((a, i) => a && { ...a, provider: args.providers[i].name }).filter(Boolean),
failed,
}
```
and these `args` (real JSON values, not a string; `pluginRoot` is the real
path of `${CLAUDE_PLUGIN_ROOT}`, `questionFile` the path Step 1 printed):
```json
{
"pluginRoot": "<CLAUDE_PLUGIN_ROOT>",
"schema": { "...the parsed schema file..." },
"providers": [
{ "name": "gemini", "questionFile": "<absolute path from Step 1>" }
]
}
```
The workflow returns `{ analyses, failed }`. Every object in `analyses`
satisfies the schema; `failed` names the providers whose analyst died or was
skipped. A provider that returned an error is not in `failed`: its analyst
reports it as a `quality: poor`, `confidence: low` analysis whose
`full_response` is the error text (the template says so). Step 5 treats both
as the same thing — a provider that did not answer.
## Step 3: Read the Result
Nothing to validate: use each analysis's fields directly in Steps 4-5, and
carry `failed` into Step 5's provider failures.
## Step 4: Display Results
For each analysis, display it using this format. `{MODEL}` is the Step 1
model: a model-fallback re-run inside an analyst cannot change this header,
and the displacement is visible only in the analysis text.
```
## {EMOJI} {PROVID|-
One independent member of a local (provider-less) council. Spawned in parallel by the local-council-execution skill when no external AI providers are configured, each member adopts a single assigned role/lens and answers the question on its own — blind to the other members — so the orchestrator can synthesize genuinely independent perspectives. Not invoked directly by users.
Query multiple AI agents (Gemini, OpenAI, Grok, Perplexity, Kimi, and a local ollama model) for diverse perspectives on architecture decisions, technology choices, debugging dead-ends, and security tradeoffs. Use this whenever the user names the council directly, whatever the topic — ask the council, council review, full council review, what does the council think, get a second opinion from the council, run this past the council — including reviews of code, documents, plans or artifacts. Also suggest it unprompted when the user is choosing between competing approaches (e.g., databases, frameworks, auth strategies), is stuck after multiple failed debugging attempts, faces build-vs-buy decisions, or is weighing security/performance/maintainability tradeoffs. Do NOT suggest it unprompted for simple implementation tasks, quick fixes, or questions with clear single answers; a direct request for the council overrides that exclusion.
Fetch, list, or cancel background council jobs started with --async
Check connectivity and configuration status of all council providers
Executes council queries by running the query pipeline across selected AI providers (Gemini, OpenAI, Grok, Perplexity), displaying formatted responses verbatim, and generating a synthesis of consensus, divergence, and recommendations. Invoked by the ask command during standard (non-agent) council queries.
Executes agent-enhanced council queries by spawning parallel Claude subagents that each query a provider, evaluate response quality, ask follow-up questions, and return structured insights with confidence ratings and blind spot analysis. Invoked when the --agents flag is used or when complex architectural decisions are detected.
Runs a local council when no external AI providers are configured. Spawns N independent Claude subagents (one per role, blind to each other) that each answer the question from a single assigned lens, then synthesizes their perspectives. Invoked by the ask command via --local, or when the user accepts the local-council offer after no providers are found. This is a same-model (Claude-only) panel, not a cross-vendor council.