brindle 0.2.0__tar.gz → 0.3.0__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.0 → brindle-0.3.0}/.gitignore +1 -0
- {brindle-0.2.0 → brindle-0.3.0}/PKG-INFO +52 -11
- {brindle-0.2.0 → brindle-0.3.0}/README.md +51 -10
- {brindle-0.2.0 → brindle-0.3.0}/pyproject.toml +3 -1
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/agents.py +205 -128
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/autopilot.py +77 -14
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/budget.py +46 -5
- brindle-0.3.0/src/brindle/builtin_agents/developer-codex.md +6 -0
- brindle-0.3.0/src/brindle/builtin_agents/developer-heavy.md +7 -0
- brindle-0.3.0/src/brindle/builtin_agents/developer-light.md +7 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/developer.md +4 -3
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/reviewer-codex.md +4 -9
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/reviewer-local.md +3 -6
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/reviewer.md +4 -9
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/ci_adapters.py +83 -11
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/ci_client.py +368 -13
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/ci_federation.py +250 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/ci_hosts.py +65 -6
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/cli.py +129 -14
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/config.py +32 -4
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/cost.py +149 -1
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/cull.py +61 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/db.py +45 -3
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/doctor.py +80 -0
- brindle-0.3.0/src/brindle/escapes.py +176 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/gates.py +82 -20
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/history.py +2 -1
- brindle-0.3.0/src/brindle/keys_cmds.py +103 -0
- brindle-0.2.0/src/brindle/pro/credentials.py → brindle-0.3.0/src/brindle/keystore.py +145 -39
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/learning.py +31 -6
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/mcp_server.py +47 -28
- brindle-0.3.0/src/brindle/model_access.py +293 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/runner.py +4 -1
- brindle-0.3.0/src/brindle/pane_auth.py +56 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pipeline.py +111 -11
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pool.py +15 -11
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pricing.py +2 -1
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/account.py +68 -8
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/auth.py +29 -6
- brindle-0.3.0/src/brindle/pro/brief_learning.py +164 -0
- brindle-0.3.0/src/brindle/pro/credentials.py +53 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/learning.py +71 -6
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/managed_models.py +53 -3
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/org_profiles.py +33 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/team_policy.py +58 -5
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/procs.py +23 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/profiles.py +33 -2
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/providers.py +162 -9
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/quota.py +14 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/secrets.py +54 -8
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/watch_costs.py +7 -2
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/workspaces.py +27 -7
- brindle-0.2.0/src/brindle/builtin_agents/developer-codex.md +0 -21
- brindle-0.2.0/src/brindle/builtin_agents/developer-heavy.md +0 -23
- {brindle-0.2.0 → brindle-0.3.0}/LICENSE +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/SCHEDULE-A +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/__init__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/__main__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/account.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/airgap.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/antigravity.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/__init__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/backend-auditor.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/developer-local.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/qa.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/subagent.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_agents/supervisor.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_rules/__init__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_rules/security/backend.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_rules/style/minimal-diff.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/builtin_rules/tests/only.md +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/codemap.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/codex_hook.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/conflicts.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/cost_estimate.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/demo.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/detect.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/events.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/git.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/guardrails.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/inbox.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/learned_rules.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/legacy.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/__init__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/client.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/loop.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/permissions.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/serve.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/native/tools.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/permissions.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/plugins.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/policy.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/__init__.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/_files.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/audit_chain.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/audit_export.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/cost_centers.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/features.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/keys.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/license.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/loopback.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/orgkey.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/rollout.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/settings_sync.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/status.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/pro/team_events.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/repo_cmds.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/repos.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/rewind.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/rule_checks.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/savings.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/scratch.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/services.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/sessions.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/sidebar_follow.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/status_cache.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/tasks.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/tmux.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/usage.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/view.py +0 -0
- {brindle-0.2.0 → brindle-0.3.0}/src/brindle/watch.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brindle
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
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.0`). 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 |
|
|
@@ -360,7 +361,8 @@ your own status line prints, so what you see doesn't change.
|
|
|
360
361
|
| `brindle cost requests` | Enterprise: your approval requests and their status; checks pending ones with the server (the cull pass also does, every few minutes). With cost centers, spend events also carry the repo (`owner/name`) so the org can total spend per center |
|
|
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
|
-
| `brindle
|
|
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 |
|
|
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) |
|
|
364
366
|
| `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) |
|
|
365
367
|
| `brindle watch [--all] [--once]` | the dashboard on its own (the same view as the sidebar): enter attaches, `p` peeks, `x` closes |
|
|
366
368
|
| `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 |
|
|
@@ -525,6 +527,7 @@ Autopilot, merge gates and cleanup:
|
|
|
525
527
|
| `max_agents` | `4` | workers running at once per session (`0`: no cap) |
|
|
526
528
|
| `check_timeout` | `900` | seconds each check may take |
|
|
527
529
|
| `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 |
|
|
530
|
+
| `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 |
|
|
528
531
|
| `usage_limit` | `90` | autopilot stops pushing on at this % of your Claude usage limit |
|
|
529
532
|
| `limit_cooldown_minutes` | `300` for Antigravity | how long a provider that hit its limit counts as unavailable |
|
|
530
533
|
| `graphify` | if the graph is there | point agents at the repo's [graphify](https://github.com/safishamsi/graphify) code map (`false` turns it off) |
|
|
@@ -588,9 +591,9 @@ keep theirs):
|
|
|
588
591
|
```json
|
|
589
592
|
{
|
|
590
593
|
"routing": {
|
|
591
|
-
"light": ["developer", "developer-codex", "developer-local"],
|
|
594
|
+
"light": ["developer-light", "developer", "developer-codex", "developer-local"],
|
|
592
595
|
"medium": ["developer", "developer-codex", "developer-heavy"],
|
|
593
|
-
"heavy": ["developer
|
|
596
|
+
"heavy": ["developer", "developer-heavy", "developer-codex"]
|
|
594
597
|
}
|
|
595
598
|
}
|
|
596
599
|
```
|
|
@@ -598,7 +601,9 @@ keep theirs):
|
|
|
598
601
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
599
602
|
be what works best for you, and that's for the learner to find out.
|
|
600
603
|
|
|
601
|
-
`developer-
|
|
604
|
+
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
605
|
+
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
606
|
+
at high effort.
|
|
602
607
|
A profile is skipped when its CLI isn't installed (`claude`, `codex`, `agy`), the
|
|
603
608
|
local model server isn't answering, or its provider is at your `usage_limit`. If
|
|
604
609
|
hosted learning is on it chooses among the profiles left; otherwise the first
|
|
@@ -761,7 +766,9 @@ brindle account login # opens your browser to sign in (--device: enter a co
|
|
|
761
766
|
brindle account status # your plan, features, hosted learning on or off, when the entitlement expires
|
|
762
767
|
brindle account savings # what hosted learning's picks gained in this repo, this month and last: estimates, from this machine's records only
|
|
763
768
|
brindle account upgrade # opens the checkout for brindle Pro (and prints its URL)
|
|
764
|
-
brindle account
|
|
769
|
+
brindle account upgrade --enterprise [--trial] --seats N --org ORG # brindle Enterprise for a team org; --trial: free trial, at most 10 seats
|
|
770
|
+
brindle account portal # opens the billing portal (invoices, payment method, cancellation); --org ORG for a team org
|
|
771
|
+
brindle account seats N # set a Team or Enterprise org's seat count (billing admin); --org ORG; Stripe prorates the change
|
|
765
772
|
brindle account org list # the orgs you belong to; `org use <id>` switches, `org policy` shows the current one
|
|
766
773
|
brindle account org policy # the org's policy, its per-role overrides, and the policy that applies to you
|
|
767
774
|
brindle account org profiles # the org's shared profiles and rule packs, and which are pinned
|
|
@@ -824,6 +831,16 @@ entitlement.
|
|
|
824
831
|
* `deny_personal_keys`: the personal model keys (`ANTHROPIC_API_KEY`,
|
|
825
832
|
`OPENAI_API_KEY`, ...) are taken out of every agent pane, and a profile that
|
|
826
833
|
sets one is refused.
|
|
834
|
+
* An org-owned key: with `provider` `anthropic` (or `openai-compatible`), set
|
|
835
|
+
`key_env` to the name of a variable that holds the org's key (not a personal
|
|
836
|
+
one like `ANTHROPIC_API_KEY`), or `key_helper` to a command, as a list of
|
|
837
|
+
arguments, that prints the key (for example `["vault", "kv", "get",
|
|
838
|
+
"-field=key", "secret/anthropic"]`). brindle runs the helper on the person's
|
|
839
|
+
machine, without a shell and with a timeout, each time a worker starts, and
|
|
840
|
+
gives the key to that worker as `ANTHROPIC_API_KEY` (`OPENAI_API_KEY` for
|
|
841
|
+
Codex). It passes `deny_personal_keys`; a personal key doesn't. The key never
|
|
842
|
+
goes through brindle's servers. When the variable is missing or the helper
|
|
843
|
+
fails, the worker doesn't start.
|
|
827
844
|
|
|
828
845
|
Two things to know when you turn on `deny_personal_keys`:
|
|
829
846
|
|
|
@@ -984,17 +1001,31 @@ workflows call these commands:
|
|
|
984
1001
|
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
985
1002
|
the branch you started on and deletes the local setup branch, so `git pull`
|
|
986
1003
|
after merging the setup pull request is clean (commit or stash your changes
|
|
987
|
-
first: it refuses to start with uncommitted work).
|
|
1004
|
+
first: it refuses to start with uncommitted work). With your own cloud
|
|
1005
|
+
(`--credential bedrock|vertex|foundry`, keyless GitHub OIDC) it can read the
|
|
1006
|
+
IDs from the deployment template's outputs instead of asking:
|
|
1007
|
+
`--from-stack NAME [--region R]` (AWS CloudFormation), `--from-terraform DIR`
|
|
1008
|
+
(Google) or `--from-deployment NAME -g RG` (Azure). They are defaults for
|
|
1009
|
+
`--cloud-var`, which still overrides them, and every ID is format-checked. A
|
|
1010
|
+
missing `aws`, `terraform` or `az` CLI or output is an error that names the
|
|
1011
|
+
`--cloud-var` to pass instead. Vertex AI and Microsoft Foundry are in
|
|
1012
|
+
**preview** (not yet verified end to end): `init` refuses them unless you pass
|
|
1013
|
+
`--preview` or set `BRINDLE_CI_PREVIEW_CLOUDS=1`, and `doctor` marks them
|
|
1014
|
+
`(preview)`. Bedrock is generally available.
|
|
988
1015
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
989
|
-
which providers CI may use on this repository.
|
|
1016
|
+
which providers CI may use on this repository. `--models` also makes one tiny
|
|
1017
|
+
call per pinned model and says why any is refused (a quota, a form not filled in).
|
|
990
1018
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
991
1019
|
or a validation of a pull request.
|
|
992
1020
|
- `brindle ci run`: run what was started: the supervisor and the result upload,
|
|
993
1021
|
or the pull request's checks and reviews and the evidence upload.
|
|
994
1022
|
- `brindle ci report`: tell the service how the workflow's jobs ended.
|
|
995
1023
|
|
|
996
|
-
Credential names are reported, never values.
|
|
997
|
-
|
|
1024
|
+
Credential names are reported, never values. CI uses API keys, cloud sign-ins
|
|
1025
|
+
(Bedrock, Vertex, Foundry) or identity federation only: a provider signed in
|
|
1026
|
+
only with a subscription (`CLAUDE_CODE_OAUTH_TOKEN`, a Codex ChatGPT login) is
|
|
1027
|
+
not used, on personal and organization repositories alike. Add an API key
|
|
1028
|
+
secret instead.
|
|
998
1029
|
|
|
999
1030
|
Fix builds only fix the default branch's *required* status checks, and a new
|
|
1000
1031
|
repository has none. When the default branch requires none, `brindle ci init`
|
|
@@ -1239,6 +1270,16 @@ needs no browser step. Put the key in your environment, or in a profile's
|
|
|
1239
1270
|
`brindle doctor` names the variable each CLI gets, from your shell or from
|
|
1240
1271
|
which profiles.
|
|
1241
1272
|
|
|
1273
|
+
A profile chooses between the two with `auth`:
|
|
1274
|
+
|
|
1275
|
+
| `auth:` | What the worker signs in with |
|
|
1276
|
+
|---|---|
|
|
1277
|
+
| `auto` (default) | A key from your environment or `brindle keys` if there is one, else the CLI's own login. |
|
|
1278
|
+
| `subscription` | Always the CLI's own login: brindle strips that provider's API keys from the pane. |
|
|
1279
|
+
| `api_key` | Only a key: the worker refuses to start without one. |
|
|
1280
|
+
|
|
1281
|
+
Your org's `deny_personal_keys` (Enterprise) still applies on top of `auth`.
|
|
1282
|
+
|
|
1242
1283
|
### Cheap workers
|
|
1243
1284
|
|
|
1244
1285
|
By default a Claude Code worker loads everything your own `claude` does: your
|
|
@@ -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.0`). 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 |
|
|
@@ -330,7 +331,8 @@ your own status line prints, so what you see doesn't change.
|
|
|
330
331
|
| `brindle cost requests` | Enterprise: your approval requests and their status; checks pending ones with the server (the cull pass also does, every few minutes). With cost centers, spend events also carry the repo (`owner/name`) so the org can total spend per center |
|
|
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
|
-
| `brindle
|
|
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 |
|
|
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) |
|
|
334
336
|
| `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) |
|
|
335
337
|
| `brindle watch [--all] [--once]` | the dashboard on its own (the same view as the sidebar): enter attaches, `p` peeks, `x` closes |
|
|
336
338
|
| `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 |
|
|
@@ -495,6 +497,7 @@ Autopilot, merge gates and cleanup:
|
|
|
495
497
|
| `max_agents` | `4` | workers running at once per session (`0`: no cap) |
|
|
496
498
|
| `check_timeout` | `900` | seconds each check may take |
|
|
497
499
|
| `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 |
|
|
500
|
+
| `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 |
|
|
498
501
|
| `usage_limit` | `90` | autopilot stops pushing on at this % of your Claude usage limit |
|
|
499
502
|
| `limit_cooldown_minutes` | `300` for Antigravity | how long a provider that hit its limit counts as unavailable |
|
|
500
503
|
| `graphify` | if the graph is there | point agents at the repo's [graphify](https://github.com/safishamsi/graphify) code map (`false` turns it off) |
|
|
@@ -558,9 +561,9 @@ keep theirs):
|
|
|
558
561
|
```json
|
|
559
562
|
{
|
|
560
563
|
"routing": {
|
|
561
|
-
"light": ["developer", "developer-codex", "developer-local"],
|
|
564
|
+
"light": ["developer-light", "developer", "developer-codex", "developer-local"],
|
|
562
565
|
"medium": ["developer", "developer-codex", "developer-heavy"],
|
|
563
|
-
"heavy": ["developer
|
|
566
|
+
"heavy": ["developer", "developer-heavy", "developer-codex"]
|
|
564
567
|
}
|
|
565
568
|
}
|
|
566
569
|
```
|
|
@@ -568,7 +571,9 @@ keep theirs):
|
|
|
568
571
|
No tier prefers another provider for its own sake: all-Claude or all-Codex may
|
|
569
572
|
be what works best for you, and that's for the learner to find out.
|
|
570
573
|
|
|
571
|
-
`developer-
|
|
574
|
+
`developer-light` runs on Claude Haiku at low effort; `developer` on your Claude
|
|
575
|
+
Code default model; `developer-codex` on Codex; `developer-heavy` on Claude Fable
|
|
576
|
+
at high effort.
|
|
572
577
|
A profile is skipped when its CLI isn't installed (`claude`, `codex`, `agy`), the
|
|
573
578
|
local model server isn't answering, or its provider is at your `usage_limit`. If
|
|
574
579
|
hosted learning is on it chooses among the profiles left; otherwise the first
|
|
@@ -731,7 +736,9 @@ brindle account login # opens your browser to sign in (--device: enter a co
|
|
|
731
736
|
brindle account status # your plan, features, hosted learning on or off, when the entitlement expires
|
|
732
737
|
brindle account savings # what hosted learning's picks gained in this repo, this month and last: estimates, from this machine's records only
|
|
733
738
|
brindle account upgrade # opens the checkout for brindle Pro (and prints its URL)
|
|
734
|
-
brindle account
|
|
739
|
+
brindle account upgrade --enterprise [--trial] --seats N --org ORG # brindle Enterprise for a team org; --trial: free trial, at most 10 seats
|
|
740
|
+
brindle account portal # opens the billing portal (invoices, payment method, cancellation); --org ORG for a team org
|
|
741
|
+
brindle account seats N # set a Team or Enterprise org's seat count (billing admin); --org ORG; Stripe prorates the change
|
|
735
742
|
brindle account org list # the orgs you belong to; `org use <id>` switches, `org policy` shows the current one
|
|
736
743
|
brindle account org policy # the org's policy, its per-role overrides, and the policy that applies to you
|
|
737
744
|
brindle account org profiles # the org's shared profiles and rule packs, and which are pinned
|
|
@@ -794,6 +801,16 @@ entitlement.
|
|
|
794
801
|
* `deny_personal_keys`: the personal model keys (`ANTHROPIC_API_KEY`,
|
|
795
802
|
`OPENAI_API_KEY`, ...) are taken out of every agent pane, and a profile that
|
|
796
803
|
sets one is refused.
|
|
804
|
+
* An org-owned key: with `provider` `anthropic` (or `openai-compatible`), set
|
|
805
|
+
`key_env` to the name of a variable that holds the org's key (not a personal
|
|
806
|
+
one like `ANTHROPIC_API_KEY`), or `key_helper` to a command, as a list of
|
|
807
|
+
arguments, that prints the key (for example `["vault", "kv", "get",
|
|
808
|
+
"-field=key", "secret/anthropic"]`). brindle runs the helper on the person's
|
|
809
|
+
machine, without a shell and with a timeout, each time a worker starts, and
|
|
810
|
+
gives the key to that worker as `ANTHROPIC_API_KEY` (`OPENAI_API_KEY` for
|
|
811
|
+
Codex). It passes `deny_personal_keys`; a personal key doesn't. The key never
|
|
812
|
+
goes through brindle's servers. When the variable is missing or the helper
|
|
813
|
+
fails, the worker doesn't start.
|
|
797
814
|
|
|
798
815
|
Two things to know when you turn on `deny_personal_keys`:
|
|
799
816
|
|
|
@@ -954,17 +971,31 @@ workflows call these commands:
|
|
|
954
971
|
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
955
972
|
the branch you started on and deletes the local setup branch, so `git pull`
|
|
956
973
|
after merging the setup pull request is clean (commit or stash your changes
|
|
957
|
-
first: it refuses to start with uncommitted work).
|
|
974
|
+
first: it refuses to start with uncommitted work). With your own cloud
|
|
975
|
+
(`--credential bedrock|vertex|foundry`, keyless GitHub OIDC) it can read the
|
|
976
|
+
IDs from the deployment template's outputs instead of asking:
|
|
977
|
+
`--from-stack NAME [--region R]` (AWS CloudFormation), `--from-terraform DIR`
|
|
978
|
+
(Google) or `--from-deployment NAME -g RG` (Azure). They are defaults for
|
|
979
|
+
`--cloud-var`, which still overrides them, and every ID is format-checked. A
|
|
980
|
+
missing `aws`, `terraform` or `az` CLI or output is an error that names the
|
|
981
|
+
`--cloud-var` to pass instead. Vertex AI and Microsoft Foundry are in
|
|
982
|
+
**preview** (not yet verified end to end): `init` refuses them unless you pass
|
|
983
|
+
`--preview` or set `BRINDLE_CI_PREVIEW_CLOUDS=1`, and `doctor` marks them
|
|
984
|
+
`(preview)`. Bedrock is generally available.
|
|
958
985
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
959
|
-
which providers CI may use on this repository.
|
|
986
|
+
which providers CI may use on this repository. `--models` also makes one tiny
|
|
987
|
+
call per pinned model and says why any is refused (a quota, a form not filled in).
|
|
960
988
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
961
989
|
or a validation of a pull request.
|
|
962
990
|
- `brindle ci run`: run what was started: the supervisor and the result upload,
|
|
963
991
|
or the pull request's checks and reviews and the evidence upload.
|
|
964
992
|
- `brindle ci report`: tell the service how the workflow's jobs ended.
|
|
965
993
|
|
|
966
|
-
Credential names are reported, never values.
|
|
967
|
-
|
|
994
|
+
Credential names are reported, never values. CI uses API keys, cloud sign-ins
|
|
995
|
+
(Bedrock, Vertex, Foundry) or identity federation only: a provider signed in
|
|
996
|
+
only with a subscription (`CLAUDE_CODE_OAUTH_TOKEN`, a Codex ChatGPT login) is
|
|
997
|
+
not used, on personal and organization repositories alike. Add an API key
|
|
998
|
+
secret instead.
|
|
968
999
|
|
|
969
1000
|
Fix builds only fix the default branch's *required* status checks, and a new
|
|
970
1001
|
repository has none. When the default branch requires none, `brindle ci init`
|
|
@@ -1209,6 +1240,16 @@ needs no browser step. Put the key in your environment, or in a profile's
|
|
|
1209
1240
|
`brindle doctor` names the variable each CLI gets, from your shell or from
|
|
1210
1241
|
which profiles.
|
|
1211
1242
|
|
|
1243
|
+
A profile chooses between the two with `auth`:
|
|
1244
|
+
|
|
1245
|
+
| `auth:` | What the worker signs in with |
|
|
1246
|
+
|---|---|
|
|
1247
|
+
| `auto` (default) | A key from your environment or `brindle keys` if there is one, else the CLI's own login. |
|
|
1248
|
+
| `subscription` | Always the CLI's own login: brindle strips that provider's API keys from the pane. |
|
|
1249
|
+
| `api_key` | Only a key: the worker refuses to start without one. |
|
|
1250
|
+
|
|
1251
|
+
Your org's `deny_personal_keys` (Enterprise) still applies on top of `auth`.
|
|
1252
|
+
|
|
1212
1253
|
### Cheap workers
|
|
1213
1254
|
|
|
1214
1255
|
By default a Claude Code worker loads everything your own `claude` does: your
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "brindle"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.3.0"
|
|
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]
|