codex2opencode 0.1.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.
Files changed (37) hide show
  1. codex2opencode-0.1.0/LICENSE +21 -0
  2. codex2opencode-0.1.0/PKG-INFO +279 -0
  3. codex2opencode-0.1.0/README.md +268 -0
  4. codex2opencode-0.1.0/bridge/codex2opencode/__init__.py +1 -0
  5. codex2opencode-0.1.0/bridge/codex2opencode/__main__.py +3 -0
  6. codex2opencode-0.1.0/bridge/codex2opencode/cli.py +692 -0
  7. codex2opencode-0.1.0/bridge/codex2opencode/errors.py +36 -0
  8. codex2opencode-0.1.0/bridge/codex2opencode/event_stream.py +58 -0
  9. codex2opencode-0.1.0/bridge/codex2opencode/locking.py +32 -0
  10. codex2opencode-0.1.0/bridge/codex2opencode/logging_utils.py +20 -0
  11. codex2opencode-0.1.0/bridge/codex2opencode/models.py +84 -0
  12. codex2opencode-0.1.0/bridge/codex2opencode/opencode_cli.py +86 -0
  13. codex2opencode-0.1.0/bridge/codex2opencode/paths.py +46 -0
  14. codex2opencode-0.1.0/bridge/codex2opencode/state.py +31 -0
  15. codex2opencode-0.1.0/bridge/codex2opencode/threading.py +18 -0
  16. codex2opencode-0.1.0/bridge/codex2opencode/version.py +1 -0
  17. codex2opencode-0.1.0/bridge/codex2opencode.egg-info/PKG-INFO +279 -0
  18. codex2opencode-0.1.0/bridge/codex2opencode.egg-info/SOURCES.txt +35 -0
  19. codex2opencode-0.1.0/bridge/codex2opencode.egg-info/dependency_links.txt +1 -0
  20. codex2opencode-0.1.0/bridge/codex2opencode.egg-info/entry_points.txt +2 -0
  21. codex2opencode-0.1.0/bridge/codex2opencode.egg-info/top_level.txt +1 -0
  22. codex2opencode-0.1.0/pyproject.toml +25 -0
  23. codex2opencode-0.1.0/setup.cfg +4 -0
  24. codex2opencode-0.1.0/tests/test_admin_commands.py +261 -0
  25. codex2opencode-0.1.0/tests/test_ask_flow_mock.py +320 -0
  26. codex2opencode-0.1.0/tests/test_cli_smoke.py +32 -0
  27. codex2opencode-0.1.0/tests/test_concurrency.py +133 -0
  28. codex2opencode-0.1.0/tests/test_event_stream.py +58 -0
  29. codex2opencode-0.1.0/tests/test_locking.py +22 -0
  30. codex2opencode-0.1.0/tests/test_opencode_cli_mock.py +117 -0
  31. codex2opencode-0.1.0/tests/test_package_metadata.py +22 -0
  32. codex2opencode-0.1.0/tests/test_paths.py +35 -0
  33. codex2opencode-0.1.0/tests/test_real_opencode_cli.py +91 -0
  34. codex2opencode-0.1.0/tests/test_recovery.py +142 -0
  35. codex2opencode-0.1.0/tests/test_skill_docs.py +47 -0
  36. codex2opencode-0.1.0/tests/test_state.py +70 -0
  37. codex2opencode-0.1.0/tests/test_threading.py +16 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenAI Codex
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,279 @@
1
+ Metadata-Version: 2.4
2
+ Name: codex2opencode
3
+ Version: 0.1.0
4
+ Summary: Local Codex-to-Opencode bridge CLI
5
+ Author: OpenAI Codex
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Dynamic: license-file
11
+
12
+ # codex2opencode
13
+
14
+ `codex2opencode` is a local one-way bridge from Codex to Opencode.
15
+
16
+ It provides:
17
+
18
+ - a reusable Python CLI bridge
19
+ - Opencode session persistence via native `sessionID`
20
+ - deterministic per-thread locking
21
+ - export-backed session verification
22
+ - a thin Codex skill wrapper surface
23
+ - no non-stdlib Python runtime dependency inside the bridge
24
+
25
+ Current implementation target:
26
+
27
+ - macOS / POSIX environments with Python 3 and local Opencode CLI access
28
+ - not designed for Windows in its current `fcntl`-based form
29
+
30
+ ## Current Status
31
+
32
+ Implemented and locally verified in this repository:
33
+
34
+ - `ask`
35
+ - `status`
36
+ - `forget`
37
+ - `gc`
38
+ - `doctor`
39
+ - automatic resume via stored Opencode `sessionID`
40
+ - Opencode-native `--fork`
41
+ - Opencode-native `--title`
42
+ - same-thread lock conflict handling
43
+
44
+ Primary verification commands:
45
+
46
+ - `PYTHONPATH=bridge python3 -m unittest discover -s tests -p 'test_*.py' -v`
47
+ - direct `codex2opencode ask ...` smoke
48
+ - direct `codex2opencode doctor ...` smoke
49
+ - opt-in real Opencode smoke when local auth is available
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ python3 -m venv .venv
55
+ source .venv/bin/activate
56
+ python3 -m pip install -e .
57
+ ```
58
+
59
+ When a PyPI release is available:
60
+
61
+ ```bash
62
+ python3 -m pip install codex2opencode
63
+ ```
64
+
65
+ You can also run it directly without installing:
66
+
67
+ ```bash
68
+ PYTHONPATH=bridge python3 -m codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"
69
+ ```
70
+
71
+ After editable install, both of these work:
72
+
73
+ ```bash
74
+ python -m codex2opencode --help
75
+ codex2opencode --help
76
+ ```
77
+
78
+ ## Usage
79
+
80
+ Ask Opencode in the current workspace thread:
81
+
82
+ ```bash
83
+ codex2opencode ask --prompt "Review this design" --workspace "$PWD"
84
+ ```
85
+
86
+ Successful `ask` output begins with a one-line metadata header before the reply body, for example:
87
+
88
+ ```text
89
+ [oc provider=opencode model=mimo-v2-omni-free session=ses_...]
90
+ ```
91
+
92
+ If session verification fails after a successful run, the bridge still prints the reply plus a minimal header with the session id, then exits non-zero.
93
+
94
+ Use a named thread:
95
+
96
+ ```bash
97
+ codex2opencode ask --prompt "Continue the review" --workspace "$PWD" --thread review
98
+ ```
99
+
100
+ Force a fresh session:
101
+
102
+ ```bash
103
+ codex2opencode ask --prompt "Start over" --workspace "$PWD" --new
104
+ ```
105
+
106
+ Fork the current mapped Opencode session:
107
+
108
+ ```bash
109
+ codex2opencode ask --prompt "Take this in a different direction" --workspace "$PWD" --fork
110
+ ```
111
+
112
+ Set an Opencode title on creation or fork:
113
+
114
+ ```bash
115
+ codex2opencode ask --prompt "Review the release checklist" --workspace "$PWD" --new --title "release-review"
116
+ ```
117
+
118
+ Inspect stored thread state:
119
+
120
+ ```bash
121
+ codex2opencode status --workspace "$PWD"
122
+ ```
123
+
124
+ Run diagnostics:
125
+
126
+ ```bash
127
+ codex2opencode doctor --workspace "$PWD"
128
+ ```
129
+
130
+ Forget the current thread and delete the mapped Opencode session:
131
+
132
+ ```bash
133
+ codex2opencode forget --workspace "$PWD"
134
+ ```
135
+
136
+ Remove stale bridge-owned files:
137
+
138
+ ```bash
139
+ codex2opencode gc --max-age-days 7
140
+ ```
141
+
142
+ ## Threading Model
143
+
144
+ By default, one workspace maps to one Opencode thread.
145
+
146
+ Use `--thread <name>` to split conversations inside the same repo:
147
+
148
+ ```bash
149
+ codex2opencode ask --prompt "Review API design" --workspace "$PWD" --thread api
150
+ codex2opencode ask --prompt "Review docs tone" --workspace "$PWD" --thread docs
151
+ ```
152
+
153
+ Use `--new` when you want a fresh Opencode session for the selected thread key.
154
+
155
+ Use `--fork` when you want Opencode to branch from the current mapped session instead of starting unrelated context. `--new` and `--fork` are intentionally mutually exclusive.
156
+
157
+ ## Codex Skill
158
+
159
+ The Codex-facing wrapper lives at:
160
+
161
+ ```text
162
+ skills/codex-to-opencode/SKILL.md
163
+ ```
164
+
165
+ The skill should stay thin. It should only:
166
+
167
+ - collect the user prompt
168
+ - choose default thread, named thread, `--new`, or `--fork`
169
+ - invoke `codex2opencode`
170
+ - return stdout or surface stderr
171
+
172
+ It must not own JSONL parsing, session storage, retries, export verification, or custom lock handling.
173
+
174
+ Recommended high-signal trigger phrases:
175
+
176
+ - `Use the codex-to-opencode skill`
177
+ - `ask Opencode about this`
178
+ - `ask oc about this`
179
+ - `send this to Opencode`
180
+ - `send this to oc`
181
+ - `let Opencode review this`
182
+ - `let oc review this`
183
+ - `give this to Opencode`
184
+ - `给 Opencode 看看`
185
+ - `给oc看看`
186
+ - `让 Opencode review 一下`
187
+ - `让oc review一下`
188
+ - `问问 Opencode`
189
+ - `问问oc`
190
+
191
+ Treat `oc` as a supported short alias for `Opencode` when it appears with a clear action.
192
+ Avoid relying on bare `opencode` by itself.
193
+ Avoid relying on bare `oc` by itself.
194
+ Trigger phrases should include a clear action like ask, review, check, continue, send, or look.
195
+
196
+ Practical everyday examples:
197
+
198
+ - `问问oc这个方案哪里最危险`
199
+ - `给oc看看这个 diff`
200
+ - `让oc review一下发布流程`
201
+ - `发给oc继续聊这个线程`
202
+ - `ask oc to review this design`
203
+
204
+ ## Activation Scope
205
+
206
+ These paths are expected to work:
207
+
208
+ - new Codex sessions started after the skill was installed
209
+ - `codex exec` runs started after the skill was installed
210
+ - direct `codex2opencode` CLI usage
211
+
212
+ Do not assume already-open Codex sessions will hot-reload newly installed or updated skills.
213
+
214
+ If you changed trigger phrases or installed the skill during an existing session, restart Codex or open a fresh session before testing.
215
+
216
+ ## Troubleshooting
217
+
218
+ If a trigger phrase does not route to Opencode:
219
+
220
+ 1. Start a new Codex session.
221
+ 2. Test with a high-signal phrase such as `Use the codex-to-opencode skill. Ask Opencode: reply with ok only.`
222
+ 3. Verify the bridge directly with `codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"`.
223
+ 4. Run `codex2opencode doctor --workspace "$PWD"` to confirm Opencode availability, debug-path output, and thread-state diagnostics.
224
+
225
+ If direct CLI usage works but a natural-language trigger does not, the issue is skill discovery in that session, not the bridge itself.
226
+
227
+ If `doctor` reports an `orphaned` thread state, the local mapping points at an Opencode session that no longer exports successfully. `forget` will remove that mapping and attempt remote deletion again.
228
+
229
+ ## Environment
230
+
231
+ - `CODEX2OPENCODE_OPENCODE_BIN`: override the Opencode executable path
232
+ - `CODEX2OPENCODE_HOME`: override the bridge state root without changing your real shell `HOME`
233
+ - `CODEX2OPENCODE_RUN_REAL=1`: enable opt-in real Opencode integration tests
234
+
235
+ ## Doctor Output
236
+
237
+ `codex2opencode doctor --workspace "$PWD"` prints JSON and checks:
238
+
239
+ - the resolved bridge root and key paths
240
+ - whether `opencode --version` is readable
241
+ - whether `opencode debug paths` is readable
242
+ - whether `opencode debug config` is parseable
243
+ - whether the selected thread state is `missing`, `ok`, `error`, or `orphaned`
244
+ - whether the mapped session can still be verified through `opencode export`
245
+ - whether the selected lock path is healthy or currently locked
246
+
247
+ It returns `0` when required checks are healthy and non-zero when Opencode availability checks fail, the state file is corrupted, or the mapped session is orphaned.
248
+
249
+ ## State Layout
250
+
251
+ Default bridge state root:
252
+
253
+ ```text
254
+ ~/.codex/codex2opencode/
255
+ threads/
256
+ runs/
257
+ logs/
258
+ ```
259
+
260
+ Key files:
261
+
262
+ - `threads/<thread_key>.json`: current thread state
263
+ - `threads/<thread_key>.lock`: per-thread lock file
264
+ - `runs/<thread_key>/*.json`: per-run artifacts
265
+ - `logs/bridge.log`: append-only JSONL bridge events
266
+
267
+ ## Boundaries
268
+
269
+ This repository is intentionally narrow:
270
+
271
+ - one-way Codex-to-Opencode only
272
+ - no Claude orchestration here
273
+ - no roundtable or multi-model discussion system
274
+ - no bridge-owned retry orchestration
275
+ - no over-generalized multi-backend framework
276
+
277
+ For design rationale and internals, see [ARCHITECTURE.md](./ARCHITECTURE.md).
278
+ For developer workflow, see [DEVELOPMENT.md](./DEVELOPMENT.md).
279
+ For contribution and release details, see [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1,268 @@
1
+ # codex2opencode
2
+
3
+ `codex2opencode` is a local one-way bridge from Codex to Opencode.
4
+
5
+ It provides:
6
+
7
+ - a reusable Python CLI bridge
8
+ - Opencode session persistence via native `sessionID`
9
+ - deterministic per-thread locking
10
+ - export-backed session verification
11
+ - a thin Codex skill wrapper surface
12
+ - no non-stdlib Python runtime dependency inside the bridge
13
+
14
+ Current implementation target:
15
+
16
+ - macOS / POSIX environments with Python 3 and local Opencode CLI access
17
+ - not designed for Windows in its current `fcntl`-based form
18
+
19
+ ## Current Status
20
+
21
+ Implemented and locally verified in this repository:
22
+
23
+ - `ask`
24
+ - `status`
25
+ - `forget`
26
+ - `gc`
27
+ - `doctor`
28
+ - automatic resume via stored Opencode `sessionID`
29
+ - Opencode-native `--fork`
30
+ - Opencode-native `--title`
31
+ - same-thread lock conflict handling
32
+
33
+ Primary verification commands:
34
+
35
+ - `PYTHONPATH=bridge python3 -m unittest discover -s tests -p 'test_*.py' -v`
36
+ - direct `codex2opencode ask ...` smoke
37
+ - direct `codex2opencode doctor ...` smoke
38
+ - opt-in real Opencode smoke when local auth is available
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ python3 -m venv .venv
44
+ source .venv/bin/activate
45
+ python3 -m pip install -e .
46
+ ```
47
+
48
+ When a PyPI release is available:
49
+
50
+ ```bash
51
+ python3 -m pip install codex2opencode
52
+ ```
53
+
54
+ You can also run it directly without installing:
55
+
56
+ ```bash
57
+ PYTHONPATH=bridge python3 -m codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"
58
+ ```
59
+
60
+ After editable install, both of these work:
61
+
62
+ ```bash
63
+ python -m codex2opencode --help
64
+ codex2opencode --help
65
+ ```
66
+
67
+ ## Usage
68
+
69
+ Ask Opencode in the current workspace thread:
70
+
71
+ ```bash
72
+ codex2opencode ask --prompt "Review this design" --workspace "$PWD"
73
+ ```
74
+
75
+ Successful `ask` output begins with a one-line metadata header before the reply body, for example:
76
+
77
+ ```text
78
+ [oc provider=opencode model=mimo-v2-omni-free session=ses_...]
79
+ ```
80
+
81
+ If session verification fails after a successful run, the bridge still prints the reply plus a minimal header with the session id, then exits non-zero.
82
+
83
+ Use a named thread:
84
+
85
+ ```bash
86
+ codex2opencode ask --prompt "Continue the review" --workspace "$PWD" --thread review
87
+ ```
88
+
89
+ Force a fresh session:
90
+
91
+ ```bash
92
+ codex2opencode ask --prompt "Start over" --workspace "$PWD" --new
93
+ ```
94
+
95
+ Fork the current mapped Opencode session:
96
+
97
+ ```bash
98
+ codex2opencode ask --prompt "Take this in a different direction" --workspace "$PWD" --fork
99
+ ```
100
+
101
+ Set an Opencode title on creation or fork:
102
+
103
+ ```bash
104
+ codex2opencode ask --prompt "Review the release checklist" --workspace "$PWD" --new --title "release-review"
105
+ ```
106
+
107
+ Inspect stored thread state:
108
+
109
+ ```bash
110
+ codex2opencode status --workspace "$PWD"
111
+ ```
112
+
113
+ Run diagnostics:
114
+
115
+ ```bash
116
+ codex2opencode doctor --workspace "$PWD"
117
+ ```
118
+
119
+ Forget the current thread and delete the mapped Opencode session:
120
+
121
+ ```bash
122
+ codex2opencode forget --workspace "$PWD"
123
+ ```
124
+
125
+ Remove stale bridge-owned files:
126
+
127
+ ```bash
128
+ codex2opencode gc --max-age-days 7
129
+ ```
130
+
131
+ ## Threading Model
132
+
133
+ By default, one workspace maps to one Opencode thread.
134
+
135
+ Use `--thread <name>` to split conversations inside the same repo:
136
+
137
+ ```bash
138
+ codex2opencode ask --prompt "Review API design" --workspace "$PWD" --thread api
139
+ codex2opencode ask --prompt "Review docs tone" --workspace "$PWD" --thread docs
140
+ ```
141
+
142
+ Use `--new` when you want a fresh Opencode session for the selected thread key.
143
+
144
+ Use `--fork` when you want Opencode to branch from the current mapped session instead of starting unrelated context. `--new` and `--fork` are intentionally mutually exclusive.
145
+
146
+ ## Codex Skill
147
+
148
+ The Codex-facing wrapper lives at:
149
+
150
+ ```text
151
+ skills/codex-to-opencode/SKILL.md
152
+ ```
153
+
154
+ The skill should stay thin. It should only:
155
+
156
+ - collect the user prompt
157
+ - choose default thread, named thread, `--new`, or `--fork`
158
+ - invoke `codex2opencode`
159
+ - return stdout or surface stderr
160
+
161
+ It must not own JSONL parsing, session storage, retries, export verification, or custom lock handling.
162
+
163
+ Recommended high-signal trigger phrases:
164
+
165
+ - `Use the codex-to-opencode skill`
166
+ - `ask Opencode about this`
167
+ - `ask oc about this`
168
+ - `send this to Opencode`
169
+ - `send this to oc`
170
+ - `let Opencode review this`
171
+ - `let oc review this`
172
+ - `give this to Opencode`
173
+ - `给 Opencode 看看`
174
+ - `给oc看看`
175
+ - `让 Opencode review 一下`
176
+ - `让oc review一下`
177
+ - `问问 Opencode`
178
+ - `问问oc`
179
+
180
+ Treat `oc` as a supported short alias for `Opencode` when it appears with a clear action.
181
+ Avoid relying on bare `opencode` by itself.
182
+ Avoid relying on bare `oc` by itself.
183
+ Trigger phrases should include a clear action like ask, review, check, continue, send, or look.
184
+
185
+ Practical everyday examples:
186
+
187
+ - `问问oc这个方案哪里最危险`
188
+ - `给oc看看这个 diff`
189
+ - `让oc review一下发布流程`
190
+ - `发给oc继续聊这个线程`
191
+ - `ask oc to review this design`
192
+
193
+ ## Activation Scope
194
+
195
+ These paths are expected to work:
196
+
197
+ - new Codex sessions started after the skill was installed
198
+ - `codex exec` runs started after the skill was installed
199
+ - direct `codex2opencode` CLI usage
200
+
201
+ Do not assume already-open Codex sessions will hot-reload newly installed or updated skills.
202
+
203
+ If you changed trigger phrases or installed the skill during an existing session, restart Codex or open a fresh session before testing.
204
+
205
+ ## Troubleshooting
206
+
207
+ If a trigger phrase does not route to Opencode:
208
+
209
+ 1. Start a new Codex session.
210
+ 2. Test with a high-signal phrase such as `Use the codex-to-opencode skill. Ask Opencode: reply with ok only.`
211
+ 3. Verify the bridge directly with `codex2opencode ask --prompt "Reply with ok only" --workspace "$PWD"`.
212
+ 4. Run `codex2opencode doctor --workspace "$PWD"` to confirm Opencode availability, debug-path output, and thread-state diagnostics.
213
+
214
+ If direct CLI usage works but a natural-language trigger does not, the issue is skill discovery in that session, not the bridge itself.
215
+
216
+ If `doctor` reports an `orphaned` thread state, the local mapping points at an Opencode session that no longer exports successfully. `forget` will remove that mapping and attempt remote deletion again.
217
+
218
+ ## Environment
219
+
220
+ - `CODEX2OPENCODE_OPENCODE_BIN`: override the Opencode executable path
221
+ - `CODEX2OPENCODE_HOME`: override the bridge state root without changing your real shell `HOME`
222
+ - `CODEX2OPENCODE_RUN_REAL=1`: enable opt-in real Opencode integration tests
223
+
224
+ ## Doctor Output
225
+
226
+ `codex2opencode doctor --workspace "$PWD"` prints JSON and checks:
227
+
228
+ - the resolved bridge root and key paths
229
+ - whether `opencode --version` is readable
230
+ - whether `opencode debug paths` is readable
231
+ - whether `opencode debug config` is parseable
232
+ - whether the selected thread state is `missing`, `ok`, `error`, or `orphaned`
233
+ - whether the mapped session can still be verified through `opencode export`
234
+ - whether the selected lock path is healthy or currently locked
235
+
236
+ It returns `0` when required checks are healthy and non-zero when Opencode availability checks fail, the state file is corrupted, or the mapped session is orphaned.
237
+
238
+ ## State Layout
239
+
240
+ Default bridge state root:
241
+
242
+ ```text
243
+ ~/.codex/codex2opencode/
244
+ threads/
245
+ runs/
246
+ logs/
247
+ ```
248
+
249
+ Key files:
250
+
251
+ - `threads/<thread_key>.json`: current thread state
252
+ - `threads/<thread_key>.lock`: per-thread lock file
253
+ - `runs/<thread_key>/*.json`: per-run artifacts
254
+ - `logs/bridge.log`: append-only JSONL bridge events
255
+
256
+ ## Boundaries
257
+
258
+ This repository is intentionally narrow:
259
+
260
+ - one-way Codex-to-Opencode only
261
+ - no Claude orchestration here
262
+ - no roundtable or multi-model discussion system
263
+ - no bridge-owned retry orchestration
264
+ - no over-generalized multi-backend framework
265
+
266
+ For design rationale and internals, see [ARCHITECTURE.md](./ARCHITECTURE.md).
267
+ For developer workflow, see [DEVELOPMENT.md](./DEVELOPMENT.md).
268
+ For contribution and release details, see [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1 @@
1
+ from .version import __version__
@@ -0,0 +1,3 @@
1
+ from .cli import main
2
+
3
+ raise SystemExit(main())