@syv-ai/rulecast 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/chunk-K37BHCEK.js +10 -0
- package/dist/chunk-POEWJTZ2.js +3780 -0
- package/dist/clack-YPV4ZOQK.js +25 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1664 -0
- package/dist/index.d.ts +840 -0
- package/dist/index.js +327 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 syv.ai
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
<!-- Generated from the repository README by `pnpm readme`. Do not edit by hand. -->
|
|
2
|
+
|
|
3
|
+
# rulecast
|
|
4
|
+
|
|
5
|
+
Your project's conventions are written down in `AGENTS.md` or `CLAUDE.md`, and your coding agent read them once, forty tool calls ago. rulecast delivers them again at the moment they matter: when the agent is about to break one.
|
|
6
|
+
|
|
7
|
+
A rule pairs a check with a message and a pointer to the doc section it enforces. rulecast runs as an agent hook, so when the agent edits a file that breaks a rule, it gets told — in the same turn, before it moves on.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
rulecast: 1 rule violated in app/services/users.py
|
|
11
|
+
|
|
12
|
+
error backend/no-httpexception
|
|
13
|
+
app/services/users.py:2 raises HTTPException(404) in the service layer. Raise a domain exception; the API layer maps it to a response.
|
|
14
|
+
|
|
15
|
+
--- conventions/backend.md#errors ---
|
|
16
|
+
## Errors
|
|
17
|
+
|
|
18
|
+
Services raise domain exceptions. `app/api/errors.py` maps each one to a status code.
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
That is real output. The agent sees the finding *and* the paragraph of your documentation that explains it, without having to go looking.
|
|
22
|
+
|
|
23
|
+
## Getting started
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
npx @syv-ai/rulecast init
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`init` reads your project — languages, docs, which agents you use — offers a catalog of ready-made rules that apply to your files, installs the hooks for your agent, and validates what it wrote. It shows you every file it will create or change before writing anything.
|
|
30
|
+
|
|
31
|
+
Then, in your agent, ask it to draft rules for the conventions in your own docs. `init` prints the prompt to paste.
|
|
32
|
+
|
|
33
|
+
## A rule
|
|
34
|
+
|
|
35
|
+
Rules live in `.rulecast-config.yaml`:
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
repos:
|
|
39
|
+
- repo: local
|
|
40
|
+
rules:
|
|
41
|
+
- id: backend/no-httpexception
|
|
42
|
+
name: Services raise domain exceptions, not HTTPException
|
|
43
|
+
files: '^app/services/.*\.py$'
|
|
44
|
+
detect:
|
|
45
|
+
regex:
|
|
46
|
+
pattern: 'raise\s+HTTPException\((?<args>[^)]*)\)'
|
|
47
|
+
message: "{{file}}:{{line}} raises HTTPException({{args}}). Raise a domain exception."
|
|
48
|
+
context:
|
|
49
|
+
- "@conventions/backend.md#errors"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- `files` selects what the rule applies to; `detect` names one detector and its config.
|
|
53
|
+
- `message` is what the agent reads. Named capture groups become template variables.
|
|
54
|
+
- `context` points at the doc section that explains the rule — delivered alongside the finding.
|
|
55
|
+
|
|
56
|
+
A rule with `context` and no `detect` delivers guidance the first time an agent touches a matching file, with nothing to catch. That is how you carry over a convention no pattern can express.
|
|
57
|
+
|
|
58
|
+
The full format is in [`agents/reference/rule-format.md`](https://github.com/syv-ai/rulecast/blob/main/agents/reference/rule-format.md).
|
|
59
|
+
|
|
60
|
+
## Detectors
|
|
61
|
+
|
|
62
|
+
| Detector | Catches | Runs on |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| `regex` | A pattern in the file's text | every edit |
|
|
65
|
+
| `path` | The file's path alone — "never edit `src/client/`" | every edit |
|
|
66
|
+
| `ast-grep` | Structure, not text: a call shape, a swallowed exception | every edit |
|
|
67
|
+
| `command` | Whatever your own script reports, as JSON or SARIF | every edit |
|
|
68
|
+
| `linter` | ruff, oxlint or eslint findings, narrowed to the rules you care about | edit (eslint: verify) |
|
|
69
|
+
| `llm` | Conventions nothing mechanical expresses, judged by a model | verify only |
|
|
70
|
+
|
|
71
|
+
`llm` rules are opt-in, name their own model, and by default run only when the agent stops, not on every edit. A rule can ask for the edit hook with `stages: [edit, verify]`. Everything else is fast enough to run on every file the agent writes. See [`agents/reference/detectors.md`](https://github.com/syv-ai/rulecast/blob/main/agents/reference/detectors.md).
|
|
72
|
+
|
|
73
|
+
## Refusing a write
|
|
74
|
+
|
|
75
|
+
Some rules are not advice. `refuse_write: true` refuses the edit before it happens, and the agent gets your message and the doc section in place of the tool's result:
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
- id: codegen/no-edit-client
|
|
79
|
+
files: '^src/client/'
|
|
80
|
+
detect:
|
|
81
|
+
path: {}
|
|
82
|
+
refuse_write: true
|
|
83
|
+
message: "{{file}} is generated from openapi.yaml. Edit the schema and run `pnpm codegen`."
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
A refusal only ever rests on the text the agent is writing, never on a reconstruction rulecast is unsure of, and it happens once per file per session — so a rule can stop a mistake without trapping the agent. Generated code, vendored directories, files that must not change. Everything else is better reported after the write, which is what the other rules do.
|
|
87
|
+
|
|
88
|
+
## Commands
|
|
89
|
+
|
|
90
|
+
| Command | Does |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `rulecast init` | Interactive setup |
|
|
93
|
+
| `rulecast install` / `uninstall` | Add or remove the agent hooks |
|
|
94
|
+
| `rulecast run` | Check staged files, changed files, or everything |
|
|
95
|
+
| `rulecast validate` | Check the config and print diagnostics |
|
|
96
|
+
| `rulecast doctor` | Compile, check the environment, dry-run every rule |
|
|
97
|
+
| `rulecast autoupdate` | Move pinned rule repos to their latest tag |
|
|
98
|
+
| `rulecast try-repo` | Run a rule repo against your project without configuring it |
|
|
99
|
+
| `rulecast clean` | Delete the cache |
|
|
100
|
+
| `rulecast warm` | Build detector caches ahead of time |
|
|
101
|
+
| `rulecast hook <adapter>` | Answer an agent hook on stdin |
|
|
102
|
+
|
|
103
|
+
`rulecast run` is also how you use rulecast in CI. `--from-ref main` checks only what a branch changed, which matters most for `llm` rules — they judge changed files only.
|
|
104
|
+
|
|
105
|
+
If something is configured but quiet, `rulecast doctor` says why: it compiles the config, reports whether each rule's linter, parser, script or API key is actually there, says where the hooks and caches live, and runs every rule against one file it matches.
|
|
106
|
+
|
|
107
|
+
## Agents
|
|
108
|
+
|
|
109
|
+
rulecast ships docs written for coding agents, not for people:
|
|
110
|
+
|
|
111
|
+
- [`agents/SETUP.md`](https://github.com/syv-ai/rulecast/blob/main/agents/SETUP.md) — give this to your agent and it will set rulecast up itself.
|
|
112
|
+
- [`agents/DRAFT-RULES.md`](https://github.com/syv-ai/rulecast/blob/main/agents/DRAFT-RULES.md) — it reads your `AGENTS.md`, proposes one rule per convention that code can visibly break, shows you what each would flag today, and asks you to keep, edit or drop it.
|
|
113
|
+
|
|
114
|
+
Claude Code is the supported agent today. Codex, Cursor and OpenCode are next; rulecast is agent-neutral by design, and only the adapter knows about a specific agent.
|
|
115
|
+
|
|
116
|
+
## Install
|
|
117
|
+
|
|
118
|
+
**npm — use this for agent hooks.**
|
|
119
|
+
|
|
120
|
+
```sh
|
|
121
|
+
pnpm add -D @syv-ai/rulecast # or npm / yarn
|
|
122
|
+
npx @syv-ai/rulecast init
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Standalone binary — use this for CI and one-off runs.** Download it from [Releases](https://github.com/syv-ai/rulecast/releases). It needs no Node installation.
|
|
126
|
+
|
|
127
|
+
Prefer the npm install for hooks. The binary extracts and loads its embedded ast-grep parser on every run, which costs about 260 ms: a `rulecast run` that takes ~110 ms under Node takes ~370 ms as a binary (measured on an Apple M3 Pro). That is invisible in CI and too slow for a hook that fires on every file an agent writes.
|
|
128
|
+
|
|
129
|
+
Node ≥ 20.12. Linux and macOS; Windows is not supported.
|
|
130
|
+
|
|
131
|
+
## Performance
|
|
132
|
+
|
|
133
|
+
The edit hook is budgeted to finish in under 500 ms at p95 — measured from process start to exit, on a 30-rule project with warm caches, excluding `llm` rules. `pnpm perf` replays 50 edit events and checks it. The last measurement, on an Apple M3 Pro with all six detectors configured, was p50 170 ms and p95 187 ms.
|
|
134
|
+
|
|
135
|
+
The budget is what shapes the design: one detector run per kind per event, kinds in parallel, slow tools defaulted to `verify`, content-addressed caches on disk, no daemon. When an edit runs long, rulecast delivers what finished and builds the rest in the background rather than making the agent wait.
|
|
136
|
+
|
|
137
|
+
## Status
|
|
138
|
+
|
|
139
|
+
0.1. Everything above works and is tested. The config format may still change before 1.0 — `minimum_rulecast_version` exists so a rule can say what it needs.
|
|
140
|
+
|
|
141
|
+
Next: adapters for Codex, Cursor and OpenCode; Biome; rule tests (good and bad examples run by `rulecast test`); an Azure OpenAI provider.
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT — see [LICENSE](https://github.com/syv-ai/rulecast/blob/main/LICENSE).
|