claude-crap 0.3.4 → 0.3.6
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/CHANGELOG.md +29 -0
- package/README.md +116 -472
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +112 -48
- package/dist/dashboard/server.js.map +1 -1
- package/dist/sarif/sarif-store.d.ts.map +1 -1
- package/dist/sarif/sarif-store.js +1 -1
- package/dist/sarif/sarif-store.js.map +1 -1
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.mcp.json +1 -2
- package/plugin/bundle/mcp-server.mjs +119 -85
- package/plugin/bundle/mcp-server.mjs.map +3 -3
- package/plugin/eslint.config.mjs +12 -0
- package/plugin/hooks/lib/hook-io.mjs +1 -1
- package/plugin/hooks/pre-tool-use.mjs +1 -1
- package/plugin/package-lock.json +2 -2
- package/plugin/package.json +1 -1
- package/scripts/bundle-plugin.mjs +53 -2
- package/scripts/doctor.mjs +2 -2
- package/src/dashboard/server.ts +137 -61
- package/src/sarif/sarif-store.ts +1 -0
package/README.md
CHANGED
|
@@ -12,560 +12,204 @@
|
|
|
12
12
|
> ship.
|
|
13
13
|
|
|
14
14
|
`claude-crap` turns Claude Code into a disciplined QA engineer. It
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
decision that touches source code, tests, or configuration must be
|
|
24
|
-
backed by a result from one of the deterministic engines exposed by
|
|
25
|
-
the plugin's MCP server — `compute_crap`, `compute_tdr`,
|
|
26
|
-
`analyze_file_ast`, `ingest_sarif`, `ingest_scanner_output`,
|
|
27
|
-
`require_test_harness`, and `score_project`.
|
|
28
|
-
|
|
15
|
+
wraps every `Write`, `Edit`, and `Bash` call with a synchronous
|
|
16
|
+
**PreToolUse gatekeeper**, a retrospective **PostToolUse verifier**,
|
|
17
|
+
and a final **Stop quality gate** that refuses to close a task until
|
|
18
|
+
maintainability, reliability, and security ratings pass policy.
|
|
19
|
+
|
|
20
|
+
Every decision that touches source code must be backed by a result
|
|
21
|
+
from the deterministic MCP engines — `compute_crap`, `compute_tdr`,
|
|
22
|
+
`analyze_file_ast`, `ingest_sarif`, `score_project`, and others.
|
|
29
23
|
This is the **Fat Platform / Thin Agent** thesis: the LLM is an
|
|
30
|
-
efficient worker, but the rails are mathematical
|
|
31
|
-
|
|
24
|
+
efficient worker, but the rails are mathematical and outside the
|
|
25
|
+
model's reach.
|
|
32
26
|
|
|
33
|
-
> **CRAP** stands for **Change Risk Anti-Patterns** — a
|
|
34
|
-
>
|
|
35
|
-
>
|
|
36
|
-
> Read the original post:
|
|
37
|
-
> [This Code is CRAP](https://testing.googleblog.com/2011/02/this-code-is-crap.html).
|
|
27
|
+
> **CRAP** stands for **Change Risk Anti-Patterns** — a metric
|
|
28
|
+
> originally developed by Alberto Savoia and Bob Evans at Google (2007).
|
|
29
|
+
> [Read the original post.](https://testing.googleblog.com/2011/02/this-code-is-crap.html)
|
|
38
30
|
|
|
39
|
-
[Quick Start](#quick-start)
|
|
31
|
+
[Quick Start](#quick-start) · [Configuration](#configuration) · [How It Works](#how-it-works) · [MCP Tools](#mcp-tools) · [Documentation](#documentation) · [Development](#development) · [Contributing](#contributing)
|
|
40
32
|
|
|
41
33
|
---
|
|
42
34
|
|
|
43
35
|
## Quick Start
|
|
44
36
|
|
|
45
|
-
`claude-crap` ships as a single npm package. One command prepares
|
|
46
|
-
the workspace and prints the Claude Code slash command you need to
|
|
47
|
-
run next:
|
|
48
|
-
|
|
49
37
|
```bash
|
|
50
38
|
npx claude-crap install
|
|
51
39
|
```
|
|
52
40
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
script executable, and prints the exact Claude Code command to
|
|
57
|
-
register the plugin:
|
|
41
|
+
This downloads the package, compiles `dist/` from source, creates
|
|
42
|
+
`.claude-crap/reports/` in your project, and prints the Claude Code
|
|
43
|
+
command to register the plugin:
|
|
58
44
|
|
|
59
45
|
```
|
|
60
|
-
✓ claude-crap is ready to register with Claude Code.
|
|
61
|
-
|
|
62
|
-
Plugin root: /.../claude-crap
|
|
63
|
-
|
|
64
46
|
Next steps — pick ONE of the following:
|
|
65
47
|
|
|
66
|
-
1. Native
|
|
48
|
+
1. Native install:
|
|
67
49
|
/plugin install /.../claude-crap
|
|
68
50
|
|
|
69
|
-
2. Marketplace install
|
|
51
|
+
2. Marketplace install:
|
|
70
52
|
/plugin marketplace add https://github.com/ahernandez-developer/claude-crap
|
|
71
53
|
/plugin install claude-crap@herz
|
|
72
54
|
```
|
|
73
55
|
|
|
74
|
-
Once
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
runs on every tool call and the Stop quality gate runs on every
|
|
79
|
-
task close — no further setup required.
|
|
80
|
-
|
|
81
|
-
> **Two install channels are live:**
|
|
82
|
-
>
|
|
83
|
-
> - **npm** — `npx claude-crap install` (direct, works anywhere `npx` does)
|
|
84
|
-
> - **Claude Code marketplace** — `/plugin marketplace add https://github.com/ahernandez-developer/claude-crap` followed by `/plugin install claude-crap@herz`. Claude Code resolves the marketplace entry's `source` to `claude-crap@0.3.4` on the npm registry, so both routes unpack the **same tarball** and get the same SHA.
|
|
85
|
-
|
|
86
|
-
### Marketplace cache troubleshooting
|
|
87
|
-
|
|
88
|
-
The Claude Code desktop app caches plugin metadata from the
|
|
89
|
-
marketplace. If you didn't see the plugin in desktop app while installing, run these
|
|
90
|
-
steps in order:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
# 1. Force the marketplace to re-fetch metadata for the publisher
|
|
94
|
-
claude plugin marketplace update herz
|
|
95
|
-
|
|
96
|
-
# 2. Reinstall the plugin under the current name
|
|
97
|
-
claude plugin install claude-crap
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Then **restart the Claude Code desktop app** to clear the in-memory
|
|
101
|
-
cache. This is expected behavior whenever a plugin is renamed or its
|
|
102
|
-
metadata changes — the marketplace does not auto-invalidate cached
|
|
103
|
-
listings.
|
|
56
|
+
Once registered, open any new session. The **SessionStart** hook
|
|
57
|
+
prints a briefing with thresholds and the dashboard URL. From that
|
|
58
|
+
point the PreToolUse gatekeeper and Stop quality gate run
|
|
59
|
+
automatically — no further setup required.
|
|
104
60
|
|
|
105
61
|
---
|
|
106
62
|
|
|
107
63
|
## Configuration
|
|
108
64
|
|
|
109
|
-
> **Default: `strict`.**
|
|
110
|
-
>
|
|
111
|
-
> quality gate on any policy violation — same behavior the plugin
|
|
112
|
-
> has always had. The rest of this section only matters if you want
|
|
113
|
-
> to loosen that enforcement while adopting the plugin gradually.
|
|
114
|
-
|
|
115
|
-
The `strictness` value controls how the **Stop quality gate** and
|
|
116
|
-
the **`score_project` MCP tool** react when a policy fails. The
|
|
117
|
-
PreToolUse security gatekeeper (blocked paths, destructive Bash,
|
|
118
|
-
hardcoded secrets) is **always** strict regardless of this setting —
|
|
119
|
-
security is not a quality gradient.
|
|
65
|
+
> **Default: `strict`.** No config file needed. The Stop gate
|
|
66
|
+
> hard-fails on any policy violation out of the box.
|
|
120
67
|
|
|
121
|
-
|
|
122
|
-
| :--------- | :------------: | :----------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
123
|
-
| `strict` | `2` | **stderr** | The full `BLOCKED` box is injected into the agent's context. The task cannot close until the rules are satisfied. **Default — nothing to configure.** |
|
|
124
|
-
| `warn` | `0` | **stdout** | The full `WARNING` box lands in the hook transcript so the agent still sees every failing rule, but the task is allowed to close. Agent can remediate voluntarily. |
|
|
125
|
-
| `advisory` | `0` | **stdout** | A single-line `ADVISORY` note is emitted. Minimal pressure on the agent — the task closes with a soft nudge only. |
|
|
68
|
+
The `strictness` value controls how the Stop gate reacts to failures:
|
|
126
69
|
|
|
127
|
-
|
|
70
|
+
| Mode | Stop exit | Effect |
|
|
71
|
+
| :--------- | :-------: | :------------------------------------------------------------- |
|
|
72
|
+
| `strict` | `2` | Task cannot close until rules pass. **Default.** |
|
|
73
|
+
| `warn` | `0` | Full verdict visible to agent, but task closes. |
|
|
74
|
+
| `advisory` | `0` | Single-line nudge only. |
|
|
128
75
|
|
|
129
|
-
|
|
130
|
-
default back with a single file at the workspace root:
|
|
76
|
+
Override per workspace:
|
|
131
77
|
|
|
132
78
|
```jsonc
|
|
133
|
-
// .claude-crap.json — commit
|
|
79
|
+
// .claude-crap.json — commit to git for team-wide policy
|
|
134
80
|
{
|
|
135
|
-
"
|
|
136
|
-
"strictness": "warn", // "strict" | "warn" | "advisory"
|
|
81
|
+
"strictness": "warn"
|
|
137
82
|
}
|
|
138
83
|
```
|
|
139
84
|
|
|
140
|
-
Or
|
|
85
|
+
Or per session: `CLAUDE_CRAP_STRICTNESS=advisory claude`
|
|
141
86
|
|
|
142
|
-
|
|
143
|
-
CLAUDE_CRAP_STRICTNESS=advisory claude
|
|
144
|
-
```
|
|
87
|
+
**Precedence:** env var > `.claude-crap.json` > hardcoded `strict`.
|
|
145
88
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
1. `CLAUDE_CRAP_STRICTNESS` environment variable — session-level
|
|
149
|
-
override. Useful for a one-off lenient run without editing the
|
|
150
|
-
committed policy.
|
|
151
|
-
2. `.claude-crap.json` at the workspace root — team-committed
|
|
152
|
-
default. Everyone who clones the repo gets the same policy.
|
|
153
|
-
3. Hardcoded default `"strict"` — applies when neither source is
|
|
154
|
-
present. **You don't need to create either the file or the env
|
|
155
|
-
var to get strict mode.**
|
|
156
|
-
|
|
157
|
-
### How to adopt gradually
|
|
158
|
-
|
|
159
|
-
Start in `advisory` so the agent simply annotates its sessions with
|
|
160
|
-
a quality reading. Once the team is comfortable, bump to `warn` so
|
|
161
|
-
the full verdict lands in the hook transcript and the agent sees
|
|
162
|
-
every failing rule. When the project is clean enough to ship under
|
|
163
|
-
policy, delete the file (or switch it to `strict`) and let CI catch
|
|
164
|
-
any regression.
|
|
165
|
-
|
|
166
|
-
The `.claude-crap.json` file is a plain JSON document designed to
|
|
167
|
-
be committed alongside the code. It is intentionally **not** matched
|
|
168
|
-
by the `.claude-crap/` gitignore rule (which only covers the
|
|
169
|
-
runtime state directory), so `git add .claude-crap.json` just works.
|
|
170
|
-
|
|
171
|
-
### Compliance with Claude Code's plugin recommendations
|
|
172
|
-
|
|
173
|
-
The [Claude Code plugins reference](https://code.claude.com/docs/en/plugins-reference#user-configuration)
|
|
174
|
-
documents exactly one canonical pattern for collecting plugin user
|
|
175
|
-
configuration:
|
|
176
|
-
|
|
177
|
-
> The `userConfig` field declares values that Claude Code prompts
|
|
178
|
-
> the user for when the plugin is enabled. Use this instead of
|
|
179
|
-
> requiring users to hand-edit `settings.json`.
|
|
180
|
-
|
|
181
|
-
**`claude-crap` deliberately deviates from that pattern** and reads
|
|
182
|
-
`.claude-crap.json` from the workspace root instead. We chose this
|
|
183
|
-
knowingly, not by accident. The trade-off:
|
|
184
|
-
|
|
185
|
-
- The canonical `userConfig` pattern prompts every user at
|
|
186
|
-
`/plugin install` time, stores the answer in Claude Code's own
|
|
187
|
-
`.claude/settings.json` under `pluginConfigs[claude-crap].options`,
|
|
188
|
-
and exposes it as `${user_config.KEY}` or `CLAUDE_PLUGIN_OPTION_KEY`.
|
|
189
|
-
It is the right channel for per-user secrets like API tokens.
|
|
190
|
-
- For an **enum policy with a sensible default** (`strict`), an
|
|
191
|
-
install-time prompt is friction with no upside: 99% of users will
|
|
192
|
-
just accept the default, and the 1% who want to tune it are
|
|
193
|
-
better served by committing a JSON file to git alongside the rest
|
|
194
|
-
of their project's quality config (`.eslintrc.json`,
|
|
195
|
-
`.prettierrc.json`, `biome.json`, `tsconfig.json`, etc.).
|
|
196
|
-
- The workspace file also lets us ship a proper JSON schema under
|
|
197
|
-
[`schemas/crap-config.json`](./schemas/crap-config.json) for
|
|
198
|
-
IDE autocompletion and CI validation — `userConfig` has no
|
|
199
|
-
equivalent surface.
|
|
200
|
-
|
|
201
|
-
So the honest answer to "are we in compliance with the Claude Code
|
|
202
|
-
recommendations?" is: **we comply with every other part of the
|
|
203
|
-
plugin spec** (manifest schema, hook events, MCP server location,
|
|
204
|
-
substitution tokens, directory layout) and **we deviate from one**:
|
|
205
|
-
user configuration, where we read a workspace file instead of
|
|
206
|
-
declaring a `userConfig` prompt. The deviation is documented here
|
|
207
|
-
and in `CHANGELOG.md`.
|
|
89
|
+
See [docs/quality-gate.md](./docs/quality-gate.md) for the full
|
|
90
|
+
CRAP formula, TDR formula, letter ratings, and adoption strategy.
|
|
208
91
|
|
|
209
92
|
---
|
|
210
93
|
|
|
211
|
-
##
|
|
212
|
-
|
|
213
|
-
Deep reference lives under [`docs/`](./docs/README.md). Everything
|
|
214
|
-
below is indexed from the [docs README](./docs/README.md) so you can
|
|
215
|
-
navigate there if you prefer browsing by chapter.
|
|
216
|
-
|
|
217
|
-
### Getting Started
|
|
218
|
-
|
|
219
|
-
- [Architecture Overview](./docs/architecture-overview.md) — the Fat
|
|
220
|
-
Platform / Thin Agent thesis, boot sequence, data flow, and the
|
|
221
|
-
design decisions behind stdio-only transport and loopback-only
|
|
222
|
-
dashboard.
|
|
223
|
-
- [Quick install walk-through](./docs/README.md) — the step-by-step
|
|
224
|
-
version of the [Quick Start](#quick-start) above, including first
|
|
225
|
-
run expectations and the `claude-crap doctor` diagnostic.
|
|
226
|
-
|
|
227
|
-
### Architecture & Concepts
|
|
228
|
-
|
|
229
|
-
- [Quality gate and math](./docs/quality-gate.md) — CRAP formula,
|
|
230
|
-
TDR formula, letter ratings, Stop hook policies.
|
|
231
|
-
- [Project score](./docs/scoring.md) — how Maintainability /
|
|
232
|
-
Reliability / Security / Overall A..E grades are aggregated and
|
|
233
|
-
rendered to chat.
|
|
234
|
-
- [Hooks reference](./docs/hooks.md) — every Claude Code lifecycle
|
|
235
|
-
hook, contract, rule catalog, and extension points.
|
|
236
|
-
|
|
237
|
-
### Reference
|
|
238
|
-
|
|
239
|
-
- [MCP tools reference](./docs/mcp-tools.md) — schemas, inputs,
|
|
240
|
-
outputs, and error semantics for every MCP tool and resource.
|
|
241
|
-
- [Scanner adapters](./docs/scanner-adapters.md) — Semgrep, ESLint,
|
|
242
|
-
Bandit, Stryker — mapping rules, effort tables, how to add a new
|
|
243
|
-
adapter.
|
|
244
|
-
- [SDK reference](./docs/sdk.md) — every symbol exported from
|
|
245
|
-
`claude-crap`, `claude-crap/metrics`,
|
|
246
|
-
`claude-crap/sarif`, `claude-crap/ast`,
|
|
247
|
-
`claude-crap/tools`, `claude-crap/adapters`.
|
|
248
|
-
|
|
249
|
-
### Contributing & Releases
|
|
250
|
-
|
|
251
|
-
- [Contributing guide](./docs/contributing.md) — dev loop, test
|
|
252
|
-
layout, coding conventions, release process.
|
|
253
|
-
- [Changelog](./CHANGELOG.md) — Keep-a-Changelog-formatted release
|
|
254
|
-
history, with the security subsection documenting every OWASP
|
|
255
|
-
Top 10:2025 finding that shipped fixed in `v0.1.0`.
|
|
256
|
-
- [Agent contract (CLAUDE.md)](./plugin/CLAUDE.md) — the Golden Rule that is
|
|
257
|
-
auto-injected into every Claude Code session where the plugin is
|
|
258
|
-
active.
|
|
94
|
+
## How It Works
|
|
259
95
|
|
|
260
|
-
|
|
96
|
+
| Component | File | Role |
|
|
97
|
+
| :-------- | :--- | :--- |
|
|
98
|
+
| **PreToolUse gatekeeper** | `plugin/hooks/pre-tool-use.mjs` | Blocks sensitive paths, destructive Bash, hardcoded secrets, path traversal — `exit 2` injects the corrective message into the agent's context. |
|
|
99
|
+
| **PostToolUse verifier** | `plugin/hooks/post-tool-use.mjs` | Warns on missing test harness, suppression markers (`eslint-disable`, `@ts-ignore`, `# nosec`), and TODO/FIXME/HACK. |
|
|
100
|
+
| **Stop quality gate** | `plugin/hooks/stop-quality-gate.mjs` | Reads the SARIF store, computes CRAP / TDR / reliability / security ratings, and blocks task close if any metric is outside policy. |
|
|
101
|
+
| **MCP server** | `src/index.ts` | Stdio-transport server exposing CRAP, TDR, tree-sitter AST, and SARIF engines as deterministic tools. |
|
|
102
|
+
| **SARIF store** | `src/sarif/sarif-store.ts` | On-disk consolidated report with finding deduplication. Tolerates malformed entries so a tampered file can't DoS the boot. |
|
|
103
|
+
| **Scanner adapters** | `src/adapters/` | Semgrep, ESLint, Bandit, Stryker — each stamps `effortMinutes` for uniform TDR computation. |
|
|
104
|
+
| **Dashboard** | `src/dashboard/server.ts` | Fastify on `127.0.0.1:5117` serving a Vue 3 SPA. Offline-capable (vendored runtime). Port auto-fallback on conflict. |
|
|
261
105
|
|
|
262
|
-
|
|
106
|
+
All findings are normalized to **SARIF 2.1.0** — one vocabulary,
|
|
107
|
+
exact coordinates, no grep walls in the context window.
|
|
263
108
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
1. **PreToolUse gatekeeper** (`plugin/hooks/pre-tool-use.mjs`). A
|
|
267
|
-
synchronous, zero-I/O speed bump that inspects the proposed
|
|
268
|
-
`tool_input` before the tool runs. Sensitive paths, destructive
|
|
269
|
-
Bash, hardcoded secrets, and path-traversal attempts trigger
|
|
270
|
-
`exit 2`, which Claude Code converts into an injection into the
|
|
271
|
-
agent's context — the model then rethinks the approach with the
|
|
272
|
-
exact corrective message in hand. For the high-risk tool
|
|
273
|
-
allowlist (`Write`, `Edit`, `MultiEdit`, `NotebookEdit`, `Bash`),
|
|
274
|
-
any failure to evaluate the rules fails **closed**, so the gate
|
|
275
|
-
cannot be bypassed by crashing a rule.
|
|
276
|
-
|
|
277
|
-
2. **PostToolUse verifier** (`plugin/hooks/post-tool-use.mjs`). Runs
|
|
278
|
-
immediately after a file-mutating tool call and scans the
|
|
279
|
-
just-written artifact for a missing test harness, inline
|
|
280
|
-
suppression markers (`eslint-disable`, `@ts-ignore`, `# nosec`,
|
|
281
|
-
`# type: ignore`), and fresh TODO / FIXME / HACK markers.
|
|
282
|
-
Warnings are emitted on stderr — non-blocking, but the Stop gate
|
|
283
|
-
will enforce the strict verdict later.
|
|
284
|
-
|
|
285
|
-
3. **Stop / SubagentStop quality gate**
|
|
286
|
-
(`plugin/hooks/stop-quality-gate.mjs`). When the agent declares a task
|
|
287
|
-
done, this hook reads the consolidated SARIF report, computes
|
|
288
|
-
CRAP / TDR / reliability / security ratings against the entire
|
|
289
|
-
workspace, and refuses to let the task close if any metric is
|
|
290
|
-
outside policy. The corrective message lists every failing rule
|
|
291
|
-
so the agent can remediate on the next turn.
|
|
292
|
-
|
|
293
|
-
4. **Deterministic MCP server** (`src/index.ts`). A Node.js
|
|
294
|
-
stdio-transport MCP server that exposes the math engines
|
|
295
|
-
(CRAP, TDR, tree-sitter AST, SARIF store with deduplication) as
|
|
296
|
-
first-class tools. Everything is a pure function or a small
|
|
297
|
-
class; no engine performs I/O outside the SARIF store's on-disk
|
|
298
|
-
persistence.
|
|
299
|
-
|
|
300
|
-
5. **SARIF 2.1.0 store** (`src/sarif/sarif-store.ts`). On-disk
|
|
301
|
-
consolidated report with finding deduplication by
|
|
302
|
-
`(ruleId, uri, startLine, startColumn)`. Loading tolerates
|
|
303
|
-
malformed entries (per-run and per-result try/catch) so a
|
|
304
|
-
tampered `latest.sarif` cannot DoS the MCP server boot. Every
|
|
305
|
-
incoming document is validated against a minimal AJV 2.1.0
|
|
306
|
-
schema before it is persisted.
|
|
307
|
-
|
|
308
|
-
6. **Per-scanner adapters** (`src/adapters/`). Semgrep (SARIF
|
|
309
|
-
passthrough with enrichment), ESLint (native JSON), Bandit
|
|
310
|
-
(native JSON), Stryker (JSON mutation report). Every adapter
|
|
311
|
-
stamps `properties.effortMinutes` on each finding so the Stop
|
|
312
|
-
gate and the project score engine can compute a uniform
|
|
313
|
-
Technical Debt Ratio across scanner families.
|
|
314
|
-
|
|
315
|
-
7. **Local dashboard** (`src/dashboard/server.ts`). A Fastify HTTP
|
|
316
|
-
server that binds to `127.0.0.1` only — never `0.0.0.0` — and
|
|
317
|
-
serves a Vue 3 SPA from `src/dashboard/public/`. The Vue runtime
|
|
318
|
-
is vendored under `src/dashboard/public/vendor/` so the
|
|
319
|
-
dashboard works offline after install and is not exposed to
|
|
320
|
-
CDN-compromise or first-boot-MITM attacks.
|
|
321
|
-
|
|
322
|
-
All findings are normalized to **SARIF 2.1.0** before the agent ever
|
|
323
|
-
sees them. One vocabulary, exact file / line / column coordinates,
|
|
324
|
-
and no walls of grep output polluting the context window.
|
|
325
|
-
|
|
326
|
-
See [Architecture Overview](./docs/architecture-overview.md) for the
|
|
327
|
-
boot sequence, the full data-flow diagram, and the design decisions
|
|
328
|
-
behind each component.
|
|
109
|
+
See [docs/architecture-overview.md](./docs/architecture-overview.md)
|
|
110
|
+
for the boot sequence, data flow, and design decisions.
|
|
329
111
|
|
|
330
112
|
---
|
|
331
113
|
|
|
332
114
|
## MCP Tools
|
|
333
115
|
|
|
334
|
-
|
|
335
|
-
Every tool has a strict JSON Schema (Draft-07) with
|
|
336
|
-
`additionalProperties: false`, `enum`, `pattern`, and numeric bounds,
|
|
337
|
-
so any drift from the contract produces a deterministic error the
|
|
338
|
-
agent can consume and correct.
|
|
339
|
-
|
|
340
|
-
**The three-layer workflow.** For any non-trivial quality task the
|
|
341
|
-
agent follows the same three-step pattern, mirroring how the
|
|
342
|
-
platform is designed to be used:
|
|
343
|
-
|
|
344
|
-
1. **Analyze** — `analyze_file_ast` for per-function metrics, or
|
|
345
|
-
`compute_crap` / `compute_tdr` when coverage and LOC are already
|
|
346
|
-
known.
|
|
347
|
-
2. **Ingest** — `ingest_sarif` or `ingest_scanner_output` to fold
|
|
348
|
-
external scanner output (Semgrep, ESLint, Bandit, Stryker) into
|
|
349
|
-
the consolidated SARIF store with deduplication.
|
|
350
|
-
3. **Score** — `score_project` to aggregate everything into a
|
|
351
|
-
single Markdown + JSON verdict with A..E grades per dimension.
|
|
352
|
-
|
|
353
|
-
**Available MCP tools:**
|
|
354
|
-
|
|
355
|
-
| Tool | Purpose | Key inputs |
|
|
356
|
-
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
357
|
-
| `compute_crap` | CRAP index for a single function plus a block verdict against the configured threshold. | `cyclomaticComplexity`, `coveragePercent`, `functionName`, `filePath` |
|
|
358
|
-
| `compute_tdr` | Technical Debt Ratio and A..E maintainability rating for a project / module / file scope. | `remediationMinutes`, `totalLinesOfCode`, `scope` |
|
|
359
|
-
| `analyze_file_ast` | Tree-sitter AST metrics: physical and logical LOC plus per-function cyclomatic complexity. Supports TypeScript, JavaScript, Python, Java, C#. | `filePath`, `language` |
|
|
360
|
-
| `ingest_sarif` | Merge a raw SARIF 2.1.0 document into the store with deduplication. Validated against a minimal AJV schema before persistence. | `sarifDocument`, `sourceTool` |
|
|
361
|
-
| `ingest_scanner_output` | Route a scanner's native output through the matching adapter, enrich each finding with an `effortMinutes` estimate, and persist as SARIF. | `scanner` (`semgrep` / `eslint` / `bandit` / `stryker`), `rawOutput` |
|
|
362
|
-
| `require_test_harness` | Check whether a production source file has an accompanying test file in any of the supported conventions. | `filePath` |
|
|
363
|
-
| `score_project` | Aggregate the entire workspace into Maintainability / Reliability / Security / Overall A..E grades with Markdown and JSON output. | `format` (`markdown` / `json` / `both`) |
|
|
364
|
-
| `auto_scan` | Auto-detect available scanners (ESLint, Semgrep, Bandit, Stryker) in the workspace, run them, and ingest findings into the SARIF store. | (none — fully automatic) |
|
|
365
|
-
| `bootstrap_scanner` | Detect project type (JS/TS/Python/Java/C#), install the right scanner, create minimal config, and run auto_scan to verify. | (none — fully automatic) |
|
|
366
|
-
|
|
367
|
-
**Available MCP resources:**
|
|
368
|
-
|
|
369
|
-
| URI | MIME | Description |
|
|
370
|
-
| ------------------------------ | ------------------------ | ------------------------------------------------------------------- |
|
|
371
|
-
| `sonar://metrics/current` | `application/json` | Live CRAP / TDR / rating snapshot derived from the in-memory store. |
|
|
372
|
-
| `sonar://reports/latest.sarif` | `application/sarif+json` | Last consolidated SARIF document produced by the Stop quality gate. |
|
|
373
|
-
|
|
374
|
-
**Example usage.** From an agent session, the tool call a typical
|
|
375
|
-
pre-publication audit lands on:
|
|
376
|
-
|
|
377
|
-
```ts
|
|
378
|
-
// Fold a Semgrep SARIF report into the store.
|
|
379
|
-
await tools.ingest_scanner_output({
|
|
380
|
-
scanner: "semgrep",
|
|
381
|
-
rawOutput: readFileSync("./semgrep.sarif", "utf8"),
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
// Ask for the final verdict as Markdown + JSON.
|
|
385
|
-
const score = await tools.score_project({ format: "both" });
|
|
386
|
-
// score.isError === true ⇒ the agent must remediate before closing
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
And from a consumer that wants to embed the engines directly without
|
|
390
|
-
running the MCP server:
|
|
391
|
-
|
|
392
|
-
```ts
|
|
393
|
-
import {
|
|
394
|
-
computeCrap,
|
|
395
|
-
computeTdr,
|
|
396
|
-
computeProjectScore,
|
|
397
|
-
SarifStore,
|
|
398
|
-
TreeSitterEngine,
|
|
399
|
-
} from "claude-crap";
|
|
400
|
-
```
|
|
116
|
+
Nine deterministic tools and two resources, all with strict JSON Schema validation.
|
|
401
117
|
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
118
|
+
| Tool | Purpose |
|
|
119
|
+
| :--- | :------ |
|
|
120
|
+
| `compute_crap` | CRAP index for a single function + block verdict against threshold. |
|
|
121
|
+
| `compute_tdr` | Technical Debt Ratio and A..E maintainability rating. |
|
|
122
|
+
| `analyze_file_ast` | Tree-sitter AST metrics: LOC + per-function cyclomatic complexity. TypeScript, JavaScript, Python, Java, C#. |
|
|
123
|
+
| `ingest_sarif` | Merge a raw SARIF 2.1.0 document into the store with deduplication. |
|
|
124
|
+
| `ingest_scanner_output` | Route native scanner output through adapter, enrich with `effortMinutes`, persist as SARIF. |
|
|
125
|
+
| `require_test_harness` | Check whether a source file has an accompanying test file. |
|
|
126
|
+
| `score_project` | Aggregate workspace into Maintainability / Reliability / Security / Overall A..E grades. |
|
|
127
|
+
| `auto_scan` | Auto-detect scanners, run them, ingest findings. |
|
|
128
|
+
| `bootstrap_scanner` | Detect project type, install the right scanner, configure, and verify. |
|
|
406
129
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
130
|
+
| Resource | Description |
|
|
131
|
+
| :------- | :---------- |
|
|
132
|
+
| `sonar://metrics/current` | Live CRAP / TDR / rating snapshot. |
|
|
133
|
+
| `sonar://reports/latest.sarif` | Consolidated SARIF document. |
|
|
410
134
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
- **Bun ≥ 1.0** is also supported as an alternative runtime:
|
|
414
|
-
`bun run build`, `bun test`, and `bun ./dist/index.js` all work
|
|
415
|
-
out of the box. CI runs against both Node and Bun.
|
|
416
|
-
- **Claude Code** with local plugin support. The plugin registers
|
|
417
|
-
itself via the native `/plugin install` slash command — no manual
|
|
418
|
-
`settings.json` surgery required.
|
|
419
|
-
- **A POSIX-compatible shell** for the hook scripts (Bash, Zsh, or
|
|
420
|
-
any POSIX `/bin/sh`). On Windows, WSL or Git Bash works.
|
|
421
|
-
- **Zero native dependencies.** The MCP server ships as pure
|
|
422
|
-
Node.js with WASM-backed tree-sitter, so `npm install` never
|
|
423
|
-
invokes a C compiler or a linker.
|
|
424
|
-
|
|
425
|
-
### Windows Setup Notes
|
|
426
|
-
|
|
427
|
-
On native Windows (no WSL), the hook scripts rely on a POSIX shell.
|
|
428
|
-
If you hit `'./plugin/hooks/pre-tool-use.mjs' is not recognized as an
|
|
429
|
-
internal or external command`, install [Git for Windows](https://gitforwindows.org/)
|
|
430
|
-
and make sure its `usr/bin` directory is on your `PATH` so `bash`
|
|
431
|
-
and `env` are available to Node's `child_process.spawn`. Using WSL
|
|
432
|
-
2 sidesteps the issue entirely and is the recommended path for
|
|
433
|
-
Windows developers who run Claude Code locally.
|
|
135
|
+
Full schemas, inputs, outputs, and examples in
|
|
136
|
+
[docs/mcp-tools.md](./docs/mcp-tools.md).
|
|
434
137
|
|
|
435
138
|
---
|
|
436
139
|
|
|
437
|
-
##
|
|
438
|
-
|
|
439
|
-
All commands run from the repo root — there is no nested package.
|
|
440
|
-
|
|
441
|
-
```bash
|
|
442
|
-
# Type-check only
|
|
443
|
-
npm run typecheck
|
|
444
|
-
|
|
445
|
-
# Canonical build with full type-checking + declaration files (the
|
|
446
|
-
# build CI and `np release` both call).
|
|
447
|
-
npm run build
|
|
448
|
-
|
|
449
|
-
# Fast dev build via esbuild — 10-20x faster than tsc, but no type
|
|
450
|
-
# check and no .d.ts files. Pair with `npm run typecheck` in watch
|
|
451
|
-
# mode for the fastest feedback loop.
|
|
452
|
-
npm run build:fast
|
|
453
|
-
|
|
454
|
-
# Watch mode for hot rebuilds during source edits
|
|
455
|
-
npm run build:watch
|
|
140
|
+
## System Requirements
|
|
456
141
|
|
|
457
|
-
|
|
458
|
-
|
|
142
|
+
- **Node.js >= 20** — the only runtime. No .NET, JDK, or Python.
|
|
143
|
+
- **Bun >= 1.0** also works (`bun run build`, `bun test`).
|
|
144
|
+
- **Claude Code** with local plugin support.
|
|
145
|
+
- **Zero native deps** — WASM-backed tree-sitter, no C compiler needed.
|
|
459
146
|
|
|
460
|
-
|
|
461
|
-
|
|
147
|
+
Windows: requires a POSIX shell (Git Bash or WSL).
|
|
148
|
+
See [docs/contributing.md](./docs/contributing.md) for Windows setup details.
|
|
462
149
|
|
|
463
|
-
|
|
464
|
-
npm run test:metrics # CRAP, TDR, score
|
|
465
|
-
npm run test:sarif # SARIF store + dedup + validator
|
|
466
|
-
npm run test:ast # Cyclomatic walker
|
|
467
|
-
npm run test:harness # Test-file resolver
|
|
468
|
-
npm run test:adapters # Semgrep, ESLint, Bandit, Stryker
|
|
469
|
-
npm run test:integration # End-to-end MCP stdio round trips
|
|
150
|
+
---
|
|
470
151
|
|
|
471
|
-
|
|
472
|
-
npm run clean
|
|
473
|
-
```
|
|
152
|
+
## Documentation
|
|
474
153
|
|
|
475
|
-
|
|
154
|
+
| Section | Link |
|
|
155
|
+
| :------ | :--- |
|
|
156
|
+
| Architecture & boot sequence | [docs/architecture-overview.md](./docs/architecture-overview.md) |
|
|
157
|
+
| Quality gate math (CRAP, TDR, ratings) | [docs/quality-gate.md](./docs/quality-gate.md) |
|
|
158
|
+
| Project score aggregation | [docs/scoring.md](./docs/scoring.md) |
|
|
159
|
+
| Hooks reference | [docs/hooks.md](./docs/hooks.md) |
|
|
160
|
+
| MCP tools & resources | [docs/mcp-tools.md](./docs/mcp-tools.md) |
|
|
161
|
+
| Scanner adapters | [docs/scanner-adapters.md](./docs/scanner-adapters.md) |
|
|
162
|
+
| SDK reference | [docs/sdk.md](./docs/sdk.md) |
|
|
163
|
+
| Contributing & dev loop | [docs/contributing.md](./docs/contributing.md) |
|
|
164
|
+
| Agent contract | [plugin/CLAUDE.md](./plugin/CLAUDE.md) |
|
|
165
|
+
| Changelog | [CHANGELOG.md](./CHANGELOG.md) |
|
|
476
166
|
|
|
477
|
-
|
|
478
|
-
npm run doctor # node ./bin/claude-crap.mjs doctor
|
|
479
|
-
npm run status # node ./bin/claude-crap.mjs status
|
|
480
|
-
npm run bug-report # writes claude-crap-bug-report-<ts>.md to the cwd
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
### Releases
|
|
167
|
+
---
|
|
484
168
|
|
|
485
|
-
|
|
486
|
-
so every release runs `clean + build + test + audit` before tagging
|
|
487
|
-
and pushing to npm:
|
|
169
|
+
## Development
|
|
488
170
|
|
|
489
171
|
```bash
|
|
490
|
-
npm
|
|
491
|
-
npm
|
|
492
|
-
npm run
|
|
493
|
-
npm run
|
|
172
|
+
npm install # postinstall builds dist/ automatically
|
|
173
|
+
npm test # 225 tests across 37 suites
|
|
174
|
+
npm run build:fast # esbuild dev build (10-20x faster than tsc)
|
|
175
|
+
npm run doctor # full diagnostic
|
|
494
176
|
```
|
|
495
177
|
|
|
496
|
-
|
|
497
|
-
npm
|
|
498
|
-
|
|
499
|
-
`np` before any tag lands.
|
|
500
|
-
|
|
501
|
-
### Running the MCP server standalone
|
|
502
|
-
|
|
503
|
-
For debugging, the MCP server can be run outside Claude Code:
|
|
504
|
-
|
|
505
|
-
```bash
|
|
506
|
-
node ./dist/index.js --transport stdio
|
|
507
|
-
```
|
|
178
|
+
Release via [`np`](https://github.com/sindresorhus/np):
|
|
179
|
+
`npm run release:patch` / `release:minor` / `release:major`.
|
|
180
|
+
`prepublishOnly` runs clean + build + test + audit automatically.
|
|
508
181
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
the server starts — change `CLAUDE_PLUGIN_OPTION_DASHBOARD_PORT` to
|
|
512
|
-
move it to a different port.
|
|
182
|
+
Full dev loop, test commands, and standalone MCP server instructions
|
|
183
|
+
in [docs/contributing.md](./docs/contributing.md).
|
|
513
184
|
|
|
514
185
|
---
|
|
515
186
|
|
|
516
187
|
## Bug Reports
|
|
517
188
|
|
|
518
|
-
The `claude-crap` CLI ships a `bug-report` subcommand that collects
|
|
519
|
-
every piece of information a maintainer typically asks for when
|
|
520
|
-
triaging an issue and writes it to a single Markdown bundle:
|
|
521
|
-
|
|
522
189
|
```bash
|
|
523
|
-
npx claude-crap bug-report
|
|
524
|
-
|
|
190
|
+
npx claude-crap bug-report # writes claude-crap-bug-report-<ts>.md
|
|
191
|
+
npx claude-crap bug-report --stdout
|
|
525
192
|
```
|
|
526
193
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
`claude-crap doctor` output, and a summary of the consolidated
|
|
532
|
-
SARIF report if one exists.
|
|
533
|
-
|
|
534
|
-
Pass `--stdout` to print the bundle instead of writing a file, or
|
|
535
|
-
`-o <path>` to choose the filename. Review the output for anything
|
|
536
|
-
sensitive that slipped past the redactor, then open a new issue at
|
|
537
|
-
[github.com/ahernandez-developer/claude-crap/issues](https://github.com/ahernandez-developer/claude-crap/issues)
|
|
538
|
-
and paste the bundle as the issue body.
|
|
194
|
+
Collects plugin version, Node/npm/platform info, doctor output,
|
|
195
|
+
SARIF summary, and resolved env vars (secrets auto-redacted).
|
|
196
|
+
Review the output, then open an issue at
|
|
197
|
+
[github.com/ahernandez-developer/claude-crap/issues](https://github.com/ahernandez-developer/claude-crap/issues).
|
|
539
198
|
|
|
540
199
|
---
|
|
541
200
|
|
|
542
201
|
## Contributing
|
|
543
202
|
|
|
544
|
-
1.
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
3. **Run `npm test`.** The full suite must stay at 225 / 225 green.
|
|
552
|
-
If you add new tests, update the count in the
|
|
553
|
-
[Development](#development) section and in `CHANGELOG.md`.
|
|
554
|
-
4. **Update the `CHANGELOG.md`** with an entry describing your
|
|
555
|
-
change. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
556
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
557
|
-
5. **Open a pull request** describing the change in the rigid
|
|
558
|
-
deduction format from `CLAUDE.md` (`Coupled dependency / Risk /
|
|
559
|
-
Required test / Blocking metric / Proposed change`). CI will run
|
|
560
|
-
typecheck, the full test suite, and `npm audit` on every push.
|
|
561
|
-
|
|
562
|
-
Full dev loop, test layout, coding conventions, and the release
|
|
563
|
-
process live in [docs/contributing.md](./docs/contributing.md).
|
|
203
|
+
1. Fork and branch off `main`.
|
|
204
|
+
2. **Write the test first** — the Golden Rule forbids code before a safety net.
|
|
205
|
+
3. Run `npm test` — full suite must stay green.
|
|
206
|
+
4. Update `CHANGELOG.md`.
|
|
207
|
+
5. Open a PR in the [rigid deduction format](./plugin/CLAUDE.md).
|
|
208
|
+
|
|
209
|
+
Full guide: [docs/contributing.md](./docs/contributing.md).
|
|
564
210
|
|
|
565
211
|
---
|
|
566
212
|
|
|
567
213
|
## License
|
|
568
214
|
|
|
569
|
-
MIT. See [LICENSE](./LICENSE)
|
|
570
|
-
|
|
571
|
-
Copyright (c) 2026 Alan Hernandez.
|
|
215
|
+
MIT. See [LICENSE](./LICENSE). Copyright (c) 2026 Alan Hernandez.
|