reins
Hold the reins of your coding agents: they respect your architecture and remember your project.
Project site: fredarcito.github.io/reins
Coding agents write code fast, but they forget your architecture (a shared component imports from a feature, an import cycle appears) and they forget your project (every session re-reads a module to work out what it does and why).
reins fixes both:
- Your architecture becomes a check. It runs on every commit and every pull request, whatever agent wrote the code. A broken rule blocks the commit with the reason and the fix, so the agent corrects it before you review. And before the edit,
reins impacttells the agent which domains consume a shared file, so a "small fix" that is really a large refactor says so before the work starts. - Each module gets a short note: what it does, how it works, the decisions taken and why, its traps. The note reaches the agent as soon as it opens a file of that module, and after a compaction the task's notebook comes back on its own.
Made for frontend teams on Vite + React or Next (app and pages router, plain JS/JSX or TypeScript) working with Claude Code, Codex, Cursor or any other agent. A Node CLI and plain markdown: no service, no API keys, no telemetry.
Requirements
- Node.js 22 or newer
- A git repository
- TypeScript projects: the
typescriptpackage already installed in the project
Install
npm install -D @agentreins/cli @agentreins/adapter-js
# pnpm add -D @agentreins/cli @agentreins/adapter-js
# yarn add -D @agentreins/cli @agentreins/adapter-js
@agentreins/cli is the reins command; @agentreins/adapter-js teaches it to read JavaScript/TypeScript imports.
Quick start
In the root of your project:
npx reins install # git hook, CI job, AGENTS.md, .reins/core/, .claude/ (--skip-claude to omit it)
npx reins init # architecture plan, baseline, module notes
npx reins check --update-baseline # freeze today's violations
npx reins check # from now on, only new violations fail
Between init and check --update-baseline:
- Review the architecture plan. In Claude Code, type
/reins-arch: your agent proposes changes with evidence and you approve each one. Otherwise read.reins/init-report.mdand edit.reins/architecture.yml. - Fill in the module notes. In Claude Code, type
/reins-notes; with other agents, ask "fill in the TODO lines of the notes in .reins/notes/".
Then commit everything. Nothing is overwritten: install and init only add files or ask first (--dry-run shows what they would do).
What you get
A plan in .reins/architecture.yml, drafted by init from your code and checked on every commit:
version: 1
adapter: js
preset: next-app
layers: # top to bottom: a layer only imports from itself and the layers below
- { name: app, paths: ["src/app/**"] }
- { name: features, paths: ["src/features/**"] }
- { name: components, paths: ["src/components/**"] }
- { name: shared, paths: ["src/lib/**", "src/hooks/**"] }
domains: # code outside a domain only imports its public API
billing: { paths: ["src/features/billing/**"], public_api: ["src/features/billing/index.js"] }
Findings an agent can fix alone, as text or --json:
✖ error layer-direction src/components/PriceTag.js → src/features/billing/index.js
Why: src/components/PriceTag.js (components) imports src/features/billing/index.js (features), but features is above components.
Fix: Move what src/components/PriceTag.js needs from features down to components or a lower layer, or invert the dependency (pass it in as props or callbacks).
reins check: 1 new (1 error, 0 warnings) · 3 in baseline · 0 fixed
Result: FAIL (new errors)
A baseline: today's violations are frozen in .reins/baseline.json, so you start green and only new problems fail. The baseline can only shrink.
The blast radius before a refactor. reins impact <file-or-folder> joins the real import graph with your plan and answers the question an agent has before touching a shared file: who else imports this?
$ npx reins impact src/lib/date.ts
File: src/lib/date.ts (no domain)
Imported by: 2 files — billing (1), no domain (1)
Public API: no
Boundary crossings: none
Existing violations: 1 (no-cycles new; run `reins check --files src/lib/date.ts` to see them)
Notes to read: .reins/notes/lib.md
Minimum level (if the change breaks importers): small (3 file(s) in 1 domain)
A boundary crossing is an import that reaches a domain's internals instead of its public API — the same leak domain-boundary reports, seen before you edit. Every import kind counts, including type-only imports: a type change breaks them too. Symbol-level questions ("who calls formatDate inside billing?") stay with grep, run inside the domains impact lists.
Module notes in .reins/notes/: one per module, drafted from the import graph and filled in by your agent. A big module keeps the notes of its parts in a folder (companies.md + companies/salaries.md); an agent working in salaries/ reads both, general first. reins notes stale ranks notes that fell behind the code.
The agent's workflow
What install sets up, in the order the agent hits it:
- Announce. Every task gets a level —
small,medium,large— from the triage policy in.reins/core/policies/.reins scope <paths>gives the objective signals: domains touched, notes to read, minimum level. - Plan. Before changing a file other domains may import (a util, a type, a barrel, a public API), the agent runs
reins impacton it. "Medium, but could be large if another domain shows up" stops being a guess. - Edit. The module note arrives the moment the agent opens a file — a Claude Code hook, or the notes index in
AGENTS.mdfor any other agent. - Close.
reins checkconfirms the boundaries instead of surprising;reins doctor(local, never in CI) compares the declared level with the branch diff and flags stale or missing notes.
Commands
| Command | What it does |
|---|---|
reins install | Wires reins into the repo: pre-commit hook (Husky or lefthook), CI workflow, .gitignore, the reins rules and notes blocks in AGENTS.md, then sync. --dry-run, --skip-claude |
reins init | Drafts architecture.yml, the baseline, a review report and the module notes from the code. --dry-run, --preset <name> |
reins check | Checks the rules (git hook and CI). --update-baseline, --coverage, --json, --files |
reins scope <paths> | Domains, public APIs, notes to read and the minimum task level for some paths. --json |
reins impact <file-or-folder> | The reverse of scope: the domains that consume a file, imports that bypass a public API, violations that already involve it, and the minimum level if the change breaks its importers. --json |
reins notes <path...> | Prints the module notes for a path (--hook: the Claude Code fast path). notes new <domain|folder> drafts one from the import graph; notes stale ranks notes behind the code. --json |
reins resume | Notebook, changed files and notes to resume a task. --json, --hook (Claude Code SessionStart) |
reins sync | Refreshes .reins/core/ (rules, policies, skills, agents), the rules and notes blocks in AGENTS.md, and the optional Claude Code files. --check, --skip-claude, --claude |
reins update | Updates the CLI and installed adapters with your package manager, then runs the new reins sync. --dry-run, --skip-claude, --claude |
reins doctor | Local workflow checks: declared task level vs the branch diff, the notebook, the notes, AGENTS.md size. Warns, never blocks, never in CI |
reins audit, reins progress, reins review | Local backlog of findings, branch notebook, review prompt |
reins <command> --help explains each one. Every command except check and init is still experimental.
Skills for your agent
reins sync keeps these skills in .reins/core/skills/ (your own versions in .reins/skills/ win). In Claude Code, type them or ask in your own words; other agents find them through AGENTS.md.
| Skill | What your agent does |
|---|---|
/reins-done | Closes a task: runs the checks once, updates the notebook and the notes of the modules it touched |
/reins-notes | Fills in module notes from the code; never invents a decision, leaves questions for you |
/reins-arch | Reviews architecture.yml against the code and proposes changes; applies nothing until you approve |
/reins-audit | Looks for improvements and adds only new findings to the backlog |
/reins-backlog | Shows what is pending and proposes what to do next |
/reins-agent | Creates a new agent definition in .reins/agents/ |
Updating
npx reins update # from 0.8.0 on: updates the packages, then runs reins sync
Coming from 0.7 or earlier, update does not exist yet: update the packages yourself (npm i -D @agentreins/cli@latest @agentreins/adapter-js@latest), then run npx reins sync once.
Read the changelog of each version you skipped: it says when something else is worth doing.
Learn more
- Project site
- Full documentation: how it works, diagrams, every option
- Walkthrough with real output
- Try it on a branch first
- Adopting it as a team
architecture.ymlreference- Changelog · Issues
License
MIT