All mechanics live in the bro CLI. This skill is policy only.
A query plan is a TOML list of independent GraphQL steps. bro plan run
fans them out over connectors under a concurrency cap and prints one
merged JSON document keyed by step id — declaration order, never
completion order. bro plan query <file> is the same pipeline in one step;
bro plan validate <file> checks without executing.
The contract
providernames a connector (the data plane:github,gitlab,atlassian, …) — never aproviders[]entry; that registry is the model plane. Absent →connectors.queriespin → auto-detect.- Read-only.
mutation/subscriptiondocuments are rejected at validate time — v1 has no write path, and the keyword sniff over-rejects by design (a field literally namedmutationcan't be expressed; that's the safe direction). - No secrets in plans.
envis a literal overlay — a token value written there is committed as text. Auth always comes from the spawned CLI's own login (gh auth,glab auth,atlassian auth) or the operator's inheritedprocess.env. Execution-shaping vars (ATLASSIAN_API_URL,PATH,HOME) are rejected outright — they could exfiltrate an inheritedAuthorizationheader or swap which binary/config the connector spawns. Operators pin endpoints via thequery.envconfig section instead. varsare scalars (string/number/bool) forgithub/gitlab— serialized as-f k=vCLI fields.atlassiantakes the table as the JSONvariablesbody verbatim.- A failed step records
{ provider, error }(transport) or{ provider, data?, errors? }(GraphQL response) and never aborts siblings. Any failure → exit 1; results still print. - Output is raw — no item normalization in v1. If you need title/status/url rows, write the jq yourself or file the follow-up.
Plan shape
kind = "query"
version = 1
concurrency = 4 # optional; config default is query.concurrency
[[steps]]
id = "gh-prs"
provider = "github"
graphql = """
query ($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
pullRequests(first: 20, states: OPEN) { nodes { number title url } }
}
}
"""
[steps.vars]
owner = "theplenkov"
name = "bro"
Commands
| Command | What it does |
|---|---|
bro plan query <plan.toml> |
validate + run; merged JSON on stdout, exit 1 on any step failure |
bro plan run <plan.toml> |
same execution via the kind router |
bro plan validate <plan.toml> |
schema + read-only gate only |
Config
{ "query": { "concurrency": 4, "env": { "GITLAB_HOST": "gl.corp.example" } } }
query.env applies under every step's env — it is where endpoint
pins belong, including the ones plans are forbidden to carry.
Policy
- Prefer one plan over N serial
gh apicalls — the fan-out is the point, and the merged document is the artifact. - A step failure is data, not a crash: read
error/errorsper key, retry only the failed step.