brindle 0.0.4__tar.gz → 0.0.6__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.0.4 → brindle-0.0.6}/PKG-INFO +49 -6
- {brindle-0.0.4 → brindle-0.0.6}/README.md +48 -5
- {brindle-0.0.4 → brindle-0.0.6}/pyproject.toml +1 -1
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/ci_adapters.py +2 -1
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/ci_client.py +458 -71
- brindle-0.0.6/src/brindle/ci_federation.py +402 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/cli.py +22 -4
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/tmux.py +57 -0
- {brindle-0.0.4 → brindle-0.0.6}/.gitignore +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/LICENSE +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/SCHEDULE-A +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/__init__.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/__main__.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/account.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/agents.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/airgap.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/antigravity.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/autopilot.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/__init__.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-codex.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-heavy.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer-local.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/developer.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer-codex.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer-local.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/reviewer.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/subagent.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/builtin_agents/supervisor.md +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/codemap.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/codex_hook.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/config.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/cull.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/db.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/demo.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/detect.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/doctor.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/events.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/gates.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/git.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/history.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/inbox.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/learning.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/legacy.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/mcp_server.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/__init__.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/client.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/loop.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/permissions.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/runner.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/serve.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/native/tools.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/permissions.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pipeline.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/plugins.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/policy.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pool.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/__init__.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/_files.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/account.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/audit_chain.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/auth.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/credentials.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/features.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/keys.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/learning.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/license.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/loopback.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/orgkey.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/settings_sync.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/team_events.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/pro/team_policy.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/procs.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/profiles.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/providers.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/quota.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/repo_cmds.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/repos.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/savings.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/scratch.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/services.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/sessions.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/sidebar_follow.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/status_cache.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/tasks.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/usage.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/view.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/watch.py +0 -0
- {brindle-0.0.4 → brindle-0.0.6}/src/brindle/workspaces.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: brindle
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
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.0.
|
|
92
|
+
session shows it too (`brindle 0.0.6`). 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
|
|
@@ -148,7 +148,15 @@ a dim ◇ instead, because the supervisor reviews it.
|
|
|
148
148
|
|
|
149
149
|
**Copying chat text.** Drag with the mouse in the chat: the selection stays inside
|
|
150
150
|
that pane and is copied to the system clipboard (`pbcopy`, `wl-copy` or `xclip`;
|
|
151
|
-
`brindle doctor` shows which)
|
|
151
|
+
`brindle doctor` shows which); a double or triple click copies the word or line.
|
|
152
|
+
tmux keeps the mouse in the chat even though Claude Code asks to track it, so a
|
|
153
|
+
click only focuses the pane (and can't park Claude Code's focus in a dialog where
|
|
154
|
+
Esc stops working); the wheel still scrolls the chat. If Claude Code's Settings
|
|
155
|
+
dialog (`/usage`, `/config`) ever ignores Esc, its filter box has the focus: press
|
|
156
|
+
Esc up to three times (clear, leave the box, close), or `↓` then Esc. Don't reach
|
|
157
|
+
for Ctrl-C twice, which quits Claude Code and pauses the session.
|
|
158
|
+
|
|
159
|
+
**Hiding the sidebar.** `h` in the sidebar hides it without quitting brindle
|
|
152
160
|
(the chat zooms; `Ctrl-b S` brings it back), and `Ctrl-b z` zooms the chat by hand.
|
|
153
161
|
If the sidebar got left behind in another tmux session, `Ctrl-b S` in a window
|
|
154
162
|
without one pulls it here, as does `brindle sidebar` (it restarts a sidebar that was closed).
|
|
@@ -820,7 +828,12 @@ workflows call these commands:
|
|
|
820
828
|
checkout of the repository. For Claude it asks whether to use an API key
|
|
821
829
|
(the `ANTHROPIC_API_KEY` secret) or Anthropic
|
|
822
830
|
[workload identity federation](https://platform.claude.com/docs/en/manage-claude/wif-reference)
|
|
823
|
-
(`--credential key|federation` answers without asking).
|
|
831
|
+
(`--credential key|federation` answers without asking). It also creates the
|
|
832
|
+
`brindle` issue label (label an issue with it to hand it to brindle CI), and
|
|
833
|
+
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
834
|
+
the branch you started on and deletes the local setup branch, so `git pull`
|
|
835
|
+
after merging the setup pull request is clean (commit or stash your changes
|
|
836
|
+
first: it refuses to start with uncommitted work).
|
|
824
837
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
825
838
|
which providers CI may use on this repository.
|
|
826
839
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
@@ -832,6 +845,16 @@ workflows call these commands:
|
|
|
832
845
|
Credential names are reported, never values. On a repository owned by a GitHub
|
|
833
846
|
organization, a provider signed in only with a personal subscription is not used.
|
|
834
847
|
|
|
848
|
+
Fix builds only fix the default branch's *required* status checks, and a new
|
|
849
|
+
repository has none. When the default branch requires none, `brindle ci init`
|
|
850
|
+
warns and, for each job in your workflows, asks whether to make it required
|
|
851
|
+
(`--required-check NAME` picks one without asking, `--no-required-check` only
|
|
852
|
+
warns; run without a terminal, init only makes a check required when
|
|
853
|
+
`--required-check` names it). It adds the check to the branch's existing protection, or protects the
|
|
854
|
+
branch with just that check. GitHub only allows branch protection on a private
|
|
855
|
+
repository with a paid plan; when it refuses, init says how to require the
|
|
856
|
+
check yourself (Settings > Branches, "Require status checks to pass").
|
|
857
|
+
|
|
835
858
|
An Anthropic API key is either a workspace key (scoped to one workspace) or an
|
|
836
859
|
organization-level key (not scoped to a workspace). An organization-level key
|
|
837
860
|
needs the workspace in every request, so after the key `brindle ci init` asks for
|
|
@@ -848,20 +871,40 @@ organization repositories), and gives the job `ANTHROPIC_AUTH_TOKEN`. `brindle
|
|
|
848
871
|
ci init` stores the rule, organization, service account and optional workspace
|
|
849
872
|
IDs as the Actions variables `ANTHROPIC_FEDERATION_RULE_ID`,
|
|
850
873
|
`ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` and
|
|
851
|
-
`ANTHROPIC_WORKSPACE_ID
|
|
874
|
+
`ANTHROPIC_WORKSPACE_ID`, from `--rule-id`, `--organization-id`,
|
|
875
|
+
`--service-account-id` and `--workspace-id` or else asked (defaulting to those
|
|
876
|
+
environment variables). Without a terminal on stdin, init asks nothing and
|
|
877
|
+
takes the options and the environment, so it can run unattended; a missing or
|
|
878
|
+
malformed ID (rule `fdrl_...`, organization a UUID, service account
|
|
879
|
+
`svac_...`, workspace `wrkspc_...`) stops it before it creates the CI token.
|
|
880
|
+
The ID options imply `--credential federation` and can't be combined with
|
|
881
|
+
`--credential key`. Create the federation rule in the Claude Console with
|
|
852
882
|
subject prefix `repo:<owner>/<name>:*`, the condition
|
|
853
883
|
|
|
854
884
|
```text
|
|
855
885
|
claims.repository == "<owner>/<name>" && claims.workflow_ref.startsWith("<owner>/<name>/.github/workflows/brindle-ci-")
|
|
856
886
|
```
|
|
857
887
|
|
|
858
|
-
audience `https://api.anthropic.com`, and a token lifetime of at least
|
|
888
|
+
audience `https://api.anthropic.com`, and a token lifetime of at least 600
|
|
859
889
|
seconds. The condition lets only brindle's workflows mint tokens. On pull
|
|
860
890
|
requests the pull request's own copy of the validate workflow runs, so give
|
|
861
891
|
write access only to people you trust (forks never get a token). Leave the `ANTHROPIC_API_KEY` secret
|
|
862
892
|
unset: a key takes precedence (brindle drops an empty one before Claude Code
|
|
863
893
|
starts).
|
|
864
894
|
|
|
895
|
+
A federated token lives at most about ten minutes, however long the rule
|
|
896
|
+
allows: Anthropic caps it at twice what remains of GitHub's OIDC token. So
|
|
897
|
+
the run job doesn't rely on the workflow's one exchange: `brindle ci run`
|
|
898
|
+
fetches a fresh OIDC token and exchanges it again at 70% of each token's
|
|
899
|
+
life, and lends the current token to the agents through a proxy on the
|
|
900
|
+
runner's loopback interface. The agents get `ANTHROPIC_BASE_URL` pointing at
|
|
901
|
+
it and a random per-run secret as `ANTHROPIC_AUTH_TOKEN`; the Anthropic token
|
|
902
|
+
itself stays in the `brindle ci run` process, and the GitHub token endpoint
|
|
903
|
+
(`ACTIONS_ID_TOKEN_REQUEST_URL` and its token) is scrubbed before any agent or
|
|
904
|
+
check starts. If the first exchange fails, the run goes on with the
|
|
905
|
+
workflow's token as before; `BRINDLE_CI_FEDERATION_REFRESH=0` in the job's
|
|
906
|
+
environment turns the refresh off.
|
|
907
|
+
|
|
865
908
|
**Closing and cleaning up.** Press `x` on an agent in the sidebar (twice for one
|
|
866
909
|
that's still running) or run `brindle close <id>` to stop it and hide it. Stopping means
|
|
867
910
|
every process of the agent, not just its window: Claude Code can host a session in its
|
|
@@ -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.0.
|
|
62
|
+
session shows it too (`brindle 0.0.6`). 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
|
|
@@ -118,7 +118,15 @@ a dim ◇ instead, because the supervisor reviews it.
|
|
|
118
118
|
|
|
119
119
|
**Copying chat text.** Drag with the mouse in the chat: the selection stays inside
|
|
120
120
|
that pane and is copied to the system clipboard (`pbcopy`, `wl-copy` or `xclip`;
|
|
121
|
-
`brindle doctor` shows which)
|
|
121
|
+
`brindle doctor` shows which); a double or triple click copies the word or line.
|
|
122
|
+
tmux keeps the mouse in the chat even though Claude Code asks to track it, so a
|
|
123
|
+
click only focuses the pane (and can't park Claude Code's focus in a dialog where
|
|
124
|
+
Esc stops working); the wheel still scrolls the chat. If Claude Code's Settings
|
|
125
|
+
dialog (`/usage`, `/config`) ever ignores Esc, its filter box has the focus: press
|
|
126
|
+
Esc up to three times (clear, leave the box, close), or `↓` then Esc. Don't reach
|
|
127
|
+
for Ctrl-C twice, which quits Claude Code and pauses the session.
|
|
128
|
+
|
|
129
|
+
**Hiding the sidebar.** `h` in the sidebar hides it without quitting brindle
|
|
122
130
|
(the chat zooms; `Ctrl-b S` brings it back), and `Ctrl-b z` zooms the chat by hand.
|
|
123
131
|
If the sidebar got left behind in another tmux session, `Ctrl-b S` in a window
|
|
124
132
|
without one pulls it here, as does `brindle sidebar` (it restarts a sidebar that was closed).
|
|
@@ -790,7 +798,12 @@ workflows call these commands:
|
|
|
790
798
|
checkout of the repository. For Claude it asks whether to use an API key
|
|
791
799
|
(the `ANTHROPIC_API_KEY` secret) or Anthropic
|
|
792
800
|
[workload identity federation](https://platform.claude.com/docs/en/manage-claude/wif-reference)
|
|
793
|
-
(`--credential key|federation` answers without asking).
|
|
801
|
+
(`--credential key|federation` answers without asking). It also creates the
|
|
802
|
+
`brindle` issue label (label an issue with it to hand it to brindle CI), and
|
|
803
|
+
commits the workflows on a `brindle/ci-setup` branch, then puts you back on
|
|
804
|
+
the branch you started on and deletes the local setup branch, so `git pull`
|
|
805
|
+
after merging the setup pull request is clean (commit or stash your changes
|
|
806
|
+
first: it refuses to start with uncommitted work).
|
|
794
807
|
- `brindle ci doctor`: which provider CLIs and credential names a runner has, and
|
|
795
808
|
which providers CI may use on this repository.
|
|
796
809
|
- `brindle ci start`: start a run for an issue, a goal text or a dispatched run,
|
|
@@ -802,6 +815,16 @@ workflows call these commands:
|
|
|
802
815
|
Credential names are reported, never values. On a repository owned by a GitHub
|
|
803
816
|
organization, a provider signed in only with a personal subscription is not used.
|
|
804
817
|
|
|
818
|
+
Fix builds only fix the default branch's *required* status checks, and a new
|
|
819
|
+
repository has none. When the default branch requires none, `brindle ci init`
|
|
820
|
+
warns and, for each job in your workflows, asks whether to make it required
|
|
821
|
+
(`--required-check NAME` picks one without asking, `--no-required-check` only
|
|
822
|
+
warns; run without a terminal, init only makes a check required when
|
|
823
|
+
`--required-check` names it). It adds the check to the branch's existing protection, or protects the
|
|
824
|
+
branch with just that check. GitHub only allows branch protection on a private
|
|
825
|
+
repository with a paid plan; when it refuses, init says how to require the
|
|
826
|
+
check yourself (Settings > Branches, "Require status checks to pass").
|
|
827
|
+
|
|
805
828
|
An Anthropic API key is either a workspace key (scoped to one workspace) or an
|
|
806
829
|
organization-level key (not scoped to a workspace). An organization-level key
|
|
807
830
|
needs the workspace in every request, so after the key `brindle ci init` asks for
|
|
@@ -818,20 +841,40 @@ organization repositories), and gives the job `ANTHROPIC_AUTH_TOKEN`. `brindle
|
|
|
818
841
|
ci init` stores the rule, organization, service account and optional workspace
|
|
819
842
|
IDs as the Actions variables `ANTHROPIC_FEDERATION_RULE_ID`,
|
|
820
843
|
`ANTHROPIC_ORGANIZATION_ID`, `ANTHROPIC_SERVICE_ACCOUNT_ID` and
|
|
821
|
-
`ANTHROPIC_WORKSPACE_ID
|
|
844
|
+
`ANTHROPIC_WORKSPACE_ID`, from `--rule-id`, `--organization-id`,
|
|
845
|
+
`--service-account-id` and `--workspace-id` or else asked (defaulting to those
|
|
846
|
+
environment variables). Without a terminal on stdin, init asks nothing and
|
|
847
|
+
takes the options and the environment, so it can run unattended; a missing or
|
|
848
|
+
malformed ID (rule `fdrl_...`, organization a UUID, service account
|
|
849
|
+
`svac_...`, workspace `wrkspc_...`) stops it before it creates the CI token.
|
|
850
|
+
The ID options imply `--credential federation` and can't be combined with
|
|
851
|
+
`--credential key`. Create the federation rule in the Claude Console with
|
|
822
852
|
subject prefix `repo:<owner>/<name>:*`, the condition
|
|
823
853
|
|
|
824
854
|
```text
|
|
825
855
|
claims.repository == "<owner>/<name>" && claims.workflow_ref.startsWith("<owner>/<name>/.github/workflows/brindle-ci-")
|
|
826
856
|
```
|
|
827
857
|
|
|
828
|
-
audience `https://api.anthropic.com`, and a token lifetime of at least
|
|
858
|
+
audience `https://api.anthropic.com`, and a token lifetime of at least 600
|
|
829
859
|
seconds. The condition lets only brindle's workflows mint tokens. On pull
|
|
830
860
|
requests the pull request's own copy of the validate workflow runs, so give
|
|
831
861
|
write access only to people you trust (forks never get a token). Leave the `ANTHROPIC_API_KEY` secret
|
|
832
862
|
unset: a key takes precedence (brindle drops an empty one before Claude Code
|
|
833
863
|
starts).
|
|
834
864
|
|
|
865
|
+
A federated token lives at most about ten minutes, however long the rule
|
|
866
|
+
allows: Anthropic caps it at twice what remains of GitHub's OIDC token. So
|
|
867
|
+
the run job doesn't rely on the workflow's one exchange: `brindle ci run`
|
|
868
|
+
fetches a fresh OIDC token and exchanges it again at 70% of each token's
|
|
869
|
+
life, and lends the current token to the agents through a proxy on the
|
|
870
|
+
runner's loopback interface. The agents get `ANTHROPIC_BASE_URL` pointing at
|
|
871
|
+
it and a random per-run secret as `ANTHROPIC_AUTH_TOKEN`; the Anthropic token
|
|
872
|
+
itself stays in the `brindle ci run` process, and the GitHub token endpoint
|
|
873
|
+
(`ACTIONS_ID_TOKEN_REQUEST_URL` and its token) is scrubbed before any agent or
|
|
874
|
+
check starts. If the first exchange fails, the run goes on with the
|
|
875
|
+
workflow's token as before; `BRINDLE_CI_FEDERATION_REFRESH=0` in the job's
|
|
876
|
+
environment turns the refresh off.
|
|
877
|
+
|
|
835
878
|
**Closing and cleaning up.** Press `x` on an agent in the sidebar (twice for one
|
|
836
879
|
that's still running) or run `brindle close <id>` to stop it and hide it. Stopping means
|
|
837
880
|
every process of the agent, not just its window: Claude Code can host a session in its
|
|
@@ -11,7 +11,8 @@ An adapter answers four questions and does three things:
|
|
|
11
11
|
endpoint without a key, or a personal subscription (``CLAUDE_CODE_OAUTH_TOKEN``;
|
|
12
12
|
a ChatGPT login for Codex). Anthropic workload identity federation reaches
|
|
13
13
|
here as an API key: the workflow exchanges GitHub's OIDC token once and
|
|
14
|
-
gives the job ``ANTHROPIC_AUTH_TOKEN
|
|
14
|
+
gives the job ``ANTHROPIC_AUTH_TOKEN``; during the run that variable holds
|
|
15
|
+
the secret of brindle's own credential proxy (:mod:`brindle.ci_federation`).
|
|
15
16
|
* ``available(env)``: installed and holding some credential.
|
|
16
17
|
* ``launch``: start a brindle autopilot supervisor with the plan's instructions.
|
|
17
18
|
* ``review``: ask the model one question (the plan's instructions) and return
|