rein-agentic-kit 0.7.1__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.
@@ -0,0 +1,340 @@
1
+ Metadata-Version: 2.4
2
+ Name: rein-agentic-kit
3
+ Version: 0.7.1
4
+ Summary: Rein โ€” keep your Claude Code agents lean and in control. Token-lean, stack-aware agentic dev flow.
5
+ Author: Luis Farfan
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/luisfarfan/rein-agentic-kit
8
+ Project-URL: Source, https://github.com/luisfarfan/rein-agentic-kit
9
+ Keywords: claude,claude-code,agents,tokens,cost,review,planning
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Topic :: Software Development :: Quality Assurance
16
+ Requires-Python: >=3.9
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Dynamic: license-file
20
+
21
+ <div align="center">
22
+
23
+ # ๐ŸŽ Rein
24
+
25
+ **Keep your Claude Code agents lean and in control.**
26
+
27
+ A Claude Code plugin that turns agent work into a bounded, measured, independently-reviewed flow โ€”
28
+ and tells you what it actually cost, per model.
29
+
30
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
31
+ [![CI](https://github.com/luisfarfan/rein-agentic-kit/actions/workflows/ci.yml/badge.svg)](https://github.com/luisfarfan/rein-agentic-kit/actions/workflows/ci.yml)
32
+ [![Dependencies](https://img.shields.io/badge/runtime%20deps-none-success.svg)](#)
33
+ [![Python](https://img.shields.io/badge/python-3.9%2B%20stdlib-blue.svg)](#)
34
+ [![Claude Code](https://img.shields.io/badge/Claude%20Code-plugin-8A2BE2.svg)](https://claude.com/claude-code)
35
+
36
+ </div>
37
+
38
+ ---
39
+
40
+ ## ๐Ÿ’ธ The problem, measured
41
+
42
+ Optimizing agent cost by "making the model write less" does nothing. Over real Claude Code
43
+ transcripts:
44
+
45
+ | Where the tokens go | Share |
46
+ |---|---:|
47
+ | ๐Ÿ”ด `cache_read` โ€” context re-read **every turn** | **~90%** |
48
+ | ๐ŸŸ  `cache_write` | ~10% |
49
+ | ๐ŸŸข **output** โ€” what a compressor would attack | **~0.3%** |
50
+ | โšช fresh input | ~0% |
51
+
52
+ **Cost โ‰ˆ turns ร— context size.** One agent that ran 241 turns, re-reading ~234k of context on
53
+ every single turn, was most of a 112M-token run.
54
+
55
+ And Claude Code has **no native eviction of stale tool results** โ€” only `/compact`, which is
56
+ lossy and breaks the prompt cache. A long agent's context only grows.
57
+
58
+ > **Measured effect of this kit: 241 turns โ†’ 26 ยท Opus 100% โ†’ 0% ยท ~7ร— less context per turn.**
59
+
60
+ ---
61
+
62
+ ## ๐Ÿ” The flow
63
+
64
+ ```mermaid
65
+ flowchart TD
66
+ A["๐Ÿงญ /rein:plan<br/><i>Why ยท Scope ยท Decisions ยท Tasks</i>"]
67
+ B{{"rein next<br/><i>deterministic gate</i>"}}
68
+ C["โš™๏ธ Implement<br/><i>bounded loop of FRESH agents</i><br/><i>context resets each step</i>"]
69
+ D{{"Verify<br/><i>ask the plan, not the agent</i>"}}
70
+ E["๐Ÿ” /rein:review<br/><i>whole change ยท 5 axes</i>"]
71
+ F["โœ… merge"]
72
+ G["โœ‹ escalate to you"]
73
+ X["๐Ÿ›‘ stop"]
74
+
75
+ A -->|you confirm| B
76
+ B -->|ready| C
77
+ C --> D
78
+ D -->|contradiction| X
79
+ D -->|consistent| E
80
+ E -->|"APPROVED + gate green"| F
81
+ E -->|"needs your judgement"| G
82
+ E -->|"CHANGES_REQUESTED ยท max 3"| C
83
+
84
+ style A fill:#1e3a5f,stroke:#4a90d9,color:#fff
85
+ style C fill:#1e4620,stroke:#4caf50,color:#fff
86
+ style E fill:#5f1e3a,stroke:#d94a90,color:#fff
87
+ style F fill:#2d4a1e,stroke:#8bc34a,color:#fff
88
+ style X fill:#4a1e1e,stroke:#d94a4a,color:#fff
89
+ style G fill:#4a3a1e,stroke:#d9a94a,color:#fff
90
+ ```
91
+
92
+ Three roles, and **no agent approves its own implementation**. Every run works in its own git
93
+ worktree; unapproved work is never merged.
94
+
95
+ ---
96
+
97
+ ## ๐Ÿš€ Quickstart
98
+
99
+ ```bash
100
+ claude plugin marketplace add luisfarfan/rein-agentic-kit
101
+ ```
102
+
103
+ ```bash
104
+ claude plugin install rein@rein-agentic-kit --scope user
105
+ ```
106
+
107
+ **Restart Claude Code**, then run inside it:
108
+
109
+ ```
110
+ /rein:ping โ†’ is it wired here, and what did it detect?
111
+ /rein:setup โ†’ probe the optional tools ยท confirm to provision them
112
+ ```
113
+
114
+ `ping` reports the detected stack, the resolved commands and where each one
115
+ came from. **If it got everything right, you configure nothing.**
116
+
117
+ > **Everything runs inside Claude Code โ€” there is nothing to add to your `$PATH`.**
118
+ > Claude Code puts the plugin's `bin/` on the path of its own sessions, which is
119
+ > where the skills, the commands and the agents call `rein`. In a plain terminal
120
+ > `rein` will *not* be found, and that is expected: the CLI exists to be called by
121
+ > the flow, and the two commands a person runs by hand have slash commands above.
122
+ ### Want `rein` in your own terminal too?
123
+
124
+ The plugin's `bin/` is only on the path of Claude Code's own sessions โ€” a plugin
125
+ cannot add anything to your shell. For `rein dashboard`, `rein ledger` or
126
+ `rein doctor` from a terminal, install the CLI the way every tool this kit
127
+ integrates ships (serena and graphify via `uv`, codegraph and openspec via `npm`):
128
+
129
+ ```bash
130
+ uv tool install rein-agentic-kit # or: pipx install rein-agentic-kit
131
+ ```
132
+
133
+ Same code, same version, zero dependencies. The two channels cannot drift: a
134
+ test fails the build if their version strings ever disagree.
135
+
136
+ > To update: `claude plugin marketplace update rein-agentic-kit` then
137
+ > `claude plugin update rein@rein-agentic-kit` โ€” qualified with the marketplace,
138
+ > or it reports `Plugin "rein" not found`.
139
+
140
+ Then, per change:
141
+
142
+ ```
143
+ /rein:plan โ†’ you confirm the plan โ†’ /rein:loop โ†’ read the verdict
144
+ ```
145
+
146
+ You come back when it finished, not before.
147
+
148
+ ---
149
+
150
+ ## ๐Ÿงฐ What you get
151
+
152
+ ### Skills โ€” the three roles
153
+
154
+ | | |
155
+ |---|---|
156
+ | ๐ŸŽญ **`/rein:role`** | Assign this session's role: planner ยท implementer ยท reviewer |
157
+ | ๐Ÿงญ **`/rein:plan`** | Plan into verifiable tasks โ€” dry-run and **explicit confirmation** before writing |
158
+ | ๐Ÿ”จ **`/rein:run`** | Exactly **one** task. Max 3 attempts, max 5 failed commands, no self-approval |
159
+ | ๐Ÿ” **`/rein:run-auto`** | Bounded loop of `run`, stopping on **verifiable signals** only |
160
+ | ๐Ÿ” **`/rein:review`** | The independent gate: mechanical checks first, then five-axis judgement |
161
+ | โ™พ๏ธ **`/rein:loop`** | Runs all three end-to-end in an isolated worktree |
162
+
163
+ ### CLI โ€” the deterministic half
164
+
165
+ ```bash
166
+ rein doctor # ๐Ÿฉบ start here: stack, resolved commands, and the source of each
167
+ # plus a "version : <verdict> -- <reason>" line -- up-to-date / stale /
168
+ # unknown against the marketplace clone, with fix commands when stale
169
+ # --json: {"version", "pluginRoot", "project", "plan", "verifyState",
170
+ # "ledger", "staleness"} -- staleness is {"verdict", "reason",
171
+ # "installedVersion", "availableVersion"}
172
+ rein setup # probe the optional tools ยท --install provisions what is missing
173
+ rein detect # stack + commands, with the source of each
174
+ rein tasks # the plan, parsed
175
+ rein context # detect + plan in ONE round-trip โ€” what the loop's first agent runs
176
+ rein verify # actually RUN each resolved command and report the truth โ€” an inference is not a fact
177
+ rein next # โœ… the gate: is there a task to claim, and may it be
178
+ rein close T001 # tick a checkbox deterministically โ€” no agent hand-edits the plan
179
+ rein review # record / check a verdict bound to a code state
180
+ rein token-report# what a run really cost, per agent and per model
181
+ rein ledger # history across projects, with deltas vs a marked baseline
182
+ # --json: {"runs": [...], "events_by_project": {...}} -- runs are
183
+ # unchanged row objects; events (D3) are counted separately, never
184
+ # folded into a run total
185
+ rein baseline # mark the run everything is compared against
186
+ rein dashboard # ๐Ÿ“Š serve it all as a local page
187
+ ```
188
+
189
+ > **The rule that separates them:** if it's a *parse*, a script does it. If it's a *judgement*,
190
+ > an agent does it. Every fact an agent doesn't have to rediscover is turns you don't pay for.
191
+
192
+ ---
193
+
194
+ ## โš–๏ธ The three levers
195
+
196
+ **1๏ธโƒฃ Bounded loop of fresh agents.** Each task is at most *N* short, fresh agents handing off a
197
+ **compact ledger** (`progress` / `remaining` / `filesTouched` / `verification`) โ€” never one agent
198
+ running 200+ turns. Context **resets at every boundary**, so spend stops growing without a ceiling.
199
+
200
+ **2๏ธโƒฃ Per-agent model routing.** Mechanical โ†’ Haiku ยท code โ†’ Sonnet ยท the review gate โ†’ Opus. On a
201
+ subscription this doesn't lower the bill โ€” it frees the **scarce Opus quota**, which is the limit
202
+ you actually hit.
203
+
204
+ **3๏ธโƒฃ Verifiable signals, not model judgement.** A loop that stops when the model *feels* finished
205
+ has no gate. `rein next` answers "is there work to claim" from the plan; `rein review check`
206
+ answers "does this approval still apply" from content hashes. Neither asks a model anything.
207
+
208
+ ### โŒ Deliberately not included
209
+
210
+ Tried and discarded **with data**, not taste:
211
+
212
+ - **Output compressors** โ€” they attack the 0.3%.
213
+ - **Multi-provider API swarms** โ€” the saving doesn't apply on a subscription, and more agents means
214
+ more contexts re-read.
215
+ - **Cross-session memory tools** โ€” orthogonal to the actual cost driver.
216
+ - **Cache-aware proxies** โ€” no-op on already-cached traffic.
217
+ - **Persona prompts** ("you are a hexagonal architecture expert") โ€” the same model with the same
218
+ weights. Constraints that can be *violated* are useful; job titles are not.
219
+
220
+ ---
221
+
222
+ ## โš™๏ธ Configure
223
+
224
+ Everything is optional. Drop a `flow.config.json` at your project root to override:
225
+
226
+ ```json
227
+ {
228
+ "commands": {
229
+ "test": "uv run pytest -q",
230
+ "testOne": "uv run pytest -q {target}",
231
+ "lint": "uv run ruff check .",
232
+ "typecheck": "uv run mypy ."
233
+ },
234
+ "models": { "aux": "haiku", "impl": "sonnet", "review": "opus" },
235
+ "limits": { "maxTaskSteps": 8, "maxReviewRounds": 3 }
236
+ }
237
+ ```
238
+
239
+ **Precedence:** `flow.config.json` โ€บ task runner (`justfile` / `Makefile` / `Taskfile`) โ€บ
240
+ autodetection. A project that already declares how it is built is never second-guessed.
241
+
242
+ ## ๐Ÿงฑ Supported stacks
243
+
244
+ | Stack | Detected by | Verification |
245
+ |---|---|---|
246
+ | ๐Ÿ Python | `pyproject.toml`, uv / poetry | pytest ยท ruff ยท mypy |
247
+ | ๐ŸŸจ Node / TS | `package.json`, pnpm / npm / yarn / bun | vitest or jest ยท eslint ยท tsc |
248
+ | ๐Ÿฆ€ Rust | `Cargo.toml` | cargo test ยท clippy ยท check |
249
+ | ๐Ÿน Go | `go.mod` | go test ยท vet |
250
+ | ๐ŸŽจ **Frontend** *(Next, Vite, Astro, SvelteKit, Nuxt, Remix)* | dependencies | **rendered verification** โ€” unit tests alone don't catch "the tests pass but the UI is broken" |
251
+ | โ˜๏ธ Serverless / infra | `serverless.yml`, `sst.config.ts`, `*.tf` | `plan` / `validate` โ€” **never deploy** |
252
+ | ๐Ÿ“ฆ Monorepo | sub-projects one or two levels down, no root manifest | reports each sub-project and its own commands โ€” **it never picks one for you**, even when there is only one candidate |
253
+
254
+ > **A resolved command is an inference until something runs it.** `rein verify` executes each one
255
+ > and reports what happened, distinguishing *"the binary is missing"* (a **setup** problem) from
256
+ > *"the suite ran and failed"* (a **code** problem) โ€” conflating them sends you to the wrong file.
257
+ > The loop runs it at Prepare: a broken gate found there costs nothing, the same one found at
258
+ > review costs a whole run.
259
+
260
+ Optional tools (`serena`, `codegraph`, `graphify`, `openspec`) are **probed, never
261
+ required**: if one is absent the flow degrades, it does not break. `rein setup` reports
262
+ what is missing and installs it on request โ€” and distinguishes *installed* from *usable*,
263
+ because graphify without an index and a just-registered MCP server are both present and
264
+ inert.
265
+
266
+ > **No retrieval speedup is claimed.** With codegraph present, the loop's implementers are
267
+ > taught `codegraph query` / `callers` / `callees` / `node` / `impact` (plus `sync` to
268
+ > refresh the index after their own edits) as the one owner of "what is this / who touches
269
+ > it / what breaks if I change it"; with codegraph absent, serena's `get_symbols_overview` /
270
+ > `find_symbol` / `find_referencing_symbols` cover the same ground as a fallback. Whether
271
+ > either reduces the turns an agent spends orienting is **unmeasured**, and the one control
272
+ > available points the other way. See [docs/decisions.md](docs/decisions.md) D2.
273
+
274
+ **One owner per question.** A tool is dropped from the prompts for having no *exclusive*
275
+ question โ€” not for being bad:
276
+
277
+ ```mermaid
278
+ flowchart LR
279
+ Q1["โ“ what is this?<br/>who touches it?<br/>what breaks if I change it?"] --> CG["๐Ÿ”Ž codegraph<br/><i>query ยท callers ยท callees</i><br/><i>node ยท impact</i>"]
280
+ Q2["โ“ edit this symbol<br/>type errors, no build"] --> SE["โœ๏ธ serena<br/><i>replace_symbol_body</i><br/><i>get_diagnostics_for_file</i>"]
281
+ Q3["โ“ docs ยท papers ยท images"] --> GR["๐Ÿ“š graphify<br/><i>/graphify skill</i><br/><i>outside the loop</i>"]
282
+
283
+ style CG fill:#1e4620,stroke:#4caf50,color:#fff
284
+ style SE fill:#1e3a5f,stroke:#4a90d9,color:#fff
285
+ style GR fill:#4a3a1e,stroke:#d9a94a,color:#fff
286
+ ```
287
+
288
+ Measured on this repo, same question, same index cost (~1.5s, no LLM, no API key for either):
289
+ asked *"where is it decided that a command is not invocable?"*, codegraph returns
290
+ `NOT_INVOCABLE_EXIT_CODES = (126,127)` with its file and line in **258 tokens**; the graph
291
+ tool it replaced returned **546 tokens of an unrelated example config**, because a JSON key
292
+ happened to match. Confident noise is worse for an agent than no answer โ€” it cannot tell the
293
+ two apart, and it pays for the difference on every later turn.
294
+
295
+ ## ๐Ÿ“Š Measure
296
+
297
+ ```bash
298
+ rein token-report && rein dashboard
299
+ ```
300
+
301
+ Reads Claude Code's own JSONL transcripts (including `cache_read`) and breaks a run down per
302
+ agent and **per model**. Every run is summarized into `~/.claude/rein/runs.jsonl`, so history
303
+ survives transcript rotation.
304
+
305
+ **On the word "savings":** this measures *consumption*. A saving needs a baseline. Mark one with
306
+ `rein baseline mark` and every later run in that project gets a signed delta. Without one, the
307
+ honest numbers are the three that predict cost โ€” **turns/agent**, **ctx_max/turn**,
308
+ **% of tokens on Opus**.
309
+
310
+ ---
311
+
312
+ ## ๐Ÿ™ƒ Honest limitations
313
+
314
+ Things a README usually hides:
315
+
316
+ - **The reviewer is calibrated hard.** 4 of 6 runs here exhausted their 3 rounds. A three-task
317
+ change will often use them all.
318
+ - **A stalled agent burns wall-clock.** One run spent 3.4 hours almost entirely in silent API
319
+ retries.
320
+ - **`discover` was considered and rejected** โ€” a per-run version of it was measured in the origin
321
+ project and did not move the needle. See [docs/decisions.md](docs/decisions.md).
322
+
323
+ ## ๐Ÿ—บ๏ธ Roadmap
324
+
325
+ | Phase | Scope | |
326
+ |---|---|---|
327
+ | 0 | Plugin plumbing ยท `token-report` ยท ledger ยท stack detection | โœ… [findings](docs/phase-0-findings.md) |
328
+ | 1 | Config-driven core loop ยท `tasks.md` adapter โ€” **measured** | โœ… |
329
+ | 2 | Stack-aware verification policy | โœ… |
330
+ | 3 | Local dashboard ยท per-agent model config | โœ… |
331
+ | 4 | Compose real browser verification | โœ… |
332
+ | 5 | Docs ยท polish ยท a second real-world project | โณ |
333
+
334
+ ## ๐Ÿ“„ License
335
+
336
+ MIT โ€” see [LICENSE](LICENSE).
337
+
338
+ <div align="center">
339
+ <sub>Built with Claude Code, reviewed by an agent that wrote none of it.</sub>
340
+ </div>
@@ -0,0 +1,31 @@
1
+ rein_agentic_kit-0.7.1.dist-info/licenses/LICENSE,sha256=mdUzbrrhWQpGbXsxfX0ifSXwnBGcFn4Fl5aCVI4NNuA,1068
2
+ rein_kit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ rein_kit/_entry.py,sha256=7x8yF9pt6qjyNO68Zsj8wA0tM5or8gEDkTSINM5JJ5g,1474
4
+ rein_kit/flow.config.example.json,sha256=VVQpSNWzWWd_jCWC3Y5aUZiAZtiQaDzNctwQmKyJcoE,3137
5
+ rein_kit/.claude-plugin/plugin.json,sha256=LlMcJB0JsDnum-qWp_UmQG_bpwoNi3QV51ZDO_oe84Y,543
6
+ rein_kit/bin/rein,sha256=DVAZItzAL2GdQkj9zXaKFTXQ5TQbqHknm2MNt3llkt8,29557
7
+ rein_kit/commands/ping.md,sha256=S_ZYTas8upjxTiwex7x8KInvhuWq0RTERCTl35Jy_cs,1474
8
+ rein_kit/commands/setup.md,sha256=QVjisKdk4O2jPyTFKtIUX3eiC7PpNKEZOtES6hgu1ZM,1276
9
+ rein_kit/lib/dashboard.py,sha256=bqWW6M4-jW-Taw6_5zhvWrm_XhDCTwvayuFbOlWCA5U,62150
10
+ rein_kit/lib/detect.py,sha256=75k-nY6n_SIJl2WQ4JiLTDCG0towOWSllaZOVl_HqS8,37584
11
+ rein_kit/lib/events.py,sha256=LhavKBssUmVLOMcRnj_e-HevtcmBQ2RYpl8Ng_FY6GQ,6099
12
+ rein_kit/lib/gate.py,sha256=CPVEdkL3JKJDyXTuMhqaEEhepf4Uyohisqhen18T1O8,10890
13
+ rein_kit/lib/plan.py,sha256=CD3qM1SAB2k3YxDR6Lt1qmXCjIEY8GzU2riuppur0eU,12767
14
+ rein_kit/lib/plan_check.py,sha256=FDeXV7m73bAdlyxywn44NSef7vw3gzlAFfrkVXN9Fb8,10274
15
+ rein_kit/lib/serve.py,sha256=aMgGBeNvJFCvXpzt9YkkRG79QenfroFLlAwXPHItpPU,17403
16
+ rein_kit/lib/setup.py,sha256=5khEsZwGf_uslNR26YS2IdpQeBBU7fUGdD0kUz6cwaE,22822
17
+ rein_kit/lib/token_report.py,sha256=j8gda8BHpqbDBR2dXZh3QSoBPFleDpcCbpETUbC3tYs,30516
18
+ rein_kit/lib/verify.py,sha256=0PXjlUamXseHzOhiPEVTicchjOnYMWIe6_subnKkErU,18610
19
+ rein_kit/lib/version_staleness.py,sha256=WDGgQ8LH0wsQEFAnb3jFKToiYoPIMzgqCGi4U5EkNeg,14330
20
+ rein_kit/skills/loop/SKILL.md,sha256=rCUBJgjn8tzwiPMhVPnwc0RdfyW7Bf3IH_0pMl-u39Y,4691
21
+ rein_kit/skills/plan/SKILL.md,sha256=0idJw9dHWjxlzavDxPgppTL-x5YcZlLXmYt_-XojthU,9798
22
+ rein_kit/skills/review/SKILL.md,sha256=usWKqdUgTyocPIiVVHTGAD2qZSQ9lYgwLGE7DuYhjl8,6148
23
+ rein_kit/skills/role/SKILL.md,sha256=Yq4PnPfFV_lNNULGDQI65cSXcG9a3i0dem-qwFyTWSc,3977
24
+ rein_kit/skills/run/SKILL.md,sha256=Wx_-cBlWdU4Ctj3HF9-G3zJW9FL1XDtI6ROEYm0waOE,2958
25
+ rein_kit/skills/run-auto/SKILL.md,sha256=qERkJPcLYh3SahIC0dZ1zNjWCyTaYPYUF6YL8uCvGlw,3516
26
+ rein_kit/workflows/loop.js,sha256=mZ347P-UQhg6_jr7UGSW4WzopCKI0t434-MQo2x8YK0,130526
27
+ rein_agentic_kit-0.7.1.dist-info/METADATA,sha256=c4DXLkkNz_J6rP-cy22XhUHSVDsbTpK_zTdayMvkOig,15033
28
+ rein_agentic_kit-0.7.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
29
+ rein_agentic_kit-0.7.1.dist-info/entry_points.txt,sha256=tNZUq83QyUqex43ObMXoCMWGkcXfhcvflx8DSOtSA6A,46
30
+ rein_agentic_kit-0.7.1.dist-info/top_level.txt,sha256=Fz0Oa2BAGZb_HqBHykX2_68Gekt3V6mo9kdAvgFdY6Q,9
31
+ rein_agentic_kit-0.7.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rein = rein_kit._entry:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luis Farfan
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
+ rein_kit
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "rein",
3
+ "description": "Rein \u2014 keep your Claude Code agents lean and in control. A config-driven, stack-aware dev flow (plan / loop / review) built on bounded fresh-agent steps, per-agent model routing, and real per-model token measurement.",
4
+ "version": "0.7.1",
5
+ "author": {
6
+ "name": "Luis Farfan"
7
+ },
8
+ "homepage": "https://github.com/luisfarfan/rein-agentic-kit",
9
+ "license": "MIT",
10
+ "keywords": [
11
+ "workflow",
12
+ "tokens",
13
+ "cost",
14
+ "agents",
15
+ "review",
16
+ "planning",
17
+ "stack-detection"
18
+ ]
19
+ }
rein_kit/__init__.py ADDED
File without changes
rein_kit/_entry.py ADDED
@@ -0,0 +1,39 @@
1
+ """Console-script entry point for the PyPI distribution.
2
+
3
+ The plugin and the package must run the SAME code, or they drift and a bug
4
+ gets fixed in one channel only. So this does not reimplement the CLI: it
5
+ loads `bin/rein` -- the identical file the plugin's own sessions execute --
6
+ and calls its `main`. `bin/rein` puts its `lib/` on `sys.path` itself, from
7
+ a path relative to its own location, so it behaves the same wherever it was
8
+ installed.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import importlib.util
14
+ import os
15
+ import sys
16
+ from importlib.machinery import SourceFileLoader
17
+
18
+ HERE = os.path.dirname(os.path.abspath(__file__))
19
+ CLI = os.path.join(HERE, "bin", "rein")
20
+
21
+
22
+ def main() -> int:
23
+ # An EXPLICIT loader: `bin/rein` has no `.py` extension (it is a shebang
24
+ # script the plugin executes directly), and spec_from_file_location
25
+ # returns None for an extension it does not recognise -- verified. The
26
+ # package installed and imported cleanly and then failed at first run.
27
+ spec = importlib.util.spec_from_file_location(
28
+ "_rein_cli", CLI, loader=SourceFileLoader("_rein_cli", CLI)
29
+ )
30
+ if spec is None or spec.loader is None: # pragma: no cover - packaging fault
31
+ print(f"rein: cannot load its own CLI at {CLI}", file=sys.stderr)
32
+ return 1
33
+ module = importlib.util.module_from_spec(spec)
34
+ spec.loader.exec_module(module)
35
+ return int(module.main(sys.argv[1:]))
36
+
37
+
38
+ if __name__ == "__main__":
39
+ raise SystemExit(main())