claude-crap 0.1.2

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.
Files changed (202) hide show
  1. package/CHANGELOG.md +308 -0
  2. package/LICENSE +21 -0
  3. package/README.md +550 -0
  4. package/bin/claude-crap.mjs +141 -0
  5. package/dist/adapters/bandit.d.ts +48 -0
  6. package/dist/adapters/bandit.d.ts.map +1 -0
  7. package/dist/adapters/bandit.js +145 -0
  8. package/dist/adapters/bandit.js.map +1 -0
  9. package/dist/adapters/common.d.ts +73 -0
  10. package/dist/adapters/common.d.ts.map +1 -0
  11. package/dist/adapters/common.js +78 -0
  12. package/dist/adapters/common.js.map +1 -0
  13. package/dist/adapters/eslint.d.ts +52 -0
  14. package/dist/adapters/eslint.d.ts.map +1 -0
  15. package/dist/adapters/eslint.js +142 -0
  16. package/dist/adapters/eslint.js.map +1 -0
  17. package/dist/adapters/index.d.ts +47 -0
  18. package/dist/adapters/index.d.ts.map +1 -0
  19. package/dist/adapters/index.js +64 -0
  20. package/dist/adapters/index.js.map +1 -0
  21. package/dist/adapters/semgrep.d.ts +30 -0
  22. package/dist/adapters/semgrep.d.ts.map +1 -0
  23. package/dist/adapters/semgrep.js +130 -0
  24. package/dist/adapters/semgrep.js.map +1 -0
  25. package/dist/adapters/stryker.d.ts +55 -0
  26. package/dist/adapters/stryker.d.ts.map +1 -0
  27. package/dist/adapters/stryker.js +165 -0
  28. package/dist/adapters/stryker.js.map +1 -0
  29. package/dist/ast/cyclomatic.d.ts +48 -0
  30. package/dist/ast/cyclomatic.d.ts.map +1 -0
  31. package/dist/ast/cyclomatic.js +106 -0
  32. package/dist/ast/cyclomatic.js.map +1 -0
  33. package/dist/ast/index.d.ts +26 -0
  34. package/dist/ast/index.d.ts.map +1 -0
  35. package/dist/ast/index.js +23 -0
  36. package/dist/ast/index.js.map +1 -0
  37. package/dist/ast/language-config.d.ts +70 -0
  38. package/dist/ast/language-config.d.ts.map +1 -0
  39. package/dist/ast/language-config.js +192 -0
  40. package/dist/ast/language-config.js.map +1 -0
  41. package/dist/ast/tree-sitter-engine.d.ts +133 -0
  42. package/dist/ast/tree-sitter-engine.d.ts.map +1 -0
  43. package/dist/ast/tree-sitter-engine.js +270 -0
  44. package/dist/ast/tree-sitter-engine.js.map +1 -0
  45. package/dist/config.d.ts +57 -0
  46. package/dist/config.d.ts.map +1 -0
  47. package/dist/config.js +78 -0
  48. package/dist/config.js.map +1 -0
  49. package/dist/crap-config.d.ts +97 -0
  50. package/dist/crap-config.d.ts.map +1 -0
  51. package/dist/crap-config.js +144 -0
  52. package/dist/crap-config.js.map +1 -0
  53. package/dist/dashboard/server.d.ts +65 -0
  54. package/dist/dashboard/server.d.ts.map +1 -0
  55. package/dist/dashboard/server.js +147 -0
  56. package/dist/dashboard/server.js.map +1 -0
  57. package/dist/index.d.ts +32 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +574 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/metrics/crap.d.ts +71 -0
  62. package/dist/metrics/crap.d.ts.map +1 -0
  63. package/dist/metrics/crap.js +67 -0
  64. package/dist/metrics/crap.js.map +1 -0
  65. package/dist/metrics/index.d.ts +31 -0
  66. package/dist/metrics/index.d.ts.map +1 -0
  67. package/dist/metrics/index.js +27 -0
  68. package/dist/metrics/index.js.map +1 -0
  69. package/dist/metrics/score.d.ts +143 -0
  70. package/dist/metrics/score.d.ts.map +1 -0
  71. package/dist/metrics/score.js +224 -0
  72. package/dist/metrics/score.js.map +1 -0
  73. package/dist/metrics/tdr.d.ts +106 -0
  74. package/dist/metrics/tdr.d.ts.map +1 -0
  75. package/dist/metrics/tdr.js +117 -0
  76. package/dist/metrics/tdr.js.map +1 -0
  77. package/dist/metrics/workspace-walker.d.ts +43 -0
  78. package/dist/metrics/workspace-walker.d.ts.map +1 -0
  79. package/dist/metrics/workspace-walker.js +137 -0
  80. package/dist/metrics/workspace-walker.js.map +1 -0
  81. package/dist/sarif/index.d.ts +21 -0
  82. package/dist/sarif/index.d.ts.map +1 -0
  83. package/dist/sarif/index.js +19 -0
  84. package/dist/sarif/index.js.map +1 -0
  85. package/dist/sarif/sarif-builder.d.ts +128 -0
  86. package/dist/sarif/sarif-builder.d.ts.map +1 -0
  87. package/dist/sarif/sarif-builder.js +79 -0
  88. package/dist/sarif/sarif-builder.js.map +1 -0
  89. package/dist/sarif/sarif-store.d.ts +205 -0
  90. package/dist/sarif/sarif-store.d.ts.map +1 -0
  91. package/dist/sarif/sarif-store.js +246 -0
  92. package/dist/sarif/sarif-store.js.map +1 -0
  93. package/dist/sarif/sarif-validator.d.ts +45 -0
  94. package/dist/sarif/sarif-validator.d.ts.map +1 -0
  95. package/dist/sarif/sarif-validator.js +138 -0
  96. package/dist/sarif/sarif-validator.js.map +1 -0
  97. package/dist/schemas/tool-schemas.d.ts +216 -0
  98. package/dist/schemas/tool-schemas.d.ts.map +1 -0
  99. package/dist/schemas/tool-schemas.js +208 -0
  100. package/dist/schemas/tool-schemas.js.map +1 -0
  101. package/dist/sdk.d.ts +45 -0
  102. package/dist/sdk.d.ts.map +1 -0
  103. package/dist/sdk.js +44 -0
  104. package/dist/sdk.js.map +1 -0
  105. package/dist/tools/index.d.ts +24 -0
  106. package/dist/tools/index.d.ts.map +1 -0
  107. package/dist/tools/index.js +23 -0
  108. package/dist/tools/index.js.map +1 -0
  109. package/dist/tools/test-harness.d.ts +75 -0
  110. package/dist/tools/test-harness.d.ts.map +1 -0
  111. package/dist/tools/test-harness.js +137 -0
  112. package/dist/tools/test-harness.js.map +1 -0
  113. package/dist/workspace-guard.d.ts +53 -0
  114. package/dist/workspace-guard.d.ts.map +1 -0
  115. package/dist/workspace-guard.js +61 -0
  116. package/dist/workspace-guard.js.map +1 -0
  117. package/package.json +133 -0
  118. package/plugin/.claude-plugin/plugin.json +29 -0
  119. package/plugin/.mcp.json +18 -0
  120. package/plugin/CLAUDE.md +143 -0
  121. package/plugin/bundle/dashboard/public/index.html +368 -0
  122. package/plugin/bundle/dashboard/public/vendor/vue.global.prod.js +9 -0
  123. package/plugin/bundle/mcp-server.mjs +8718 -0
  124. package/plugin/bundle/mcp-server.mjs.map +7 -0
  125. package/plugin/bundle/tdr-engine.mjs +50 -0
  126. package/plugin/bundle/tdr-engine.mjs.map +7 -0
  127. package/plugin/hooks/hooks.json +62 -0
  128. package/plugin/hooks/lib/crap-config.mjs +152 -0
  129. package/plugin/hooks/lib/gatekeeper-rules.mjs +257 -0
  130. package/plugin/hooks/lib/hook-io.mjs +151 -0
  131. package/plugin/hooks/lib/quality-gate.mjs +329 -0
  132. package/plugin/hooks/lib/test-harness.mjs +152 -0
  133. package/plugin/hooks/post-tool-use.mjs +245 -0
  134. package/plugin/hooks/pre-tool-use.mjs +290 -0
  135. package/plugin/hooks/session-start.mjs +109 -0
  136. package/plugin/hooks/stop-quality-gate.mjs +226 -0
  137. package/plugin/package.json +18 -0
  138. package/plugin/skills/adopt/SKILL.md +74 -0
  139. package/plugin/skills/analyze/SKILL.md +77 -0
  140. package/plugin/skills/check-test/SKILL.md +50 -0
  141. package/plugin/skills/score/SKILL.md +31 -0
  142. package/scripts/bug-report.mjs +328 -0
  143. package/scripts/build-fast.mjs +130 -0
  144. package/scripts/bundle-plugin.mjs +74 -0
  145. package/scripts/doctor.mjs +320 -0
  146. package/scripts/install.mjs +192 -0
  147. package/scripts/lib/cli-ui.mjs +122 -0
  148. package/scripts/postinstall.mjs +127 -0
  149. package/scripts/run-tests.mjs +95 -0
  150. package/scripts/status.mjs +110 -0
  151. package/scripts/uninstall.mjs +72 -0
  152. package/src/adapters/bandit.ts +191 -0
  153. package/src/adapters/common.ts +133 -0
  154. package/src/adapters/eslint.ts +187 -0
  155. package/src/adapters/index.ts +78 -0
  156. package/src/adapters/semgrep.ts +150 -0
  157. package/src/adapters/stryker.ts +218 -0
  158. package/src/ast/cyclomatic.ts +131 -0
  159. package/src/ast/index.ts +33 -0
  160. package/src/ast/language-config.ts +231 -0
  161. package/src/ast/tree-sitter-engine.ts +385 -0
  162. package/src/config.ts +109 -0
  163. package/src/crap-config.ts +196 -0
  164. package/src/dashboard/public/index.html +368 -0
  165. package/src/dashboard/public/vendor/vue.global.prod.js +9 -0
  166. package/src/dashboard/server.ts +205 -0
  167. package/src/index.ts +696 -0
  168. package/src/metrics/crap.ts +101 -0
  169. package/src/metrics/index.ts +51 -0
  170. package/src/metrics/score.ts +329 -0
  171. package/src/metrics/tdr.ts +155 -0
  172. package/src/metrics/workspace-walker.ts +146 -0
  173. package/src/sarif/index.ts +31 -0
  174. package/src/sarif/sarif-builder.ts +139 -0
  175. package/src/sarif/sarif-store.ts +347 -0
  176. package/src/sarif/sarif-validator.ts +145 -0
  177. package/src/schemas/tool-schemas.ts +225 -0
  178. package/src/sdk.ts +110 -0
  179. package/src/tests/adapters/bandit.test.ts +111 -0
  180. package/src/tests/adapters/dispatch.test.ts +100 -0
  181. package/src/tests/adapters/eslint.test.ts +138 -0
  182. package/src/tests/adapters/semgrep.test.ts +125 -0
  183. package/src/tests/adapters/stryker.test.ts +103 -0
  184. package/src/tests/crap-config.test.ts +228 -0
  185. package/src/tests/crap.test.ts +59 -0
  186. package/src/tests/cyclomatic.test.ts +87 -0
  187. package/src/tests/dashboard-http.test.ts +108 -0
  188. package/src/tests/dashboard-integrity.test.ts +128 -0
  189. package/src/tests/integration/mcp-server.integration.test.ts +352 -0
  190. package/src/tests/pre-tool-use-hook.test.ts +178 -0
  191. package/src/tests/sarif-store.test.ts +241 -0
  192. package/src/tests/sarif-validator.test.ts +164 -0
  193. package/src/tests/score.test.ts +260 -0
  194. package/src/tests/skills-frontmatter.test.ts +172 -0
  195. package/src/tests/stop-quality-gate-strictness.test.ts +243 -0
  196. package/src/tests/tdr.test.ts +86 -0
  197. package/src/tests/test-harness.test.ts +153 -0
  198. package/src/tests/workspace-guard.test.ts +111 -0
  199. package/src/tools/index.ts +24 -0
  200. package/src/tools/test-harness.ts +158 -0
  201. package/src/workspace-guard.ts +64 -0
  202. package/tsconfig.json +27 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,308 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.2] - 2026-04-12
