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/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
- sits underneath your existing Claude Code session as a plugin and
16
- wraps every `Write`, `Edit`, and `Bash` call with deterministic
17
- validation: a synchronous **PreToolUse gatekeeper**, a retrospective
18
- **PostToolUse verifier**, and a final **Stop quality gate** that
19
- refuses to close a task until the project's maintainability,
20
- reliability, and security ratings are inside the configured policy.
21
-
22
- The agent's probabilistic reasoning is never trusted by itself. Every
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, unforgiving, and
31
- outside the model's reach.
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 mildly offensive
34
- > acronym to protect you from deeply offensive code. The metric was
35
- > originally developed by Alberto Savoia and Bob Evans at Google in 2007.
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) [Configuration](#configuration) [Documentation](#documentation) • [How It Works](#how-it-works) [MCP Tools](#mcp-tools) [System Requirements](#system-requirements) [Development](#development) [Bug Reports](#bug-reports) • [Contributing](#contributing)
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
- `npx` downloads the package, the `postinstall` step compiles `dist/`
54
- from source, and then `claude-crap install` creates
55
- `.claude-crap/reports/` in the current project, marks every hook
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 Claude Code install from this directory:
48
+ 1. Native install:
67
49
  /plugin install /.../claude-crap
68
50
 
69
- 2. Marketplace install (Claude Code pulls the published npm tarball):
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 Claude Code reports the plugin as active, open any new session
75
- in your workspace. The **SessionStart** hook will print a one-line
76
- briefing showing the plugin version, the active thresholds, and the
77
- local dashboard URL. From that point on the PreToolUse gatekeeper
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`.** You don't need to create a config file or
110
- > set any environment variables. A fresh install hard-fails the Stop
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
- | Mode | Stop hook exit | Verdict sink | Agent experience |
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
- ### How to override the default
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
- Teams adopting the plugin on an existing codebase can dial the
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 this to git for team-wide policy
79
+ // .claude-crap.json — commit to git for team-wide policy
134
80
  {
135
- "$schema": "https://raw.githubusercontent.com/ahernandez-developer/claude-crap/main/schemas/crap-config.json",
136
- "strictness": "warn", // "strict" | "warn" | "advisory"
81
+ "strictness": "warn"
137
82
  }
138
83
  ```
139
84
 
140
- Or override for a single session from the shell:
85
+ Or per session: `CLAUDE_CRAP_STRICTNESS=advisory claude`
141
86
 
142
- ```bash
143
- CLAUDE_CRAP_STRICTNESS=advisory claude
144
- ```
87
+ **Precedence:** env var > `.claude-crap.json` > hardcoded `strict`.
145
88
 
146
- **Precedence** (most specific wins):
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
- ## Documentation
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
- ## How It Works
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
- **Core components:**
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
- The MCP server exposes nine deterministic tools and two resources.
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
- Full details including every schema, every error shape, and the
403
- per-scanner effort tables live in
404
- [docs/mcp-tools.md](./docs/mcp-tools.md) and
405
- [docs/scanner-adapters.md](./docs/scanner-adapters.md).
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
- ## System Requirements
130
+ | Resource | Description |
131
+ | :------- | :---------- |
132
+ | `sonar://metrics/current` | Live CRAP / TDR / rating snapshot. |
133
+ | `sonar://reports/latest.sarif` | Consolidated SARIF document. |
410
134
 
411
- - **Node.js 20.0.0** the only runtime requirement. No .NET, no
412
- JDK, no Python toolchain.
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
- ## Development
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
- # Run in dev mode (tsx, no build step)
458
- npm run dev
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
- # Full native test suite 225 tests across 37 suites
461
- npm test
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
- # Narrow the feedback loop to one domain while iterating
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
- # Clean build artifacts
472
- npm run clean
473
- ```
152
+ ## Documentation
474
153
 
475
- CLI shortcuts are exposed as npm scripts too:
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
- ```bash
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
- Publishing goes through [`np`](https://github.com/sindresorhus/np)
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 run release # interactive prompts for patch/minor/major
491
- npm run release:patch # non-interactive patch bump
492
- npm run release:minor # non-interactive minor bump
493
- npm run release:major # non-interactive major bump
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
- `prepublishOnly` runs `npm run clean && npm run build && npm test &&
497
- npm audit --omit=dev --audit-level=high` automatically. A broken
498
- test OR a new high-severity advisory in a runtime dependency blocks
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
- Paste an MCP `initialize` request on stdin to exercise the JSON-RPC
510
- framing. The dashboard auto-boots at `http://127.0.0.1:5117` when
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
- # writes ./claude-crap-bug-report-<timestamp>.md
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
- The bundle includes the plugin version, Node / npm / platform
528
- versions, plugin file presence, the build state of `dist/`, the
529
- resolved `CLAUDE_PLUGIN_OPTION_*` environment variables (with every
530
- secret-looking variable automatically redacted by name), the
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. **Fork** [ahernandez-developer/claude-crap](https://github.com/ahernandez-developer/claude-crap)
545
- and create a feature branch off `main`.
546
- 2. **Write the test first.** The CLAUDE.md Golden Rule forbids
547
- writing functional code before a test safety net exists, and the
548
- PreToolUse hook will block you if you try. Add a characterization
549
- test that pins the current behavior, then the attack test that
550
- demonstrates the bug, then the patch.
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) for the full text.
570
-
571
- Copyright (c) 2026 Alan Hernandez.
215
+ MIT. See [LICENSE](./LICENSE). Copyright (c) 2026 Alan Hernandez.