brindle 0.2.1__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {brindle-0.2.1 → brindle-0.3.1}/PKG-INFO +123 -12
- {brindle-0.2.1 → brindle-0.3.1}/README.md +122 -11
- {brindle-0.2.1 → brindle-0.3.1}/pyproject.toml +3 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/agents.py +108 -13
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/autopilot.py +5 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/developer-light.md +2 -2
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/ci_adapters.py +83 -11
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/ci_client.py +368 -13
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/ci_federation.py +250 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/ci_hosts.py +65 -6
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/cli.py +72 -7
- brindle-0.3.1/src/brindle/company_identity.py +531 -0
- brindle-0.3.1/src/brindle/company_login.py +416 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/config.py +6 -2
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/cost.py +12 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/cull.py +73 -4
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/doctor.py +137 -0
- brindle-0.3.1/src/brindle/identity_lock.py +71 -0
- brindle-0.3.1/src/brindle/keys_cmds.py +121 -0
- brindle-0.2.1/src/brindle/pro/credentials.py → brindle-0.3.1/src/brindle/keystore.py +145 -39
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/legacy.py +12 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/mcp_server.py +16 -0
- brindle-0.3.1/src/brindle/model_access.py +293 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/runner.py +4 -1
- brindle-0.3.1/src/brindle/pane_auth.py +87 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pipeline.py +70 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pool.py +15 -11
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pricing.py +2 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/account.py +78 -8
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/auth.py +29 -6
- brindle-0.3.1/src/brindle/pro/credentials.py +53 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/managed_models.py +53 -3
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/org_profiles.py +33 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/team_policy.py +282 -5
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/procs.py +23 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/profiles.py +33 -2
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/providers.py +278 -9
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/quota.py +14 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/rewind.py +2 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/secrets.py +54 -8
- brindle-0.3.1/src/brindle/self_serve.py +344 -0
- brindle-0.3.1/src/brindle/signin_pause.py +384 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/tasks.py +8 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/view.py +12 -1
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/workspaces.py +27 -7
- {brindle-0.2.1 → brindle-0.3.1}/.gitignore +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/LICENSE +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/SCHEDULE-A +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/__init__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/__main__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/account.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/airgap.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/antigravity.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/budget.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/__init__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/backend-auditor.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/developer-codex.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/developer-heavy.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/developer-local.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/developer.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/qa.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/reviewer-codex.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/reviewer-local.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/reviewer.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/subagent.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_agents/supervisor.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_rules/__init__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_rules/security/backend.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_rules/style/minimal-diff.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/builtin_rules/tests/only.md +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/codemap.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/codex_hook.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/conflicts.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/cost_estimate.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/db.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/demo.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/detect.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/escapes.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/events.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/gates.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/git.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/guardrails.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/history.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/inbox.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/learned_rules.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/learning.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/__init__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/client.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/loop.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/permissions.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/serve.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/native/tools.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/permissions.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/plugins.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/policy.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/__init__.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/_files.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/audit_chain.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/audit_export.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/brief_learning.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/cost_centers.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/features.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/keys.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/learning.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/license.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/loopback.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/orgkey.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/rollout.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/settings_sync.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/status.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/pro/team_events.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/repo_cmds.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/repos.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/rule_checks.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/savings.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/scratch.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/services.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/sessions.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/sidebar_follow.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/status_cache.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/tmux.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/usage.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/watch.py +0 -0
- {brindle-0.2.1 → brindle-0.3.1}/src/brindle/watch_costs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brindle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Run coding agents in parallel, each on its own git branch, with a supervisor that delegates, reviews, and merges
|
|
5
5
|
Project-URL: Homepage, https://pawdelta.com/brindle/
|
|
6
6
|
Project-URL: Documentation, https://pawdelta.com/brindle/docs/recommended-use
|
|
@@ -89,7 +89,7 @@ uv tool install --editable ~/Projects/brindle # or from a local checkout
|
|
|
89
89
|
brindle drives Claude Code, so you need that too (`npm install -g @anthropic-ai/claude-code`).
|
|
90
90
|
|
|
91
91
|
`brindle --version` prints the installed version; the tmux status bar of every brindle
|
|
92
|
-
session shows it too (`brindle 0.
|
|
92
|
+
session shows it too (`brindle 0.3.1`). A session started before an upgrade keeps
|
|
93
93
|
running the old code, and shows the old number, until you restart it.
|
|
94
94
|
|
|
95
95
|
## Quick start
|
|
@@ -350,6 +350,7 @@ your own status line prints, so what you see doesn't change.
|
|
|
350
350
|
| `brindle transfer [REPO] [--from SESSION] [-b BRANCH]` | move a scratch session's work into a real repo |
|
|
351
351
|
| `brindle ls [--all]` | workspaces and agents |
|
|
352
352
|
| `brindle repo add PATH [--name ALIAS] / rm ALIAS / ls` | attach other local repos to the current session so workers can go there (brindle Pro; see "Several repos in one session") |
|
|
353
|
+
| `brindle keys set/unset/list [NAME]` | store model API keys (e.g. `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`) once in the OS keychain (or a 0600 file); every agent pane gets the ones its provider reads, unless you already export it. `set` reads the value from a hidden prompt or stdin, `list` shows names and the last 4 characters. `CLAUDE_CODE_OAUTH_TOKEN` (a Claude subscription token) is never stored |
|
|
353
354
|
| `brindle history [--limit N] [--kind K] [--all]` | durable log of worker results, reviews, merges and milestone checks |
|
|
354
355
|
| `brindle cost [--days N] [--all]` | dollar spend at list prices over the last 30 days, by model |
|
|
355
356
|
| `brindle cost report [--days N] [--all]` | Pro: spend by day, profile and goal, cost per merged branch, review pass rate per worker profile |
|
|
@@ -361,7 +362,8 @@ your own status line prints, so what you see doesn't change.
|
|
|
361
362
|
| `brindle cost estimate [--tasks N] [--weight W] [--profile P] [--reviewer R]` | what the current goal (or N tasks) is likely to cost, as a range from this repo's history (median to p80 of past worker and review runs), plus a cheaper alternative with a different reviewer; says "low confidence" when there's too little history. Also added to `set_goal` and `assign` replies (brindle Pro) |
|
|
362
363
|
| `brindle learning` | whether brindle Pro's hosted learning is on for this repo, and if not, why (nothing is learned on your machine) |
|
|
363
364
|
| `brindle learning seed` | Pro: sends this repo's finished routing history to the hosted learner once, so it starts with what this machine has seen. Only the usual coarse record fields leave (kind/size one-hots, counters, HMAC keys), never task text or paths. A second run sends nothing new; decisions already sent live are skipped |
|
|
364
|
-
| `brindle account [login\|logout\|status\|upgrade\|portal\|org]` | paid features: bare `brindle account` shows what your plan has and how to get the rest (see "brindle Pro and Team" below) |
|
|
365
|
+
| `brindle account [login\|logout\|status\|upgrade\|portal\|seats\|org]` | paid features: bare `brindle account` shows what your plan has and how to get the rest (see "brindle Pro and Team" below) |
|
|
366
|
+
| `brindle login` | the same as `brindle account login`; when your org's policy has an `agent_setup` block it also signs you in to the Claude and Codex route the company chose (AWS SSO profile, `gcloud`, `az`, `claude auth login`, `codex login`), stores the Claude Code environment for brindle's panes in `~/.brindle/config.json`, and checks the pinned models. `brindle doctor --fix` does the same |
|
|
365
367
|
| `brindle audit verify\|export\|pubkey\|ship\|prune` | the local tamper-evident audit log, and shipping it to your SIEM (brindle Enterprise; see "Audit log" below) |
|
|
366
368
|
| `brindle watch [--all] [--once]` | the dashboard on its own (the same view as the sidebar): enter attaches, `p` peeks, `x` closes |
|
|
367
369
|
| `brindle sidebar` | bring this session's sidebar into the tmux session you're in (also `Ctrl-b S` in a window without one); restarts it if it was closed |
|
|
@@ -526,6 +528,7 @@ Autopilot, merge gates and cleanup:
|
|
|
526
528
|
| `max_agents` | `4` | workers running at once per session (`0`: no cap) |
|
|
527
529
|
| `check_timeout` | `900` | seconds each check may take |
|
|
528
530
|
| `check_concurrency` | `2` | check runs at once on this machine, across branches; the rest wait their turn (`0`: no cap). A run far past its last duration is reported to the supervisor |
|
|
531
|
+
| `fable_escalation` | on, unless the worker runs on a cloud account (Bedrock, Vertex or Foundry) | retry a failed heavy task once on `developer-heavy` (Fable) before handing it to you; `true` turns it on for a cloud account, `false` off |
|
|
529
532
|
| `usage_limit` | `90` | autopilot stops pushing on at this % of your Claude usage limit |
|
|
530
533
|
| `limit_cooldown_minutes` | `300` for Antigravity | how long a provider that hit its limit counts as unavailable |
|
|
531
534
|
| `graphify` | if the graph is there | point agents at the repo's [graphify](https://github.com/safishamsi/graphify) code map (`false` turns it off) |
|
|
@@ -589,9 +592,9 @@ keep theirs):
|
|
|
589
592
|
```json
|
|
590
593
|
{
|
|
591
594
|
"routing": {
|
|
592
|
-
"light": ["developer", "developer-codex", "developer-local"],
|
|
595
|
+
"light": ["developer-light", "developer", "developer-codex", "developer-local"],
|
|
593
596
|
"medium": ["developer", "developer-codex", "developer-heavy"],
|
|
594
|
-
"heavy": ["developer
|
|
597
|
+
"heavy": ["developer", "developer-heavy", "developer-codex"]
|
|
595
598
|
}
|
|
596
599
|
}
|
|
597
600
|
```
|
|
@@ -599,7 +602,9 @@ keep theirs):
|
|
|
599
602
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
600
603
|
be what works best for you, and that's for the learner to find out.
|
|
601
604
|
|
|
602
|
-
`developer-
|
|
605
|
+
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
606
|
+
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
607
|
+
at high effort.
|
|
603
608
|
A profile is skipped when its CLI isn't installed (`claude`, `codex`, `agy`), the
|
|
604
609
|
local model server isn't answering, or its provider is at your `usage_limit`. If
|
|
605
610
|
hosted learning is on it chooses among the profiles left; otherwise the first
|
|
@@ -758,11 +763,14 @@ workflow.
|
|
|
758
763
|
|
|
759
764
|
```sh
|
|
760
765
|
brindle account # paid features: what you have, how to use them, how to get the rest
|
|
766
|
+
brindle login # the same as `brindle account login`; also applies your org's agent_setup (company agent sign-in)
|
|
761
767
|
brindle account login # opens your browser to sign in (--device: enter a code instead, e.g. over SSH); brindle checks the plan offline from then on
|
|
762
768
|
brindle account status # your plan, features, hosted learning on or off, when the entitlement expires
|
|
763
769
|
brindle account savings # what hosted learning's picks gained in this repo, this month and last: estimates, from this machine's records only
|
|
764
770
|
brindle account upgrade # opens the checkout for brindle Pro (and prints its URL)
|
|
765
|
-
brindle account
|
|
771
|
+
brindle account upgrade --enterprise [--trial] --seats N --org ORG # brindle Enterprise for a team org; --trial: free trial, at most 10 seats
|
|
772
|
+
brindle account portal # opens the billing portal (invoices, payment method, cancellation); --org ORG for a team org
|
|
773
|
+
brindle account seats N # set a Team or Enterprise org's seat count (billing admin); --org ORG; Stripe prorates the change
|
|
766
774
|
brindle account org list # the orgs you belong to; `org use <id>` switches, `org policy` shows the current one
|
|
767
775
|
brindle account org policy # the org's policy, its per-role overrides, and the policy that applies to you
|
|
768
776
|
brindle account org profiles # the org's shared profiles and rule packs, and which are pinned
|
|
@@ -772,6 +780,51 @@ brindle account org member policy-role <member> <role|none> # give a member a
|
|
|
772
780
|
brindle account org company [link <org_id> | unlink] # link orgs you own into one company; learning is pooled only within it
|
|
773
781
|
```
|
|
774
782
|
|
|
783
|
+
**Sign-in loss pauses agents.** While agents run, brindle checks every 30 s that
|
|
784
|
+
Claude and Codex are still signed in (`claude auth status` or the cloud route's
|
|
785
|
+
identity, re-checked only when its credentials change; `codex login status`;
|
|
786
|
+
Antigravity can't be checked). If one is signed out, its running agents pause
|
|
787
|
+
with their worktrees, commits and conversations kept, and the supervisor and
|
|
788
|
+
your session are told; a timeout or missing CLI never pauses, it warns once.
|
|
789
|
+
A wrong company identity pauses them only when the org policy enforces it
|
|
790
|
+
(Enterprise); otherwise it warns once. While it enforces, Claude agents run
|
|
791
|
+
on exactly the route brindle checked: a profile's env lines can't change the
|
|
792
|
+
backend, account, key or proxy, and other cloud and Claude credential variables
|
|
793
|
+
(`ANTHROPIC_*`, `AWS_*`, `GOOGLE_*`, `CLOUDSDK_*`, `AZURE_*`, ...) in your
|
|
794
|
+
environment or `brindle keys` are left out of their panes, so those agents
|
|
795
|
+
can't use your own AWS, Google Cloud or Azure access in their shell either.
|
|
796
|
+
Claude Code's own settings files can still set variables inside it; to rule
|
|
797
|
+
that out too, use Claude Code's managed settings. After `brindle login`,
|
|
798
|
+
`brindle doctor --fix` or the CLI's own login, the agents brindle paused resume
|
|
799
|
+
into their conversations, but only as the account they started under: if
|
|
800
|
+
someone else is signed in (a personal login, say) they stay paused until the
|
|
801
|
+
original account is back. Your own chat session is never paused, only the
|
|
802
|
+
workers. A cloud sign-in is re-checked only when its credential files or
|
|
803
|
+
variables change, so a token that expires silently isn't noticed until then.
|
|
804
|
+
`brindle doctor` lists agents paused for sign-in.
|
|
805
|
+
|
|
806
|
+
**Sessions stay with their identity.** Each Claude agent records the identity it
|
|
807
|
+
launched under (Claude org, AWS account and role, GCP project, Azure
|
|
808
|
+
subscription; ids only, never tokens). While a different identity is signed in,
|
|
809
|
+
that agent is locked: brindle refuses to resume it (`brindle continue`), rewind
|
|
810
|
+
it, message or hand off to it, start a new agent in its worktree (including
|
|
811
|
+
naming its branch for a new worker), or `peek` at it, with "This session
|
|
812
|
+
belongs to <org/account>; sign in as it to continue (`brindle login`)".
|
|
813
|
+
`brindle ls`, `watch`, the sidebar, `list_agents` and `agent_turns` show it as
|
|
814
|
+
`locked: <org/account>` without its conversation (usage, last activity, turn
|
|
815
|
+
summaries), and `depends_on` and `merge_workspace` won't pull its branch into a
|
|
816
|
+
session under another identity. Agents with no recorded identity (started before
|
|
817
|
+
this, or without a company setup) are unaffected, and so is everything while the
|
|
818
|
+
current identity can't be told (signed out, CLI missing).
|
|
819
|
+
|
|
820
|
+
This is a guard inside brindle, not a sandbox: on one OS user account the
|
|
821
|
+
worktrees, transcripts and credential files stay readable outside brindle (a
|
|
822
|
+
shell, another tool). Real separation needs a separate OS user or your
|
|
823
|
+
company's device management. Codex and Antigravity can't be told apart by
|
|
824
|
+
account (brindle only sees "signed in"), so their sessions are paused on
|
|
825
|
+
sign-out but can't be locked to one account; isolation applies to Claude routes
|
|
826
|
+
(subscription, Bedrock, Vertex, Foundry).
|
|
827
|
+
|
|
775
828
|
### Several repos in one session (brindle Pro)
|
|
776
829
|
|
|
777
830
|
A session can work across several repos. Attach another local repo you own
|
|
@@ -825,6 +878,16 @@ entitlement.
|
|
|
825
878
|
* `deny_personal_keys`: the personal model keys (`ANTHROPIC_API_KEY`,
|
|
826
879
|
`OPENAI_API_KEY`, ...) are taken out of every agent pane, and a profile that
|
|
827
880
|
sets one is refused.
|
|
881
|
+
* An org-owned key: with `provider` `anthropic` (or `openai-compatible`), set
|
|
882
|
+
`key_env` to the name of a variable that holds the org's key (not a personal
|
|
883
|
+
one like `ANTHROPIC_API_KEY`), or `key_helper` to a command, as a list of
|
|
884
|
+
arguments, that prints the key (for example `["vault", "kv", "get",
|
|
885
|
+
"-field=key", "secret/anthropic"]`). brindle runs the helper on the person's
|
|
886
|
+
machine, without a shell and with a timeout, each time a worker starts, and
|
|
887
|
+
gives the key to that worker as `ANTHROPIC_API_KEY` (`OPENAI_API_KEY` for
|
|
888
|
+
Codex). It passes `deny_personal_keys`; a personal key doesn't. The key never
|
|
889
|
+
goes through brindle's servers. When the variable is missing or the helper
|
|
890
|
+
fails, the worker doesn't start.
|
|
828
891
|
|
|
829
892
|
Two things to know when you turn on `deny_personal_keys`:
|
|
830
893
|
|
|
@@ -985,17 +1048,31 @@ workflows call these commands:
|
|
|
985
1048
|
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
986
1049
|
the branch you started on and deletes the local setup branch, so `git pull`
|
|
987
1050
|
after merging the setup pull request is clean (commit or stash your changes
|
|
988
|
-
first: it refuses to start with uncommitted work).
|
|
1051
|
+
first: it refuses to start with uncommitted work). With your own cloud
|
|
1052
|
+
(`--credential bedrock|vertex|foundry`, keyless GitHub OIDC) it can read the
|
|
1053
|
+
IDs from the deployment template's outputs instead of asking:
|
|
1054
|
+
`--from-stack NAME [--region R]` (AWS CloudFormation), `--from-terraform DIR`
|
|
1055
|
+
(Google) or `--from-deployment NAME -g RG` (Azure). They are defaults for
|
|
1056
|
+
`--cloud-var`, which still overrides them, and every ID is format-checked. A
|
|
1057
|
+
missing `aws`, `terraform` or `az` CLI or output is an error that names the
|
|
1058
|
+
`--cloud-var` to pass instead. Vertex AI and Microsoft Foundry are in
|
|
1059
|
+
**preview** (not yet verified end to end): `init` refuses them unless you pass
|
|
1060
|
+
`--preview` or set `BRINDLE_CI_PREVIEW_CLOUDS=1`, and `doctor` marks them
|
|
1061
|
+
`(preview)`. Bedrock is generally available.
|
|
989
1062
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
990
|
-
which providers CI may use on this repository.
|
|
1063
|
+
which providers CI may use on this repository. `--models` also makes one tiny
|
|
1064
|
+
call per pinned model and says why any is refused (a quota, a form not filled in).
|
|
991
1065
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
992
1066
|
or a validation of a pull request.
|
|
993
1067
|
- `brindle ci run`: run what was started: the supervisor and the result upload,
|
|
994
1068
|
or the pull request's checks and reviews and the evidence upload.
|
|
995
1069
|
- `brindle ci report`: tell the service how the workflow's jobs ended.
|
|
996
1070
|
|
|
997
|
-
Credential names are reported, never values.
|
|
998
|
-
|
|
1071
|
+
Credential names are reported, never values. CI uses API keys, cloud sign-ins
|
|
1072
|
+
(Bedrock, Vertex, Foundry) or identity federation only: a provider signed in
|
|
1073
|
+
only with a subscription (`CLAUDE_CODE_OAUTH_TOKEN`, a Codex ChatGPT login) is
|
|
1074
|
+
not used, on personal and organization repositories alike. Add an API key
|
|
1075
|
+
secret instead.
|
|
999
1076
|
|
|
1000
1077
|
Fix builds only fix the default branch's *required* status checks, and a new
|
|
1001
1078
|
repository has none. When the default branch requires none, `brindle ci init`
|
|
@@ -1228,7 +1305,7 @@ it's signed in without a plan that includes it, is reported to its supervisor.
|
|
|
1228
1305
|
| Provider | Key login (environment variables) |
|
|
1229
1306
|
|---|---|
|
|
1230
1307
|
| `claude` | yes: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, or Bedrock/Vertex/Foundry (`CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY`) |
|
|
1231
|
-
| `codex` | yes: `OPENAI_API_KEY`, `CODEX_API_KEY` |
|
|
1308
|
+
| `codex` | yes: `OPENAI_API_KEY`, `CODEX_API_KEY`. With Codex signed in with ChatGPT (checked on Codex CLI 0.162.0): interactive `codex`, which brindle runs in agent panes, ignores both keys and uses the ChatGPT plan, and only `codex login --with-api-key` switches it to a key; headless `codex exec` (Brindle-CI) bills `CODEX_API_KEY` over the login and ignores `OPENAI_API_KEY`. `brindle doctor` and `brindle keys set` say so, and `auth: api_key` on an interactive Codex profile is refused under a ChatGPT login (run `codex login --with-api-key`, or use `auth: subscription`) |
|
|
1232
1309
|
| `antigravity` | `GEMINI_API_KEY`, only with `"modelProvider": "gemini"` in `agy`'s `settings.json` (see [Google Antigravity](#google-antigravity)); otherwise `agy`'s own browser sign-in |
|
|
1233
1310
|
|
|
1234
1311
|
Workers that run unattended should use key login where the CLI supports it.
|
|
@@ -1240,6 +1317,16 @@ needs no browser step. Put the key in your environment, or in a profile's
|
|
|
1240
1317
|
`brindle doctor` names the variable each CLI gets, from your shell or from
|
|
1241
1318
|
which profiles.
|
|
1242
1319
|
|
|
1320
|
+
A profile chooses between the two with `auth`:
|
|
1321
|
+
|
|
1322
|
+
| `auth:` | What the worker signs in with |
|
|
1323
|
+
|---|---|
|
|
1324
|
+
| `auto` (default) | A key from your environment or `brindle keys` if there is one, else the CLI's own login. |
|
|
1325
|
+
| `subscription` | Always the CLI's own login: brindle strips that provider's API keys from the pane. |
|
|
1326
|
+
| `api_key` | Only a key: the worker refuses to start without one. |
|
|
1327
|
+
|
|
1328
|
+
Your org's `deny_personal_keys` (Enterprise) still applies on top of `auth`.
|
|
1329
|
+
|
|
1243
1330
|
### Cheap workers
|
|
1244
1331
|
|
|
1245
1332
|
By default a Claude Code worker loads everything your own `claude` does: your
|
|
@@ -1626,6 +1713,30 @@ marks the agent idle and delivers any queued message. Codex has no Stop hook, so
|
|
|
1626
1713
|
an autopilot supervisor on Codex that turn end is also where brindle tells it to keep
|
|
1627
1714
|
going, with the same limit on reminders as Claude Code.
|
|
1628
1715
|
|
|
1716
|
+
### Using your company's access
|
|
1717
|
+
|
|
1718
|
+
Two ways to run brindle's agents on your company's Claude (Bedrock, Vertex,
|
|
1719
|
+
Foundry, a Team or Enterprise plan) and Codex, without handling keys:
|
|
1720
|
+
|
|
1721
|
+
- **Your org sets it up (brindle Team).** When your org's policy has an
|
|
1722
|
+
`agent_setup` block, `brindle login` (and `brindle doctor --fix`) signs you
|
|
1723
|
+
in to the route the company chose and `brindle doctor` shows which identity
|
|
1724
|
+
each agent uses. It always wins over anything below.
|
|
1725
|
+
- **You set it up yourself (any plan).** When your org has no `agent_setup`,
|
|
1726
|
+
`brindle login` looks, read-only, at what this machine is already signed in
|
|
1727
|
+
to: Claude Code's managed settings (if your IT configures Claude Code,
|
|
1728
|
+
brindle just uses it), `claude auth status`, AWS SSO profiles in
|
|
1729
|
+
`~/.aws/config`, the active `gcloud` project, the active `az` subscription
|
|
1730
|
+
and `codex login status`. It never reads tokens or credential files. It
|
|
1731
|
+
proposes what it found ("Use Bedrock (AWS 1234…, role Dev, us-east-1)?");
|
|
1732
|
+
the default is no, and with no terminal it is always no. A yes is saved as
|
|
1733
|
+
`"agent_setup"` in `~/.brindle/config.json`, in the same format as the org
|
|
1734
|
+
policy's (`enforce` is never applied to it), and `brindle doctor` labels it
|
|
1735
|
+
as self-serve and says who is billed.
|
|
1736
|
+
|
|
1737
|
+
You must be authorized to use any company credentials you connect: brindle only
|
|
1738
|
+
signs in with the access you already have, it doesn't grant any.
|
|
1739
|
+
|
|
1629
1740
|
## Google Antigravity
|
|
1630
1741
|
|
|
1631
1742
|
brindle runs Google Antigravity's terminal agent, `agy`, as well as Claude Code and
|
|
@@ -59,7 +59,7 @@ uv tool install --editable ~/Projects/brindle # or from a local checkout
|
|
|
59
59
|
brindle drives Claude Code, so you need that too (`npm install -g @anthropic-ai/claude-code`).
|
|
60
60
|
|
|
61
61
|
`brindle --version` prints the installed version; the tmux status bar of every brindle
|
|
62
|
-
session shows it too (`brindle 0.
|
|
62
|
+
session shows it too (`brindle 0.3.1`). A session started before an upgrade keeps
|
|
63
63
|
running the old code, and shows the old number, until you restart it.
|
|
64
64
|
|
|
65
65
|
## Quick start
|
|
@@ -320,6 +320,7 @@ your own status line prints, so what you see doesn't change.
|
|
|
320
320
|
| `brindle transfer [REPO] [--from SESSION] [-b BRANCH]` | move a scratch session's work into a real repo |
|
|
321
321
|
| `brindle ls [--all]` | workspaces and agents |
|
|
322
322
|
| `brindle repo add PATH [--name ALIAS] / rm ALIAS / ls` | attach other local repos to the current session so workers can go there (brindle Pro; see "Several repos in one session") |
|
|
323
|
+
| `brindle keys set/unset/list [NAME]` | store model API keys (e.g. `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`) once in the OS keychain (or a 0600 file); every agent pane gets the ones its provider reads, unless you already export it. `set` reads the value from a hidden prompt or stdin, `list` shows names and the last 4 characters. `CLAUDE_CODE_OAUTH_TOKEN` (a Claude subscription token) is never stored |
|
|
323
324
|
| `brindle history [--limit N] [--kind K] [--all]` | durable log of worker results, reviews, merges and milestone checks |
|
|
324
325
|
| `brindle cost [--days N] [--all]` | dollar spend at list prices over the last 30 days, by model |
|
|
325
326
|
| `brindle cost report [--days N] [--all]` | Pro: spend by day, profile and goal, cost per merged branch, review pass rate per worker profile |
|
|
@@ -331,7 +332,8 @@ your own status line prints, so what you see doesn't change.
|
|
|
331
332
|
| `brindle cost estimate [--tasks N] [--weight W] [--profile P] [--reviewer R]` | what the current goal (or N tasks) is likely to cost, as a range from this repo's history (median to p80 of past worker and review runs), plus a cheaper alternative with a different reviewer; says "low confidence" when there's too little history. Also added to `set_goal` and `assign` replies (brindle Pro) |
|
|
332
333
|
| `brindle learning` | whether brindle Pro's hosted learning is on for this repo, and if not, why (nothing is learned on your machine) |
|
|
333
334
|
| `brindle learning seed` | Pro: sends this repo's finished routing history to the hosted learner once, so it starts with what this machine has seen. Only the usual coarse record fields leave (kind/size one-hots, counters, HMAC keys), never task text or paths. A second run sends nothing new; decisions already sent live are skipped |
|
|
334
|
-
| `brindle account [login\|logout\|status\|upgrade\|portal\|org]` | paid features: bare `brindle account` shows what your plan has and how to get the rest (see "brindle Pro and Team" below) |
|
|
335
|
+
| `brindle account [login\|logout\|status\|upgrade\|portal\|seats\|org]` | paid features: bare `brindle account` shows what your plan has and how to get the rest (see "brindle Pro and Team" below) |
|
|
336
|
+
| `brindle login` | the same as `brindle account login`; when your org's policy has an `agent_setup` block it also signs you in to the Claude and Codex route the company chose (AWS SSO profile, `gcloud`, `az`, `claude auth login`, `codex login`), stores the Claude Code environment for brindle's panes in `~/.brindle/config.json`, and checks the pinned models. `brindle doctor --fix` does the same |
|
|
335
337
|
| `brindle audit verify\|export\|pubkey\|ship\|prune` | the local tamper-evident audit log, and shipping it to your SIEM (brindle Enterprise; see "Audit log" below) |
|
|
336
338
|
| `brindle watch [--all] [--once]` | the dashboard on its own (the same view as the sidebar): enter attaches, `p` peeks, `x` closes |
|
|
337
339
|
| `brindle sidebar` | bring this session's sidebar into the tmux session you're in (also `Ctrl-b S` in a window without one); restarts it if it was closed |
|
|
@@ -496,6 +498,7 @@ Autopilot, merge gates and cleanup:
|
|
|
496
498
|
| `max_agents` | `4` | workers running at once per session (`0`: no cap) |
|
|
497
499
|
| `check_timeout` | `900` | seconds each check may take |
|
|
498
500
|
| `check_concurrency` | `2` | check runs at once on this machine, across branches; the rest wait their turn (`0`: no cap). A run far past its last duration is reported to the supervisor |
|
|
501
|
+
| `fable_escalation` | on, unless the worker runs on a cloud account (Bedrock, Vertex or Foundry) | retry a failed heavy task once on `developer-heavy` (Fable) before handing it to you; `true` turns it on for a cloud account, `false` off |
|
|
499
502
|
| `usage_limit` | `90` | autopilot stops pushing on at this % of your Claude usage limit |
|
|
500
503
|
| `limit_cooldown_minutes` | `300` for Antigravity | how long a provider that hit its limit counts as unavailable |
|
|
501
504
|
| `graphify` | if the graph is there | point agents at the repo's [graphify](https://github.com/safishamsi/graphify) code map (`false` turns it off) |
|
|
@@ -559,9 +562,9 @@ keep theirs):
|
|
|
559
562
|
```json
|
|
560
563
|
{
|
|
561
564
|
"routing": {
|
|
562
|
-
"light": ["developer", "developer-codex", "developer-local"],
|
|
565
|
+
"light": ["developer-light", "developer", "developer-codex", "developer-local"],
|
|
563
566
|
"medium": ["developer", "developer-codex", "developer-heavy"],
|
|
564
|
-
"heavy": ["developer
|
|
567
|
+
"heavy": ["developer", "developer-heavy", "developer-codex"]
|
|
565
568
|
}
|
|
566
569
|
}
|
|
567
570
|
```
|
|
@@ -569,7 +572,9 @@ keep theirs):
|
|
|
569
572
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
570
573
|
be what works best for you, and that's for the learner to find out.
|
|
571
574
|
|
|
572
|
-
`developer-
|
|
575
|
+
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
576
|
+
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
577
|
+
at high effort.
|
|
573
578
|
A profile is skipped when its CLI isn't installed (`claude`, `codex`, `agy`), the
|
|
574
579
|
local model server isn't answering, or its provider is at your `usage_limit`. If
|
|
575
580
|
hosted learning is on it chooses among the profiles left; otherwise the first
|
|
@@ -728,11 +733,14 @@ workflow.
|
|
|
728
733
|
|
|
729
734
|
```sh
|
|
730
735
|
brindle account # paid features: what you have, how to use them, how to get the rest
|
|
736
|
+
brindle login # the same as `brindle account login`; also applies your org's agent_setup (company agent sign-in)
|
|
731
737
|
brindle account login # opens your browser to sign in (--device: enter a code instead, e.g. over SSH); brindle checks the plan offline from then on
|
|
732
738
|
brindle account status # your plan, features, hosted learning on or off, when the entitlement expires
|
|
733
739
|
brindle account savings # what hosted learning's picks gained in this repo, this month and last: estimates, from this machine's records only
|
|
734
740
|
brindle account upgrade # opens the checkout for brindle Pro (and prints its URL)
|
|
735
|
-
brindle account
|
|
741
|
+
brindle account upgrade --enterprise [--trial] --seats N --org ORG # brindle Enterprise for a team org; --trial: free trial, at most 10 seats
|
|
742
|
+
brindle account portal # opens the billing portal (invoices, payment method, cancellation); --org ORG for a team org
|
|
743
|
+
brindle account seats N # set a Team or Enterprise org's seat count (billing admin); --org ORG; Stripe prorates the change
|
|
736
744
|
brindle account org list # the orgs you belong to; `org use <id>` switches, `org policy` shows the current one
|
|
737
745
|
brindle account org policy # the org's policy, its per-role overrides, and the policy that applies to you
|
|
738
746
|
brindle account org profiles # the org's shared profiles and rule packs, and which are pinned
|
|
@@ -742,6 +750,51 @@ brindle account org member policy-role <member> <role|none> # give a member a
|
|
|
742
750
|
brindle account org company [link <org_id> | unlink] # link orgs you own into one company; learning is pooled only within it
|
|
743
751
|
```
|
|
744
752
|
|
|
753
|
+
**Sign-in loss pauses agents.** While agents run, brindle checks every 30 s that
|
|
754
|
+
Claude and Codex are still signed in (`claude auth status` or the cloud route's
|
|
755
|
+
identity, re-checked only when its credentials change; `codex login status`;
|
|
756
|
+
Antigravity can't be checked). If one is signed out, its running agents pause
|
|
757
|
+
with their worktrees, commits and conversations kept, and the supervisor and
|
|
758
|
+
your session are told; a timeout or missing CLI never pauses, it warns once.
|
|
759
|
+
A wrong company identity pauses them only when the org policy enforces it
|
|
760
|
+
(Enterprise); otherwise it warns once. While it enforces, Claude agents run
|
|
761
|
+
on exactly the route brindle checked: a profile's env lines can't change the
|
|
762
|
+
backend, account, key or proxy, and other cloud and Claude credential variables
|
|
763
|
+
(`ANTHROPIC_*`, `AWS_*`, `GOOGLE_*`, `CLOUDSDK_*`, `AZURE_*`, ...) in your
|
|
764
|
+
environment or `brindle keys` are left out of their panes, so those agents
|
|
765
|
+
can't use your own AWS, Google Cloud or Azure access in their shell either.
|
|
766
|
+
Claude Code's own settings files can still set variables inside it; to rule
|
|
767
|
+
that out too, use Claude Code's managed settings. After `brindle login`,
|
|
768
|
+
`brindle doctor --fix` or the CLI's own login, the agents brindle paused resume
|
|
769
|
+
into their conversations, but only as the account they started under: if
|
|
770
|
+
someone else is signed in (a personal login, say) they stay paused until the
|
|
771
|
+
original account is back. Your own chat session is never paused, only the
|
|
772
|
+
workers. A cloud sign-in is re-checked only when its credential files or
|
|
773
|
+
variables change, so a token that expires silently isn't noticed until then.
|
|
774
|
+
`brindle doctor` lists agents paused for sign-in.
|
|
775
|
+
|
|
776
|
+
**Sessions stay with their identity.** Each Claude agent records the identity it
|
|
777
|
+
launched under (Claude org, AWS account and role, GCP project, Azure
|
|
778
|
+
subscription; ids only, never tokens). While a different identity is signed in,
|
|
779
|
+
that agent is locked: brindle refuses to resume it (`brindle continue`), rewind
|
|
780
|
+
it, message or hand off to it, start a new agent in its worktree (including
|
|
781
|
+
naming its branch for a new worker), or `peek` at it, with "This session
|
|
782
|
+
belongs to <org/account>; sign in as it to continue (`brindle login`)".
|
|
783
|
+
`brindle ls`, `watch`, the sidebar, `list_agents` and `agent_turns` show it as
|
|
784
|
+
`locked: <org/account>` without its conversation (usage, last activity, turn
|
|
785
|
+
summaries), and `depends_on` and `merge_workspace` won't pull its branch into a
|
|
786
|
+
session under another identity. Agents with no recorded identity (started before
|
|
787
|
+
this, or without a company setup) are unaffected, and so is everything while the
|
|
788
|
+
current identity can't be told (signed out, CLI missing).
|
|
789
|
+
|
|
790
|
+
This is a guard inside brindle, not a sandbox: on one OS user account the
|
|
791
|
+
worktrees, transcripts and credential files stay readable outside brindle (a
|
|
792
|
+
shell, another tool). Real separation needs a separate OS user or your
|
|
793
|
+
company's device management. Codex and Antigravity can't be told apart by
|
|
794
|
+
account (brindle only sees "signed in"), so their sessions are paused on
|
|
795
|
+
sign-out but can't be locked to one account; isolation applies to Claude routes
|
|
796
|
+
(subscription, Bedrock, Vertex, Foundry).
|
|
797
|
+
|
|
745
798
|
### Several repos in one session (brindle Pro)
|
|
746
799
|
|
|
747
800
|
A session can work across several repos. Attach another local repo you own
|
|
@@ -795,6 +848,16 @@ entitlement.
|
|
|
795
848
|
* `deny_personal_keys`: the personal model keys (`ANTHROPIC_API_KEY`,
|
|
796
849
|
`OPENAI_API_KEY`, ...) are taken out of every agent pane, and a profile that
|
|
797
850
|
sets one is refused.
|
|
851
|
+
* An org-owned key: with `provider` `anthropic` (or `openai-compatible`), set
|
|
852
|
+
`key_env` to the name of a variable that holds the org's key (not a personal
|
|
853
|
+
one like `ANTHROPIC_API_KEY`), or `key_helper` to a command, as a list of
|
|
854
|
+
arguments, that prints the key (for example `["vault", "kv", "get",
|
|
855
|
+
"-field=key", "secret/anthropic"]`). brindle runs the helper on the person's
|
|
856
|
+
machine, without a shell and with a timeout, each time a worker starts, and
|
|
857
|
+
gives the key to that worker as `ANTHROPIC_API_KEY` (`OPENAI_API_KEY` for
|
|
858
|
+
Codex). It passes `deny_personal_keys`; a personal key doesn't. The key never
|
|
859
|
+
goes through brindle's servers. When the variable is missing or the helper
|
|
860
|
+
fails, the worker doesn't start.
|
|
798
861
|
|
|
799
862
|
Two things to know when you turn on `deny_personal_keys`:
|
|
800
863
|
|
|
@@ -955,17 +1018,31 @@ workflows call these commands:
|
|
|
955
1018
|
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
956
1019
|
the branch you started on and deletes the local setup branch, so `git pull`
|
|
957
1020
|
after merging the setup pull request is clean (commit or stash your changes
|
|
958
|
-
first: it refuses to start with uncommitted work).
|
|
1021
|
+
first: it refuses to start with uncommitted work). With your own cloud
|
|
1022
|
+
(`--credential bedrock|vertex|foundry`, keyless GitHub OIDC) it can read the
|
|
1023
|
+
IDs from the deployment template's outputs instead of asking:
|
|
1024
|
+
`--from-stack NAME [--region R]` (AWS CloudFormation), `--from-terraform DIR`
|
|
1025
|
+
(Google) or `--from-deployment NAME -g RG` (Azure). They are defaults for
|
|
1026
|
+
`--cloud-var`, which still overrides them, and every ID is format-checked. A
|
|
1027
|
+
missing `aws`, `terraform` or `az` CLI or output is an error that names the
|
|
1028
|
+
`--cloud-var` to pass instead. Vertex AI and Microsoft Foundry are in
|
|
1029
|
+
**preview** (not yet verified end to end): `init` refuses them unless you pass
|
|
1030
|
+
`--preview` or set `BRINDLE_CI_PREVIEW_CLOUDS=1`, and `doctor` marks them
|
|
1031
|
+
`(preview)`. Bedrock is generally available.
|
|
959
1032
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
960
|
-
which providers CI may use on this repository.
|
|
1033
|
+
which providers CI may use on this repository. `--models` also makes one tiny
|
|
1034
|
+
call per pinned model and says why any is refused (a quota, a form not filled in).
|
|
961
1035
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
962
1036
|
or a validation of a pull request.
|
|
963
1037
|
- `brindle ci run`: run what was started: the supervisor and the result upload,
|
|
964
1038
|
or the pull request's checks and reviews and the evidence upload.
|
|
965
1039
|
- `brindle ci report`: tell the service how the workflow's jobs ended.
|
|
966
1040
|
|
|
967
|
-
Credential names are reported, never values.
|
|
968
|
-
|
|
1041
|
+
Credential names are reported, never values. CI uses API keys, cloud sign-ins
|
|
1042
|
+
(Bedrock, Vertex, Foundry) or identity federation only: a provider signed in
|
|
1043
|
+
only with a subscription (`CLAUDE_CODE_OAUTH_TOKEN`, a Codex ChatGPT login) is
|
|
1044
|
+
not used, on personal and organization repositories alike. Add an API key
|
|
1045
|
+
secret instead.
|
|
969
1046
|
|
|
970
1047
|
Fix builds only fix the default branch's *required* status checks, and a new
|
|
971
1048
|
repository has none. When the default branch requires none, `brindle ci init`
|
|
@@ -1198,7 +1275,7 @@ it's signed in without a plan that includes it, is reported to its supervisor.
|
|
|
1198
1275
|
| Provider | Key login (environment variables) |
|
|
1199
1276
|
|---|---|
|
|
1200
1277
|
| `claude` | yes: `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `CLAUDE_CODE_OAUTH_TOKEN`, or Bedrock/Vertex/Foundry (`CLAUDE_CODE_USE_BEDROCK`, `CLAUDE_CODE_USE_VERTEX`, `CLAUDE_CODE_USE_FOUNDRY`) |
|
|
1201
|
-
| `codex` | yes: `OPENAI_API_KEY`, `CODEX_API_KEY` |
|
|
1278
|
+
| `codex` | yes: `OPENAI_API_KEY`, `CODEX_API_KEY`. With Codex signed in with ChatGPT (checked on Codex CLI 0.162.0): interactive `codex`, which brindle runs in agent panes, ignores both keys and uses the ChatGPT plan, and only `codex login --with-api-key` switches it to a key; headless `codex exec` (Brindle-CI) bills `CODEX_API_KEY` over the login and ignores `OPENAI_API_KEY`. `brindle doctor` and `brindle keys set` say so, and `auth: api_key` on an interactive Codex profile is refused under a ChatGPT login (run `codex login --with-api-key`, or use `auth: subscription`) |
|
|
1202
1279
|
| `antigravity` | `GEMINI_API_KEY`, only with `"modelProvider": "gemini"` in `agy`'s `settings.json` (see [Google Antigravity](#google-antigravity)); otherwise `agy`'s own browser sign-in |
|
|
1203
1280
|
|
|
1204
1281
|
Workers that run unattended should use key login where the CLI supports it.
|
|
@@ -1210,6 +1287,16 @@ needs no browser step. Put the key in your environment, or in a profile's
|
|
|
1210
1287
|
`brindle doctor` names the variable each CLI gets, from your shell or from
|
|
1211
1288
|
which profiles.
|
|
1212
1289
|
|
|
1290
|
+
A profile chooses between the two with `auth`:
|
|
1291
|
+
|
|
1292
|
+
| `auth:` | What the worker signs in with |
|
|
1293
|
+
|---|---|
|
|
1294
|
+
| `auto` (default) | A key from your environment or `brindle keys` if there is one, else the CLI's own login. |
|
|
1295
|
+
| `subscription` | Always the CLI's own login: brindle strips that provider's API keys from the pane. |
|
|
1296
|
+
| `api_key` | Only a key: the worker refuses to start without one. |
|
|
1297
|
+
|
|
1298
|
+
Your org's `deny_personal_keys` (Enterprise) still applies on top of `auth`.
|
|
1299
|
+
|
|
1213
1300
|
### Cheap workers
|
|
1214
1301
|
|
|
1215
1302
|
By default a Claude Code worker loads everything your own `claude` does: your
|
|
@@ -1596,6 +1683,30 @@ marks the agent idle and delivers any queued message. Codex has no Stop hook, so
|
|
|
1596
1683
|
an autopilot supervisor on Codex that turn end is also where brindle tells it to keep
|
|
1597
1684
|
going, with the same limit on reminders as Claude Code.
|
|
1598
1685
|
|
|
1686
|
+
### Using your company's access
|
|
1687
|
+
|
|
1688
|
+
Two ways to run brindle's agents on your company's Claude (Bedrock, Vertex,
|
|
1689
|
+
Foundry, a Team or Enterprise plan) and Codex, without handling keys:
|
|
1690
|
+
|
|
1691
|
+
- **Your org sets it up (brindle Team).** When your org's policy has an
|
|
1692
|
+
`agent_setup` block, `brindle login` (and `brindle doctor --fix`) signs you
|
|
1693
|
+
in to the route the company chose and `brindle doctor` shows which identity
|
|
1694
|
+
each agent uses. It always wins over anything below.
|
|
1695
|
+
- **You set it up yourself (any plan).** When your org has no `agent_setup`,
|
|
1696
|
+
`brindle login` looks, read-only, at what this machine is already signed in
|
|
1697
|
+
to: Claude Code's managed settings (if your IT configures Claude Code,
|
|
1698
|
+
brindle just uses it), `claude auth status`, AWS SSO profiles in
|
|
1699
|
+
`~/.aws/config`, the active `gcloud` project, the active `az` subscription
|
|
1700
|
+
and `codex login status`. It never reads tokens or credential files. It
|
|
1701
|
+
proposes what it found ("Use Bedrock (AWS 1234…, role Dev, us-east-1)?");
|
|
1702
|
+
the default is no, and with no terminal it is always no. A yes is saved as
|
|
1703
|
+
`"agent_setup"` in `~/.brindle/config.json`, in the same format as the org
|
|
1704
|
+
policy's (`enforce` is never applied to it), and `brindle doctor` labels it
|
|
1705
|
+
as self-serve and says who is billed.
|
|
1706
|
+
|
|
1707
|
+
You must be authorized to use any company credentials you connect: brindle only
|
|
1708
|
+
signs in with the access you already have, it doesn't grant any.
|
|
1709
|
+
|
|
1599
1710
|
## Google Antigravity
|
|
1600
1711
|
|
|
1601
1712
|
brindle runs Google Antigravity's terminal agent, `agy`, as well as Claude Code and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "brindle"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.1"
|
|
4
4
|
description = "Run coding agents in parallel, each on its own git branch, with a supervisor that delegates, reviews, and merges"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -52,6 +52,8 @@ audit_export = "brindle.pro.audit_export:make"
|
|
|
52
52
|
dev = [
|
|
53
53
|
"pytest>=8",
|
|
54
54
|
"pytest-xdist>=3.8.0",
|
|
55
|
+
"python-hcl2>=8.1.4",
|
|
56
|
+
"pyyaml>=6.0.3",
|
|
55
57
|
]
|
|
56
58
|
|
|
57
59
|
[build-system]
|