9
+
10
+ Plugin distribution refactored from npm-source to git-source. Claude
11
+ Desktop's Directory view now renders Skills / Hooks / Connectors counts
12
+ for `claude-crap`, matching the pattern used by `claude-mem` and every
13
+ plugin in the official Anthropic marketplace.
14
+
15
+ ### Added
16
+
17
+ - **`plugin/` subdirectory** — self-contained plugin artifact committed
18
+ to git. Contains `.claude-plugin/plugin.json`, `.mcp.json`, `CLAUDE.md`,
19
+ `hooks/`, `skills/`, `bundle/`, and a minimal `package.json` declaring
20
+ only the un-bundleable native/WASM runtime deps.
21
+ - **`scripts/bundle-plugin.mjs`** — esbuild bundler that produces
22
+ `plugin/bundle/mcp-server.mjs` (the MCP server entry) and
23
+ `plugin/bundle/tdr-engine.mjs` (standalone TDR classifier for hooks).
24
+ Also copies dashboard static assets into `plugin/bundle/dashboard/public/`.
25
+ - **`npm run build:plugin`** script in `package.json`.
26
+ - **Dashboard HTTP characterization test** (`src/tests/dashboard-http.test.ts`)
27
+ that boots the bundled MCP server and verifies the dashboard responds
28
+ with 200 OK + HTML and the `/api/score` endpoint returns valid JSON.
29
+ - **CI bundle drift check** — `.github/workflows/ci.yml` now rebuilds
30
+ `plugin/bundle/` and fails the PR if the committed bundles are stale.
31
+
32
+ ### Changed
33
+
34
+ - **Marketplace source** in `.claude-plugin/marketplace.json` changed
35
+ from `{ source: "npm", package: "claude-crap" }` to
36
+ `"./plugin"`. Claude Desktop can now filesystem-scan the plugin
37
+ directory from the cloned marketplace repo.
38
+ - **MCP server entry** in `plugin/.mcp.json` changed from
39
+ `dist/index.js` to `bundle/mcp-server.mjs`.
40
+ - **TDR import** in `plugin/hooks/lib/quality-gate.mjs` changed from
41
+ `dist/metrics/tdr.js` to `../../bundle/tdr-engine.mjs`.
42
+ - **Integration tests** (`mcp-server.integration.test.ts`,
43
+ `stop-quality-gate-strictness.test.ts`, `dashboard-http.test.ts`)
44
+ now default to the bundled entry points and accept `SONAR_MCP_ENTRY` /
45
+ `SONAR_TDR_ENTRY` env var overrides.
46
+ - **Hooks, skills, CLAUDE.md, .mcp.json** moved from the repo root
47
+ into `plugin/` via `git mv` (history preserved).
48
+ - **`resolvePublicRoot()`** in `src/dashboard/server.ts` gained a new
49
+ first-place candidate for the bundle-relative layout.
50
+ - **Diagnostic scripts** (`doctor.mjs`, `status.mjs`, `bug-report.mjs`,
51
+ `install.mjs`) updated to check both `dist/` and `plugin/bundle/`.
52
+ - **`prepublishOnly`** now runs `npm run build:plugin` alongside `tsc`.
53
+ - **npm library surface preserved** — `main`, `types`, `exports` still
54
+ point to `dist/`. Both distribution channels coexist (dual-track).
55
+
56
+ ### Fixed
57
+
58
+ - Directory view in Claude Desktop now shows Skills / Hooks / Connectors
59
+ counts (previously blank because the npm-source type prevented
60
+ pre-install filesystem scanning).
61
+
62
+ ## [0.1.1] - 2026-04-11
63
+
64
+ First feature release on top of the initial public drop. All the
65
+ plumbing that `v0.1.0` put in place (hooks, MCP server, dashboard,
66
+ SARIF store, scanner adapters, CLI) is unchanged — this release adds
67
+ the user-facing surface that makes those engines reachable from
68
+ Claude Code's slash-command palette.
69
+
70
+ ### Added
71
+
72
+ - **Four user-invocable skills** under `plugin/skills/` at the plugin root.
73
+ Each skill is a `SKILL.md` file with YAML frontmatter declaring a
74
+ `name` and a "pushy" `description` (per the `skill-creator` skill's
75
+ guidance on combating undertriggering), and Markdown instructions
76
+ in the body that tell Claude how to invoke the underlying MCP tool
77
+ and render the result. The four skills:
78
+ - `/claude-crap:score` — runs the `score_project` MCP tool and
79
+ displays the Markdown summary (Maintainability / Reliability /
80
+ Security / Overall A..E grades, plus the live dashboard URL and
81
+ the consolidated SARIF report path).
82
+ - `/claude-crap:check-test` — takes a file-path argument, runs
83
+ `require_test_harness` against it, and reports whether a matching
84
+ characterization test exists; on `hasTest: false`, lists the top
85
+ three resolver candidate paths so the user knows exactly where
86
+ the new test should live per CLAUDE.md's Golden Rule.
87
+ - `/claude-crap:analyze` — takes a file-path argument, auto-detects
88
+ the language from the extension (`typescript`, `javascript`,
89
+ `python`, `java`, `csharp`), runs `analyze_file_ast` against it,
90
+ and reports per-function cyclomatic complexity ranked descending
91
+ with refactoring candidates called out above the `cyclomaticMax`
92
+ ceiling.
93
+ - `/claude-crap:adopt` — interactive onboarding walkthrough that
94
+ asks three questions about the team's test coverage, existing
95
+ findings, and enforcement appetite, and recommends one of
96
+ `strict` / `warn` / `advisory` for the workspace's
97
+ `.claude-crap.json`. Produces a copy-pasteable JSON snippet and
98
+ a gradual-adoption roadmap.
99
+ - **Frontmatter contract test** at `src/tests/skills-frontmatter.test.ts`
100
+ validates that every `plugin/skills/<name>/SKILL.md` has YAML frontmatter
101
+ with a `name` matching the directory, a `description` longer than
102
+ 100 characters, and the `use this skill when/whenever ...` trigger
103
+ phrasing that the `skill-creator` guidance recommends. The test
104
+ fires on every `npm test` run so a future drive-by edit that
105
+ removes a field cannot slip through CI.
106
+
107
+ ### Changed
108
+
109
+ - **`package.json#files` now ships `plugin/skills/`** in the npm tarball. The
110
+ `v0.1.0` tarball did NOT include `plugin/skills/` — this is the reason a
111
+ new version is mandatory rather than an in-place fix: Claude Code's
112
+ marketplace installs via `npm install claude-crap@<version>`,
113
+ not from the git repo, so the SKILL.md files only reach users after
114
+ a new tarball is published. Consumers who already ran
115
+ `/plugin install claude-crap@herz` against `0.1.0` need to run
116
+ `/plugin marketplace update herz` to pick up `0.1.1`.
117
+ - **`.claude-plugin/marketplace.json` plugin version bumped** on both
118
+ the top-level `version` field and the `source.version` pin, so the
119
+ `herz` marketplace now delivers `0.1.1` instead of `0.1.0`.
120
+
121
+ ### Fixed
122
+
123
+ - **Stale README install instructions** that were written in the
124
+ future tense before the `v0.1.0` tag landed ("Once the plugin is
125
+ tagged on GitHub the Claude Code marketplace path becomes a fully
126
+ native second install route") are now replaced with the live
127
+ commands: `npx claude-crap install` for the direct npm
128
+ route, and `/plugin marketplace add https://github.com/ahernandez-developer/claude-crap`
129
+ followed by `/plugin install claude-crap@herz` for the Claude Code
130
+ marketplace route.
131
+
132
+ ### Merge and publish sequence for maintainers
133
+
134
+ Because this release requires a new npm tarball to reach users via
135
+ the marketplace, the merge and publish order matters:
136
+
137
+ 1. Review and merge this PR into `main` via "Squash and merge".
138
+ 2. Pull the merged `main` locally: `git checkout main && git pull`.
139
+ 3. Run `npm publish --otp=<6-digit-OTP>` from the repo root. The
140
+ `prepublishOnly` script gates the publish on
141
+ `clean + build + test + audit` — a broken test or a new HIGH
142
+ audit finding will block the tag before any version lands.
143
+ 4. Verify on the registry: `npm view claude-crap version`
144
+ should print `0.1.1`.
145
+ 5. Tag the release in git: `git tag -a v0.1.1 -m "Release v0.1.1"`
146
+ followed by `git push origin v0.1.1`.
147
+ 6. Optionally publish a GitHub release via
148
+ `gh release create v0.1.1 --notes-file CHANGELOG.md`.
149
+
150
+ Between step 1 (merge) and step 3 (publish), the `herz` marketplace
151
+ briefly references `claude-crap@0.1.1` before that version
152
+ exists on the registry. New marketplace installs during that window
153
+ will fail with a clean npm 404 — no persistent state damage, but
154
+ running `npm publish` immediately after merging minimizes the gap.
155
+
156
+ ## [0.1.0] - 2026-04-11
157
+
158
+ Initial public release of `claude-crap` — a deterministic Quality Assurance
159
+ plugin for Claude Code. Ships the full plugin shell, the MCP server, the
160
+ local Vue dashboard, the per-scanner SARIF adapters, and the publication
161
+ tooling in a single npm package.
162
+
163
+ ### Added
164
+
165
+ - **Plugin shell.** Plugin manifest under `.claude-plugin/plugin.json`,
166
+ `.mcp.json` wiring, `CLAUDE.md` Golden-Rule contract injected into
167
+ every Claude Code session where the plugin is active, MIT `LICENSE`
168
+ file, and `CHANGELOG.md`. Every file is validated against the
169
+ official Claude Code [plugins-reference](https://code.claude.com/docs/en/plugins-reference)
170
+ schema — only documented fields appear in the manifest, and every
171
+ inline substitution uses a supported token (`${CLAUDE_PLUGIN_ROOT}`).
172
+ - **Deterministic hooks.**
173
+ - PreToolUse gatekeeper with blocked-path, hardcoded-secret and
174
+ destructive-bash rules (all pure regex, zero I/O, sub-200 ms latency).
175
+ - PostToolUse verifier that flags missing test harnesses, inline
176
+ suppression markers (`eslint-disable`, `@ts-ignore`, `# nosec`,
177
+ `# type: ignore`), and fresh TODO / FIXME / HACK markers.
178
+ - Stop / SubagentStop quality gate that reads the consolidated SARIF
179
+ report, computes a project-wide Technical Debt Ratio, and — under
180
+ `strict` mode — blocks task-close when the TDR rating or SARIF
181
+ error count exceeds policy.
182
+ - SessionStart briefing that prints the plugin version, the active
183
+ thresholds, and the dashboard URL.
184
+ - **Workspace strictness config.** A single `.claude-crap.json`
185
+ file at the workspace root controls how the Stop quality gate and
186
+ the `score_project` MCP tool react to a failing verdict. Three
187
+ modes are supported: `strict` (default, hard-blocks the task
188
+ close — same as previous behavior), `warn` (exits 0 but writes
189
+ the full verdict to the hook transcript so the agent can
190
+ voluntarily remediate), and `advisory` (exits 0 with a single-line
191
+ note for the lightest possible pressure). `CLAUDE_CRAP_STRICTNESS`
192
+ env var overrides the file for a single session. The PreToolUse
193
+ security rules are **not** affected by this setting — security is
194
+ always strict. Teams can adopt claude-crap in stages without
195
+ having to bypass the plugin.
196
+
197
+ **Compliance note.** The Claude Code [plugins reference](https://code.claude.com/docs/en/plugins-reference#user-configuration)
198
+ documents `userConfig` in `plugin.json` as the canonical channel
199
+ for collecting plugin-level user configuration, with values
200
+ stored in `.claude/settings.json` under `pluginConfigs[<plugin-id>].options`.
201
+ `claude-crap` deliberately reads `.claude-crap.json` from the
202
+ workspace root instead because (1) the canonical pattern prompts
203
+ every user at install time and an enum policy with a sensible
204
+ default does not warrant that friction, (2) a dedicated workspace
205
+ file is team-committable and code-reviewable alongside
206
+ `.eslintrc.json` / `.prettierrc.json` / `biome.json`, and (3) a
207
+ workspace file can carry a JSON schema for IDE autocompletion.
208
+ The deviation is called out in the `Configuration` section of
209
+ `README.md`. Every other part of the plugin spec (manifest schema,
210
+ hook events, MCP server location, `${CLAUDE_PLUGIN_ROOT}`
211
+ substitution, directory layout) is fully compliant.
212
+ - **MCP server (stdio transport).**
213
+ - `compute_crap` — Change-Risk-Anti-Patterns index for a single function.
214
+ - `compute_tdr` — Technical Debt Ratio and A..E maintainability rating
215
+ for a project, module, or file scope.
216
+ - `analyze_file_ast` — tree-sitter AST metrics (physical / logical LOC,
217
+ per-function cyclomatic complexity) for TypeScript, JavaScript,
218
+ Python, Java, and C#.
219
+ - `ingest_sarif` — merge a raw SARIF 2.1.0 document into the store
220
+ with deduplication by `(ruleId, uri, startLine, startColumn)`.
221
+ - `ingest_scanner_output` — route a scanner's native output through
222
+ the matching adapter, enrich every finding with an `effortMinutes`
223
+ estimate, and persist the normalized SARIF 2.1.0 document.
224
+ - `require_test_harness` — check that a production source file has a
225
+ matching test file in any of the supported conventions (sibling
226
+ `.test.`, `__tests__/`, mirror tree under `tests/`, nearest-ancestor
227
+ flat `tests/`, Python `test_` prefix).
228
+ - `score_project` — aggregate the entire workspace into
229
+ Maintainability, Reliability, Security and Overall letter grades
230
+ with Markdown and JSON output.
231
+ - **MCP resources.**
232
+ - `sonar://metrics/current` — live CRAP / TDR / rating snapshot
233
+ derived from the in-memory SARIF store.
234
+ - `sonar://reports/latest.sarif` — the last consolidated SARIF
235
+ document.
236
+ - **Local dashboard.** Fastify HTTP server bound to `127.0.0.1` only
237
+ (never `0.0.0.0`), Vue 3 SPA served from `src/dashboard/public/`,
238
+ endpoints: `GET /api/score`, `GET /api/sarif`, `GET /api/health`.
239
+ - **Per-scanner SARIF adapters.** Semgrep (SARIF passthrough with
240
+ effort enrichment), ESLint (native JSON), Bandit (JSON), Stryker
241
+ (JSON mutation report). Every adapter stamps `properties.effortMinutes`
242
+ on each finding so the Stop quality gate can compute a uniform TDR.
243
+ - **CLI.** `claude-crap install` / `doctor` / `status` / `bug-report`
244
+ subcommands. The `bug-report` subcommand produces a Markdown
245
+ diagnostic bundle with every sensitive environment variable
246
+ redacted by name.
247
+ - **Packaging.** Single npm package (`@types`, `import`, `exports`
248
+ surface), postinstall build fallback, `np` release scripts, esbuild
249
+ fast-build path, Bun runtime supported, `docs/` deep reference.
250
+ - **CI.** GitHub Actions workflow that runs `typecheck`, `test`, and
251
+ `audit` on every push and pull request.
252
+ - **Tests.** 155 unit / adapter / integration tests across 27 suites,
253
+ all run on every `npm test` invocation.
254
+
255
+ ### Security
256
+
257
+ The following findings from the OWASP Top 10:2025 pre-publication scan
258
+ were remediated before `v0.1.0` shipped. Each fix landed with
259
+ characterization and attack tests per the Golden Rule in `CLAUDE.md`.
260
+
261
+ - **F-A06-01 (HIGH)** — The PreToolUse hook now fails **closed**
262
+ (exit 2) on any evaluation error when the proposed tool is in the
263
+ high-risk allowlist (`Write`, `Edit`, `MultiEdit`, `NotebookEdit`,
264
+ `Bash`). A best-effort `tool_name` regex recovers the tool name even
265
+ from unparseable stdin, so a crash in `runAllRules` can no longer
266
+ silently bypass the gatekeeper for workspace-mutating tools. Legacy
267
+ fail-open semantics are preserved for low-risk tools so a broken
268
+ hook does not deadlock read-only operations.
269
+ (`plugin/hooks/pre-tool-use.mjs`, `src/tests/pre-tool-use-hook.test.ts`.)
270
+ - **F-A03-01 (HIGH)** — The dashboard no longer fetches Vue from
271
+ `unpkg.com`. Vue 3.5.13 is now vendored locally under
272
+ `src/dashboard/public/vendor/vue.global.prod.js` and the HTML
273
+ comment has been rewritten to describe the vendored runtime
274
+ accurately. Closes a missing-SRI / first-boot-MITM attack vector
275
+ and eliminates a false claim in the source comments.
276
+ (`src/dashboard/public/index.html`,
277
+ `src/dashboard/public/vendor/vue.global.prod.js`,
278
+ `src/tests/dashboard-integrity.test.ts`.)
279
+ - **F-A01-01 (MEDIUM)** — Workspace path containment is now enforced
280
+ by a separator-aware check (`candidate === workspace ||
281
+ candidate.startsWith(workspace + sep)`) extracted into a dedicated
282
+ `src/workspace-guard.ts` module. The previous inlined
283
+ `candidate.startsWith(workspace)` check was vulnerable to
284
+ prefix confusion — a sibling directory like
285
+ `${workspace}-evil/secret.txt` would have been accepted.
286
+ (`src/workspace-guard.ts`, `src/tests/workspace-guard.test.ts`.)
287
+ - **F-A03-02 (LOW / process)** — The `prepublishOnly` script now
288
+ gates on `npm audit --omit=dev --audit-level=high`, so a new
289
+ high-severity advisory in any runtime dependency blocks
290
+ publication until it is resolved. (`package.json`.)
291
+ - **F-A08-01 (LOW)** — `SarifStore.loadLatest` now tolerates
292
+ malformed on-disk reports: the top-level `runs` field must be an
293
+ array, each run is wrapped in its own try/catch, and each result is
294
+ hydrated inside a nested try/catch. A single tampered entry drops
295
+ with a stderr warning instead of crashing the MCP server boot.
296
+ (`src/sarif/sarif-store.ts`, new assertions in
297
+ `src/tests/sarif-store.test.ts`.)
298
+ - **F-A05-01 (LOW)** — Both `ingest_sarif` and `ingest_scanner_output`
299
+ now validate the incoming SARIF document against a minimal AJV
300
+ schema (`src/sarif/sarif-validator.ts`) before touching the store.
301
+ The validator covers exactly the fields claude-crap actually reads
302
+ (`version`, `runs[].tool.driver.name`, and the per-result shape),
303
+ with passthrough allowed for every other field so real-world SARIF
304
+ extensions are not rejected. (`src/sarif/sarif-validator.ts`,
305
+ `src/tests/sarif-validator.test.ts`.)
306
+
307
+ [0.1.1]: https://github.com/ahernandez-developer/claude-crap/releases/tag/v0.1.1
308
+ [0.1.0]: https://github.com/ahernandez-developer/claude-crap/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alan Hernandez
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.