brichan 0.5.0__py3-none-any.whl
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.
- brichan-0.5.0.dist-info/METADATA +193 -0
- brichan-0.5.0.dist-info/RECORD +42 -0
- brichan-0.5.0.dist-info/WHEEL +5 -0
- brichan-0.5.0.dist-info/entry_points.txt +6 -0
- brichan-0.5.0.dist-info/licenses/LICENSE +21 -0
- brichan-0.5.0.dist-info/top_level.txt +1 -0
- brida/__init__.py +3 -0
- brida/cli/__init__.py +1 -0
- brida/cli/_root.py +23 -0
- brida/cli/claude.py +58 -0
- brida/cli/codex.py +118 -0
- brida/cli/provider_commands.py +404 -0
- brida/cli/runtime.py +197 -0
- brida/contracts/__init__.py +1 -0
- brida/contracts/receipts/__init__.py +13 -0
- brida/contracts/receipts/discovery.py +5 -0
- brida/contracts/receipts/parser.py +5 -0
- brida/contracts/receipts/schema.py +35 -0
- brida/contracts/receipts/validation.py +1177 -0
- brida/lifecycle.py +334 -0
- brida/orchestration/__init__.py +23 -0
- brida/orchestration/herdr_client.py +8 -0
- brida/orchestration/layout.py +5 -0
- brida/orchestration/model_routing.py +283 -0
- brida/orchestration/worker_launch.py +479 -0
- brida/project.py +64 -0
- brida/resources/__init__.py +1 -0
- brida/resources/dogfood_v1/__init__.py +1 -0
- brida/resources/dogfood_v1/config/model-routing.json +38 -0
- brida/resources/dogfood_v1/policy/bootstrap.md +23 -0
- brida/resources/dogfood_v1/policy/identity.md +18 -0
- brida/resources/dogfood_v1/policy/memory-policy.md +14 -0
- brida/resources/dogfood_v1/policy/operating-principles.md +13 -0
- brida/resources/dogfood_v1/project-memory/index.md +6 -0
- brida/resources/dogfood_v1/project-memory/main/current-state.md +9 -0
- brida/resources/dogfood_v1/project-memory/main/decisions.md +3 -0
- brida/resources/dogfood_v1/project-memory/main/overview.md +8 -0
- brida/resources/dogfood_v1/project-memory/main/references.md +3 -0
- brida/resources/dogfood_v1/project-memory/main/tasks.md +11 -0
- brida/resources/dogfood_v1/skills/herdr-orchestration/SKILL.md +25 -0
- brida/resources/dogfood_v1/skills/herdr-orchestration/references/commands.md +24 -0
- brida/resources/dogfood_v1/skills/herdr-orchestration/references/task-packet.md +39 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: brichan
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: Repository-native AI Chief of Staff orchestration
|
|
5
|
+
Author: Minh Tran
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Minh Tran
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Keywords: ai,orchestration,codex,claude-code,chief-of-staff
|
|
29
|
+
Classifier: Development Status :: 3 - Alpha
|
|
30
|
+
Classifier: Environment :: Console
|
|
31
|
+
Classifier: Intended Audience :: Developers
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Operating System :: POSIX
|
|
34
|
+
Classifier: Programming Language :: Python :: 3
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
39
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
40
|
+
Requires-Python: >=3.10
|
|
41
|
+
Description-Content-Type: text/markdown
|
|
42
|
+
License-File: LICENSE
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# Brichan
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
Brichan is an AI Chief of Staff for Codex and Claude Code. Give it a project
|
|
50
|
+
goal; it keeps the necessary context, coordinates independent workers through
|
|
51
|
+
Herdr, checks their evidence, and records useful project state outside chat.
|
|
52
|
+
Its existing runtime package and console commands remain `brida` and
|
|
53
|
+
`brida-*` for compatibility.
|
|
54
|
+
|
|
55
|
+
## Current dogfood scope
|
|
56
|
+
|
|
57
|
+
The primary one-user dogfood path is now an installed Python package running
|
|
58
|
+
inside an existing top-level Git repository. Installed-project mode currently
|
|
59
|
+
supports Codex on POSIX-compatible systems with Python 3.10+. Herdr is needed
|
|
60
|
+
only when Brida coordinates independent worker sessions.
|
|
61
|
+
|
|
62
|
+
Brida is not published to a package registry yet; the planned PyPI
|
|
63
|
+
distribution name is `brichan` (`pip install brichan`), while the importable
|
|
64
|
+
package stays `brida` and every console command keeps its existing name.
|
|
65
|
+
Until it is published, build the wheel locally from this repository with the
|
|
66
|
+
installer. It can be invoked from any directory and does not activate or
|
|
67
|
+
modify the target project's virtual environment:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
/absolute/path/to/brida/scripts/install-brida
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
By default, the script creates a dedicated environment at
|
|
74
|
+
`$HOME/.local/share/brida/venv` and command symlinks in `$HOME/.local/bin`.
|
|
75
|
+
It automatically selects an available Python 3.10+ interpreter with `pip`,
|
|
76
|
+
`setuptools`, `venv`, and `wheel`, builds from a temporary source snapshot,
|
|
77
|
+
and installs all Brida console commands. No virtualenv activation is
|
|
78
|
+
required. If the command directory is not on `PATH`, the installer prints
|
|
79
|
+
the exact export to add to the shell profile.
|
|
80
|
+
|
|
81
|
+
## Initialize a project
|
|
82
|
+
|
|
83
|
+
Preview the complete footprint before writing:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
brida init --project /absolute/path/to/repository
|
|
87
|
+
brida init --apply --project /absolute/path/to/repository
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`init` defaults to dry-run and performs zero writes. `--apply` creates only a
|
|
91
|
+
versioned `.brida/` directory containing managed policy, model routing, Herdr
|
|
92
|
+
skill resources, and mutable project memory. Repeating it against healthy
|
|
93
|
+
state is idempotent.
|
|
94
|
+
|
|
95
|
+
Diagnose and launch from any directory with an explicit target:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
brida status --project /absolute/path/to/repository
|
|
99
|
+
brida doctor --project /absolute/path/to/repository
|
|
100
|
+
brida run --project /absolute/path/to/repository -- <codex arguments>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
From inside a healthy initialized repository, bare `brida` also launches
|
|
104
|
+
Codex. The installed entrypoint:
|
|
105
|
+
|
|
106
|
+
- leaves `AGENTS.md`, `CLAUDE.md`, `.codex/`, and provider configuration
|
|
107
|
+
untouched;
|
|
108
|
+
- launches external `codex` directly at the target root and never executes
|
|
109
|
+
target-owned `bin/brida-*` wrappers;
|
|
110
|
+
- injects package-owned Brida policy and Herdr skill discovery;
|
|
111
|
+
- rejects native delegation, permission bypasses, cwd/scope widening, profiles,
|
|
112
|
+
remote execution, and arbitrary Codex configuration before `--`;
|
|
113
|
+
- treats option-looking text after `--` as literal prompt content.
|
|
114
|
+
|
|
115
|
+
State diagnostics reject malformed, dangling, symlinked, inaccessible, or
|
|
116
|
+
incompatible `.brida/` state without silently repairing it. Schema v1 has no
|
|
117
|
+
automatic migration: package-version changes require deliberate backup and
|
|
118
|
+
reinitialization. See the
|
|
119
|
+
[installed Codex dogfood guide](docs/guides/installable-dogfood.md) for the
|
|
120
|
+
exact footprint, exit codes, safeguards, and compatibility boundary.
|
|
121
|
+
|
|
122
|
+
## Checkout compatibility and development
|
|
123
|
+
|
|
124
|
+
The original checkout workflow remains available for development and for
|
|
125
|
+
Claude Code:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
bin/brida
|
|
129
|
+
bin/brida --runtime claude
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Checkout mode uses package-owned `bin/brida-*` wrappers. Installed-project mode
|
|
133
|
+
does not. Coordinator defaults and worker routes are settings-driven, so the
|
|
134
|
+
coordinator and implementation, review, planning, or scan workers may use
|
|
135
|
+
different runtimes. See the [model-routing guide](docs/guides/model-routing.md)
|
|
136
|
+
to change defaults, select a named route, or use a one-off override.
|
|
137
|
+
|
|
138
|
+
The `brida-codex` and `brida-claude` console commands installed by `brichan`
|
|
139
|
+
remain checkout-oriented: `brida-codex` resolves coordinator routing from a
|
|
140
|
+
Brida source checkout (or `BRIDA_ROOT`) or from an already-initialized
|
|
141
|
+
project's `.brida/` state, while `brida-claude` resolves only from a checkout
|
|
142
|
+
or `BRIDA_ROOT`. Both are for development and checkout use, not standalone
|
|
143
|
+
installed-project launches. `--help`/`--version` work from any directory; the
|
|
144
|
+
[installed Codex dogfood guide](docs/guides/installable-dogfood.md) has the
|
|
145
|
+
exact boundary.
|
|
146
|
+
|
|
147
|
+
## How it works
|
|
148
|
+
|
|
149
|
+
1. You describe the outcome and constraints.
|
|
150
|
+
2. Brida reads only the project context needed for that work.
|
|
151
|
+
3. Brida gives bounded tasks to independent workers through Herdr.
|
|
152
|
+
4. Brida verifies results, records decisions and status, then reports back.
|
|
153
|
+
|
|
154
|
+
Herdr is the worker control plane. Native runtime delegation stays disabled so
|
|
155
|
+
worker ownership, evidence, and cleanup remain visible.
|
|
156
|
+
|
|
157
|
+
Project context lives in `projects/<project-slug>/` as a small set of Markdown
|
|
158
|
+
files for overview, current state, tasks, decisions, and references. Read the
|
|
159
|
+
[project memory policy](docs/policy/memory-policy.md) for the contract.
|
|
160
|
+
|
|
161
|
+
## Development
|
|
162
|
+
|
|
163
|
+
Run the complete local validation suite before sharing a change:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
make check
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
You can also run individual layers while iterating:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
make test-unit
|
|
173
|
+
make test-contract
|
|
174
|
+
make test-integration
|
|
175
|
+
make package-check
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The importable implementation is in `src/brida/`; stable command wrappers are
|
|
179
|
+
in `bin/` and `scripts/`. See [CONTRIBUTING.md](CONTRIBUTING.md) for the change
|
|
180
|
+
workflow and [the repository layout](docs/architecture/repository-layout.md)
|
|
181
|
+
for module boundaries.
|
|
182
|
+
|
|
183
|
+
## Learn more
|
|
184
|
+
|
|
185
|
+
- [Model routing and worker launch settings](docs/guides/model-routing.md)
|
|
186
|
+
- [Installed Codex dogfood](docs/guides/installable-dogfood.md)
|
|
187
|
+
- [Documentation index](docs/index.md)
|
|
188
|
+
- [Operating principles](docs/policy/operating-principles.md)
|
|
189
|
+
- [Security policy](SECURITY.md)
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
Brida is available under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
brichan-0.5.0.dist-info/licenses/LICENSE,sha256=9XdXK_INnKeX43x8WI6sIBknvaELPBF64IjF39Hkaas,1066
|
|
2
|
+
brida/__init__.py,sha256=6TP3n7y8nk_HGMjPKHLpja53qNufdyO8a92fHnEscCk,68
|
|
3
|
+
brida/lifecycle.py,sha256=A7XBRW6GuWtFKzTFqpiu0Eff4n6JhlUMvz4_8uphyjI,10932
|
|
4
|
+
brida/project.py,sha256=Zi4tH0_V69VQJNNovB_--rDqVRAQEmI6ZBifx6glf0Y,1816
|
|
5
|
+
brida/cli/__init__.py,sha256=-WeS-o4ivaNlUCWmEkRbq-qmyMGGWImHkpsSMGGfKBg,45
|
|
6
|
+
brida/cli/_root.py,sha256=1MpUoMCJK51DieyE68-3Rq45wCIiQmGHWgmS1P4Zm84,708
|
|
7
|
+
brida/cli/claude.py,sha256=rFkrKaLp5IXNk9GqbISs2YnVtq3szrInnFFHuZ9zHTA,1786
|
|
8
|
+
brida/cli/codex.py,sha256=UGWzeE6CCtTT1x0B_sc0wqKDqTOPUDNx0RhSxjbSvzE,3903
|
|
9
|
+
brida/cli/provider_commands.py,sha256=nvWFbFKR9dx9QixUt4BaRZF-kF6xqsVfGOhAAW0Nut4,14067
|
|
10
|
+
brida/cli/runtime.py,sha256=_FVI1U5iWMwXEovWAD9BsUvrVxYkRtSCpBlHmyMpGbc,6129
|
|
11
|
+
brida/contracts/__init__.py,sha256=Va71T-aZ4_6gsWQ1f2-MK11_cWUK-HlU2OJ5WW4wG8M,31
|
|
12
|
+
brida/contracts/receipts/__init__.py,sha256=XLX3G9j2XSyo14tFLCxm_t6B0zFqCZyHkRHlBoFJH8M,340
|
|
13
|
+
brida/contracts/receipts/discovery.py,sha256=LOvvHwv7JF3ARpUtKWzkdzRROlV8balNedsHqArsFwY,115
|
|
14
|
+
brida/contracts/receipts/parser.py,sha256=ef8mCjPhyGpn7BYzPwhICHp3sPdKbakDkfwbcIsIlOs,127
|
|
15
|
+
brida/contracts/receipts/schema.py,sha256=OXSBHmxvddvVZn0nuVKRHS_WQ3REMbJWfwzYj69RSf8,807
|
|
16
|
+
brida/contracts/receipts/validation.py,sha256=Vt3AM1OwMDJ-BU25Xihxnf3Xp55QMD4AJod9hd7BiNM,35492
|
|
17
|
+
brida/orchestration/__init__.py,sha256=zJ29vdNooU0vdsm39em21taAAqdXvAa_b4bmuw_wpEs,453
|
|
18
|
+
brida/orchestration/herdr_client.py,sha256=x0aOSOZ3WZtxiH1beciztcYh5PK67F795VXJjxd4aJM,207
|
|
19
|
+
brida/orchestration/layout.py,sha256=QJF6sdfj6P4pMtdCGrdD0AH52lErxlVVC66KqJAEUxE,154
|
|
20
|
+
brida/orchestration/model_routing.py,sha256=ifdlYgtyZ_DEaOu5p1ILlvBODR5FxDij5ny6HMm0ljA,9092
|
|
21
|
+
brida/orchestration/worker_launch.py,sha256=yk6l_jRcEOzYpF9-v_2LXMotLYvnDE13FoRdulu-qBU,15620
|
|
22
|
+
brida/resources/__init__.py,sha256=7GEpLlpkVEZme8RnxNlCnLzD_uLikBA_88GEXx4spx8,40
|
|
23
|
+
brida/resources/dogfood_v1/__init__.py,sha256=L78bUjJrs4arq1LDoO59UdiVY4xQ5jTbekraVBFs0A4,45
|
|
24
|
+
brida/resources/dogfood_v1/config/model-routing.json,sha256=FiWJdemnKZVEu83WN4qX0B-w2I0BlJm17zJlSPiROag,710
|
|
25
|
+
brida/resources/dogfood_v1/policy/bootstrap.md,sha256=_w8q-EIlZco5QeMNj_Ec0xZNfBKykaxMPhn2OJuG7OA,1094
|
|
26
|
+
brida/resources/dogfood_v1/policy/identity.md,sha256=s9ITrFrsTJ4EAR8KXN_bWZi_2UbZ1sYX0XEnSQusRo0,846
|
|
27
|
+
brida/resources/dogfood_v1/policy/memory-policy.md,sha256=T2aWpntloiiCNK962JNPhBMGRxjCgbb4XFaxJ-YLffA,647
|
|
28
|
+
brida/resources/dogfood_v1/policy/operating-principles.md,sha256=9mgsHhpW_AWI3-bunGNnvkFJphkefzZs5O-6Frza_70,779
|
|
29
|
+
brida/resources/dogfood_v1/project-memory/index.md,sha256=PhLkcqvVkfOeTTaKkDqkgpQHmvEmKY2efKE7z_F-L_k,149
|
|
30
|
+
brida/resources/dogfood_v1/project-memory/main/current-state.md,sha256=edsLUKxloOFEsXmxx1XN8HlMwpPto7TOS4BUiOvi1HQ,163
|
|
31
|
+
brida/resources/dogfood_v1/project-memory/main/decisions.md,sha256=7YFB4XErRSqtn8G_DkYLvDRVMET12PWyDZJWokjtJvI,91
|
|
32
|
+
brida/resources/dogfood_v1/project-memory/main/overview.md,sha256=0ZSZvrBXixQucghtnPIHFzrUXBAQ8mGe6donHGDqtSA,182
|
|
33
|
+
brida/resources/dogfood_v1/project-memory/main/references.md,sha256=QK-QLajcACshlEHGhDsAH_7BKX2PeTQ5eoABQ4Pd4LE,68
|
|
34
|
+
brida/resources/dogfood_v1/project-memory/main/tasks.md,sha256=bTnFf-vkOb6hfbqtaNeYWwn0yhL5gQEz7DVH48fcDFk,196
|
|
35
|
+
brida/resources/dogfood_v1/skills/herdr-orchestration/SKILL.md,sha256=Wn1R5chYYO8oZ2lABsOY7fX9TV7_u2Qiy-DStnQbIMs,1064
|
|
36
|
+
brida/resources/dogfood_v1/skills/herdr-orchestration/references/commands.md,sha256=-aD6JS8M6aGl64fMm-m9VzOh3bMRLDDG_4m7xyVZ6Is,678
|
|
37
|
+
brida/resources/dogfood_v1/skills/herdr-orchestration/references/task-packet.md,sha256=7nmPVPIveATBeqVuOYo0rPFmZzIvPKd3BUaSLwHmvo4,616
|
|
38
|
+
brichan-0.5.0.dist-info/METADATA,sha256=cfqYf5K8eg59GUOszobjhBTGZkobaHOjULCkHKr7NIA,8026
|
|
39
|
+
brichan-0.5.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
40
|
+
brichan-0.5.0.dist-info/entry_points.txt,sha256=9NZhQ3yZ70QED5FHpl0d4_gO75RJUDcI_DHnj41ml6s,253
|
|
41
|
+
brichan-0.5.0.dist-info/top_level.txt,sha256=RJpGCwKsFy7LBiknV_FtTiR0OBrJXUR9XDDruQxH4AA,6
|
|
42
|
+
brichan-0.5.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Minh Tran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
brida
|
brida/__init__.py
ADDED
brida/cli/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Stable Brida command-line entrypoints."""
|
brida/cli/_root.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""Repository-root resolution shared by source and installed CLI adapters."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def repository_root() -> Path:
|
|
8
|
+
override = os.environ.get("BRIDA_ROOT")
|
|
9
|
+
if override:
|
|
10
|
+
return Path(override).resolve()
|
|
11
|
+
|
|
12
|
+
current = Path.cwd().resolve()
|
|
13
|
+
for candidate in (current, *current.parents):
|
|
14
|
+
if (candidate / "AGENTS.md").is_file() and (candidate / "bin").is_dir():
|
|
15
|
+
return candidate
|
|
16
|
+
|
|
17
|
+
source_root = Path(__file__).resolve().parents[3]
|
|
18
|
+
if (source_root / "AGENTS.md").is_file():
|
|
19
|
+
return source_root
|
|
20
|
+
raise RuntimeError(
|
|
21
|
+
"cannot locate the Brida repository root; run inside the repository "
|
|
22
|
+
"or set BRIDA_ROOT"
|
|
23
|
+
)
|
brida/cli/claude.py
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""Claude Code runtime adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from ._root import repository_root
|
|
9
|
+
from brida import __version__
|
|
10
|
+
from brida.orchestration.model_routing import (
|
|
11
|
+
RoutingError,
|
|
12
|
+
load_settings,
|
|
13
|
+
resolve_coordinator,
|
|
14
|
+
)
|
|
15
|
+
from .provider_commands import claude_command
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def command(argv: list[str], environment: dict[str, str]) -> list[str]:
|
|
19
|
+
root = repository_root()
|
|
20
|
+
settings = load_settings(repository=root, environment=environment)
|
|
21
|
+
compatibility_model = environment.get("BRIDA_CLAUDE_COORDINATOR_MODEL") or None
|
|
22
|
+
route = resolve_coordinator(
|
|
23
|
+
settings,
|
|
24
|
+
"claude",
|
|
25
|
+
model=compatibility_model,
|
|
26
|
+
)
|
|
27
|
+
return claude_command(route, argv)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def main(argv: list[str] | None = None) -> int:
|
|
31
|
+
arguments = sys.argv[1:] if argv is None else argv
|
|
32
|
+
try:
|
|
33
|
+
os.chdir(repository_root())
|
|
34
|
+
resolved_command = command(arguments, os.environ)
|
|
35
|
+
except RoutingError as exc:
|
|
36
|
+
print(f"brida-claude: {exc}", file=sys.stderr)
|
|
37
|
+
return 2
|
|
38
|
+
except RuntimeError as exc:
|
|
39
|
+
if arguments[:1] in (["--help"], ["-h"]):
|
|
40
|
+
print("usage: brida-claude [claude arguments...]")
|
|
41
|
+
print()
|
|
42
|
+
print(
|
|
43
|
+
"brida-claude is checkout-oriented: run it from within the "
|
|
44
|
+
"Brida source checkout, or with BRIDA_ROOT set. It is not "
|
|
45
|
+
"part of the Codex-first installed-project workflow."
|
|
46
|
+
)
|
|
47
|
+
return 0
|
|
48
|
+
if arguments[:1] in (["--version"], ["-V"]):
|
|
49
|
+
print(f"brida-claude {__version__}")
|
|
50
|
+
return 0
|
|
51
|
+
print(f"brida-claude: {exc}", file=sys.stderr)
|
|
52
|
+
return 2
|
|
53
|
+
os.execvp("claude", resolved_command)
|
|
54
|
+
return 0
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if __name__ == "__main__":
|
|
58
|
+
raise SystemExit(main())
|
brida/cli/codex.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Codex runtime adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from ._root import repository_root
|
|
9
|
+
from brida import __version__
|
|
10
|
+
from brida.lifecycle import StateKind, inspect_project
|
|
11
|
+
from brida.orchestration.model_routing import (
|
|
12
|
+
RoutingError,
|
|
13
|
+
load_settings,
|
|
14
|
+
resolve_coordinator,
|
|
15
|
+
)
|
|
16
|
+
from brida.project import ProjectPaths, ProjectError, project_paths
|
|
17
|
+
from .provider_commands import codex_command, codex_project_command
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def command(
|
|
21
|
+
argv: list[str],
|
|
22
|
+
environment: dict[str, str] | None = None,
|
|
23
|
+
) -> list[str]:
|
|
24
|
+
env = os.environ if environment is None else environment
|
|
25
|
+
root = repository_root()
|
|
26
|
+
settings = load_settings(repository=root, environment=env)
|
|
27
|
+
route = resolve_coordinator(settings, "codex")
|
|
28
|
+
return codex_command(route, argv, cwd=root)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def project_command(
|
|
32
|
+
paths: ProjectPaths,
|
|
33
|
+
argv: list[str],
|
|
34
|
+
environment: dict[str, str] | None = None,
|
|
35
|
+
) -> list[str]:
|
|
36
|
+
"""Resolve a package-owned command for one initialized Git project."""
|
|
37
|
+
|
|
38
|
+
env = os.environ if environment is None else environment
|
|
39
|
+
inspection = inspect_project(paths)
|
|
40
|
+
if inspection.kind is not StateKind.HEALTHY:
|
|
41
|
+
raise RoutingError(
|
|
42
|
+
f"project state is {inspection.kind.value}: {inspection.detail}"
|
|
43
|
+
)
|
|
44
|
+
settings = load_settings(
|
|
45
|
+
paths.state_root / "config" / "model-routing.json",
|
|
46
|
+
environment=env,
|
|
47
|
+
)
|
|
48
|
+
route = resolve_coordinator(settings, "codex")
|
|
49
|
+
bootstrap_path = paths.state_root / "policy" / "bootstrap.md"
|
|
50
|
+
try:
|
|
51
|
+
bootstrap = bootstrap_path.read_text(encoding="utf-8")
|
|
52
|
+
except OSError as exc:
|
|
53
|
+
raise RoutingError(f"cannot read Brida bootstrap policy: {exc}") from exc
|
|
54
|
+
developer_instructions = (
|
|
55
|
+
f"{bootstrap.rstrip()}\n\n"
|
|
56
|
+
f"Target project root: {paths.project_root}\n"
|
|
57
|
+
f"Mutable Brida state root: {paths.state_root}\n"
|
|
58
|
+
"Use only package-owned Brida launchers; never execute target-repository "
|
|
59
|
+
"bin/brida-* wrappers."
|
|
60
|
+
)
|
|
61
|
+
return codex_project_command(
|
|
62
|
+
route,
|
|
63
|
+
argv,
|
|
64
|
+
cwd=paths.project_root,
|
|
65
|
+
developer_instructions=developer_instructions,
|
|
66
|
+
skill_path=paths.state_root / "skills" / "herdr-orchestration",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def run_project(
|
|
71
|
+
paths: ProjectPaths,
|
|
72
|
+
argv: list[str],
|
|
73
|
+
environment: dict[str, str] | None = None,
|
|
74
|
+
) -> int:
|
|
75
|
+
resolved_command = project_command(paths, argv, environment)
|
|
76
|
+
os.chdir(paths.project_root)
|
|
77
|
+
os.execvp("codex", resolved_command)
|
|
78
|
+
return 0
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def main(argv: list[str] | None = None) -> int:
|
|
82
|
+
arguments = sys.argv[1:] if argv is None else argv
|
|
83
|
+
try:
|
|
84
|
+
paths = project_paths()
|
|
85
|
+
if paths.state_root.exists():
|
|
86
|
+
return run_project(paths, arguments, os.environ)
|
|
87
|
+
except (ProjectError, RoutingError) as exc:
|
|
88
|
+
if not isinstance(exc, ProjectError):
|
|
89
|
+
print(f"brida-codex: {exc}", file=sys.stderr)
|
|
90
|
+
return 2
|
|
91
|
+
pass
|
|
92
|
+
try:
|
|
93
|
+
resolved_command = command(arguments, os.environ)
|
|
94
|
+
except RoutingError as exc:
|
|
95
|
+
print(f"brida-codex: {exc}", file=sys.stderr)
|
|
96
|
+
return 2
|
|
97
|
+
except RuntimeError as exc:
|
|
98
|
+
if arguments[:1] in (["--help"], ["-h"]):
|
|
99
|
+
print("usage: brida-codex [codex arguments...]")
|
|
100
|
+
print()
|
|
101
|
+
print(
|
|
102
|
+
"brida-codex is checkout-oriented: run it from within the "
|
|
103
|
+
"Brida source checkout (or with BRIDA_ROOT set), or inside a "
|
|
104
|
+
"Git project initialized with 'brida init --apply' for the "
|
|
105
|
+
"installed-project workflow."
|
|
106
|
+
)
|
|
107
|
+
return 0
|
|
108
|
+
if arguments[:1] in (["--version"], ["-V"]):
|
|
109
|
+
print(f"brida-codex {__version__}")
|
|
110
|
+
return 0
|
|
111
|
+
print(f"brida-codex: {exc}", file=sys.stderr)
|
|
112
|
+
return 2
|
|
113
|
+
os.execvp("codex", resolved_command)
|
|
114
|
+
return 0
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
raise SystemExit(main())
|