@codacy/gate-cli 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,402 @@
1
+ # /gate-setup — Configure GATE.md for this project
2
+
3
+ You are setting up GATE.md, a quality gate for AI-generated code. Follow every step below. Do not skip steps or reorder them.
4
+
5
+ **Reference files** (installed in this project at `.claude/skills/gate-setup/`):
6
+ - `patterns-reference.yaml` — Research-backed patterns catalog (quality, security, language-specific)
7
+ - `standard-template.yaml` — YAML skeleton for the Standard
8
+
9
+ ---
10
+
11
+ ## Step 1: Check prerequisites
12
+
13
+ 1. Verify `gate` CLI is installed: `which gate`
14
+ - If missing: tell the user to run the installer: `curl -fsSL https://raw.githubusercontent.com/codacy/gatemd/main/install.sh | bash` and stop.
15
+ 2. Verify `codacy-analysis` is installed: `which codacy-analysis`
16
+ - If missing: tell the user to run `npm install -g @codacy/analysis-cli` and stop.
17
+ 3. Check if `GATE.md` already exists in the project root:
18
+ - If it exists and user didn't pass `--force`: say "Already configured. Run `/gate-setup --force` to reconfigure." and stop.
19
+ - If it exists with `--force`: continue (will overwrite).
20
+ 4. Get the git remote URL: `git remote get-url origin`
21
+ - If no remote: ask the user for a project identifier to use instead.
22
+
23
+ ---
24
+
25
+ ## Step 2: Analyze the codebase
26
+
27
+ Detect the following by reading project files:
28
+
29
+ **Languages** — count files by extension:
30
+ ```bash
31
+ find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" -o -name "*.py" -o -name "*.go" -o -name "*.java" -o -name "*.kt" -o -name "*.rb" -o -name "*.rs" -o -name "*.c" -o -name "*.cpp" \) -not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/dist/*" -not -path "*/vendor/*" | sed 's/.*\.//' | sort | uniq -c | sort -rn
32
+ ```
33
+
34
+ **Frameworks** — check config files and dependencies:
35
+ - Read `package.json` → check `dependencies` and `devDependencies` for React, Express, Next.js, Vue, Angular, Fastify, NestJS, etc.
36
+ - Read `pyproject.toml` or `requirements.txt` → check for Django, Flask, FastAPI, etc.
37
+ - Read `go.mod` → check for gin, echo, fiber, etc.
38
+ - Read `pom.xml` or `build.gradle` → check for Spring, etc.
39
+
40
+ **Architecture** — check for markers:
41
+ - `lerna.json`, `pnpm-workspace.yaml`, `nx.json`, `turbo.json` → monorepo
42
+ - Multiple `go.mod` or multiple `package.json` → monorepo
43
+ - `services/` or `packages/` directories → monorepo or microservices
44
+ - Single root → monolith
45
+
46
+ **Existing tool configs** — check for configs already present:
47
+ - `eslint.config.*` or `.eslintrc*` → ESLint already configured (note the path)
48
+ - `.semgrep*` or `semgrep.yaml` → Semgrep rules
49
+ - `trivy.yaml` → Trivy config (note the path)
50
+ - `ruff.toml` or `pyproject.toml [tool.ruff]` → Ruff config
51
+ - `.pylintrc` → Pylint config
52
+ - `.codacy/tools-configs/` → Codacy tool configs (note any files here)
53
+
54
+ **Context** — read for additional insight:
55
+ - `README.md` — project description, purpose
56
+ - `CLAUDE.md` — existing agent instructions
57
+ - Recent `git log --oneline -10` — commit patterns
58
+
59
+ Record all findings. You will use them in the next steps.
60
+
61
+ ---
62
+
63
+ ## Step 3: Ask analysis intensity
64
+
65
+ Use the **AskUserQuestion** tool to ask:
66
+
67
+ > **Analysis intensity:**
68
+ > - **lightweight** — Critical security only. Fastest (~3s). Good for rapid iteration.
69
+ > - **balanced** (recommended) — Security + quality. Good coverage (~8s).
70
+ > - **thorough** — All tools, all rules. Most comprehensive (~15s).
71
+ >
72
+ > Which mode? [balanced]
73
+
74
+ Default to `balanced` if the user says "default" or doesn't specify a preference.
75
+
76
+ ---
77
+
78
+ ## Step 4: Synthesize the Standard
79
+
80
+ Read `.claude/skills/gate-setup/patterns-reference.yaml` and `.claude/skills/gate-setup/standard-template.yaml` from the project root.
81
+
82
+ Generate `.gate/standard.yaml` by filling in the template:
83
+
84
+ 1. **knowledge_spec**: Fill from Step 2 findings (project_name from git remote or directory, languages, frameworks, architecture, build_system, test_framework).
85
+
86
+ 2. **quality_dimensions**: Keep all 4. Adjust thresholds if the existing codebase diverges significantly (e.g., if average file length is 500, set threshold to 400 instead of 300). Add language-specific type_safety signals from the patterns reference.
87
+
88
+ 3. **security_patterns**: Keep all 7. Populate `enforced_by` fields based on detected languages and the tool recommendations in the patterns reference. For tools with existing configs, add those references.
89
+
90
+ 4. **custom_patterns**: Synthesize 2-5 project-specific patterns by analyzing:
91
+ - Project structure (e.g., "all files in `api/` use auth middleware")
92
+ - README/docs stated conventions
93
+ - Existing code patterns (e.g., "RLS policies on all Supabase tables")
94
+ - Each pattern needs: id, description, severity, rationale
95
+
96
+ 5. **process_constraints**: Set `analysis_mode` to the user's choice from Step 3. Keep `self_healing_limit: 2`.
97
+
98
+ 6. **tool_configuration**: Based on detected languages + mode, select tools from the patterns reference `tool_recommendations` section. For existing tool configs, set the config_file path.
99
+
100
+ Write the file to `.gate/standard.yaml`. Show the user a summary:
101
+ > **Standard synthesized:**
102
+ > - Languages: typescript, python
103
+ > - Quality dimensions: 4 (comprehensibility, modularity, type_safety, test_adequacy)
104
+ > - Security patterns: 7 (3 critical, 4 high)
105
+ > - Custom patterns: 3 (auth-middleware, rls-policy, error-boundary)
106
+ > - Analysis mode: balanced
107
+ > - Tools: ESLint9, Semgrep, Trivy
108
+
109
+ Ask for confirmation before proceeding.
110
+
111
+ ---
112
+
113
+ ## Step 5: Configure analysis CLI
114
+
115
+ **ALWAYS OVERWRITE `.codacy/codacy.config.json` completely.** Do NOT read an existing config and tweak it — delete it and write a fresh file from scratch using the template below. Do NOT run `codacy-analysis init` either.
116
+
117
+ ### Why this matters
118
+
119
+ `"patterns": []` means **ALL default patterns** for a tool:
120
+ - ESLint9 = 2,900+ rules → massive output, slow, token explosion
121
+ - Semgrep = 2,517 rules → massive output, slow, token explosion
122
+ - Ruff = 773 rules → same problem
123
+
124
+ **NEVER use `"patterns": []`.** Always populate patterns with specific patternId entries from `patterns-reference.yaml` section 8 (`curated_patterns`). This is the single most important step for keeping analysis fast and token-efficient.
125
+
126
+ ### How to build the config
127
+
128
+ 1. Read `patterns-reference.yaml` → `curated_patterns` section
129
+ 2. For each tool selected for this mode, copy its pattern list into the config
130
+ 3. For tools with an **existing local config** (e.g., `eslint.config.js`): use `localConfigurationFile` to point to it. When `localConfigurationFile` is set, the tool uses its native config and the `patterns` array is ignored — but you still MUST include at least one pattern in the array (the CLI crashes without it). Use a single placeholder: `[{ "patternId": "no-eval" }]` for ESLint, etc.
131
+ 4. For tools **without** a local config: populate the full curated pattern list from `patterns-reference.yaml`
132
+
133
+ ### Template — write this file exactly
134
+
135
+ Delete `.codacy/codacy.config.json` and write a new one. This example is for TypeScript **balanced** mode. Adapt the tool list and patterns for the detected languages and mode.
136
+
137
+ ```json
138
+ {
139
+ "version": 1,
140
+ "metadata": {
141
+ "source": "local",
142
+ "languages": ["TypeScript"]
143
+ },
144
+ "tools": [
145
+ {
146
+ "toolId": "ESLint9",
147
+ "localConfigurationFile": "./eslint.config.js",
148
+ "patterns": [
149
+ { "patternId": "no-eval" },
150
+ { "patternId": "no-implied-eval" },
151
+ { "patternId": "no-new-func" },
152
+ { "patternId": "no-script-url" },
153
+ { "patternId": "no-unused-vars" },
154
+ { "patternId": "no-undef" },
155
+ { "patternId": "no-unreachable" },
156
+ { "patternId": "no-constant-condition" },
157
+ { "patternId": "no-dupe-keys" },
158
+ { "patternId": "no-duplicate-case" },
159
+ { "patternId": "no-fallthrough" },
160
+ { "patternId": "no-self-assign" },
161
+ { "patternId": "no-self-compare" },
162
+ { "patternId": "use-isnan" },
163
+ { "patternId": "valid-typeof" },
164
+ { "patternId": "no-loss-of-precision" },
165
+ { "patternId": "no-unsafe-optional-chaining" },
166
+ { "patternId": "@typescript-eslint/no-explicit-any" },
167
+ { "patternId": "@typescript-eslint/no-unused-vars" },
168
+ { "patternId": "@typescript-eslint/no-unsafe-assignment" },
169
+ { "patternId": "@typescript-eslint/no-unsafe-call" },
170
+ { "patternId": "@typescript-eslint/no-unsafe-return" },
171
+ { "patternId": "eqeqeq" },
172
+ { "patternId": "no-var" },
173
+ { "patternId": "prefer-const" }
174
+ ]
175
+ },
176
+ {
177
+ "toolId": "Semgrep",
178
+ "patterns": [
179
+ { "patternId": "javascript.lang.security.audit.sqli.node-sequelize-sqli" },
180
+ { "patternId": "javascript.lang.security.audit.sqli.node-knex-sqli" },
181
+ { "patternId": "typescript.lang.security.audit.sqli.node-sequelize-sqli" },
182
+ { "patternId": "javascript.lang.security.audit.command-injection" },
183
+ { "patternId": "javascript.lang.security.audit.unsafe-html" },
184
+ { "patternId": "generic.secrets.security.detected-generic-api-key" },
185
+ { "patternId": "javascript.express.security.audit.express-jwt-not-revoked" },
186
+ { "patternId": "javascript.jsonwebtoken.security.jwt-hardcode" }
187
+ ]
188
+ },
189
+ {
190
+ "toolId": "Trivy",
191
+ "patterns": [
192
+ { "patternId": "trivy_vuln" },
193
+ { "patternId": "trivy_secret" },
194
+ { "patternId": "trivy_config" },
195
+ { "patternId": "trivy_license" }
196
+ ]
197
+ }
198
+ ],
199
+ "exclude": [
200
+ "**/node_modules/**",
201
+ "**/dist/**",
202
+ "**/build/**",
203
+ "**/.git/**",
204
+ "**/vendor/**",
205
+ "**/coverage/**"
206
+ ]
207
+ }
208
+ ```
209
+
210
+ **Tool selection by language** — ONLY include tools that apply to the detected languages:
211
+
212
+ | Language | Balanced mode tools |
213
+ |----------|-------------------|
214
+ | TypeScript/JavaScript | ESLint9 + Semgrep + Trivy |
215
+ | Python | Ruff + Semgrep + Trivy |
216
+ | Go | Semgrep + Trivy |
217
+ | Java | PMD7 + Semgrep + Trivy |
218
+ | Kotlin | detekt + Semgrep + Trivy |
219
+ | Shell | shellcheck + Trivy |
220
+ | C/C++ | cppcheck + flawfinder + Trivy |
221
+ | Dockerfile | Hadolint + Trivy |
222
+
223
+ Use curated patterns from `patterns-reference.yaml` for each tool. For Python, use the Ruff and Semgrep Python patterns. For TypeScript, use ESLint9 and Semgrep JS/TS patterns.
224
+
225
+ **Do NOT include tools for languages not in the project.** For example:
226
+ - Do NOT add ESLint9 to a Python project
227
+ - Do NOT add Checkov unless the project has Terraform/CloudFormation/K8s files
228
+ - Do NOT add Hadolint unless the project has Dockerfiles
229
+ - Do NOT add shellcheck unless the project has shell scripts
230
+
231
+ ### Format rules (the CLI will crash without these)
232
+
233
+ - **Every tool MUST have a `"patterns"` array with at least one entry.** Without it: `Cannot read properties of undefined (reading 'map')`.
234
+ - **NEVER use `"patterns": []`** — this enables ALL defaults (thousands of rules).
235
+ - `"toolId"` is the field name, NOT `"name"` or `"tool"`.
236
+ - Exact adapter IDs: `ESLint9`, `Semgrep`, `Trivy`, `Ruff`, `Bandit`, `shellcheck`, `Hadolint`, `PMD7`, `Checkstyle`, `detekt`, `cppcheck`, `flawfinder`, `Lizard`, `PyLintPython3`.
237
+ - `"metadata.languages"` — capitalize first letter: `"TypeScript"`, `"Python"`, `"JavaScript"`, `"Go"`, `"Java"`, `"Shell"`.
238
+
239
+ ### Tool selection by mode
240
+
241
+ | Mode | Tools | Approximate pattern count |
242
+ |------|-------|--------------------------|
243
+ | lightweight | Trivy only | ~4 patterns |
244
+ | balanced | Language linter + Semgrep + Trivy | ~25 + ~8-17 + 4 = ~40 patterns |
245
+ | thorough | All applicable + Lizard | ~60-80 patterns |
246
+
247
+ ### Verify
248
+
249
+ ```bash
250
+ codacy-analysis analyze --install-dependencies --files src/some-small-file.ts --log-level error --output-format json 2>/dev/null
251
+ ```
252
+
253
+ Expected: single-digit findings per file, not hundreds. If you see 50+ issues from one file, you likely have `"patterns": []` somewhere — fix it. The `--install-dependencies` flag ensures any missing tool binaries (ESLint9, Semgrep, Trivy, etc.) are auto-installed by the CLI — no need to install them manually.
254
+
255
+ ---
256
+
257
+ ## Step 6: Register with GATE.md service
258
+
259
+ Use the `gate` CLI to register. It handles credential storage and service URL automatically.
260
+
261
+ ```bash
262
+ gate auth register --project "PROJECT_NAME" --remote "GIT_REMOTE_URL"
263
+ ```
264
+
265
+ This command:
266
+ - **New project**: Registers, stores token + service URL in `.gate/credentials`, prints `project_id`. Continue.
267
+ - **Already registered**: Automatically discovers the project, ensures `.gate/credentials` has the service URL. If a token already exists in credentials, it updates the file and succeeds. If no token exists, it asks you to paste one.
268
+ - **Other errors**: Show the error and stop.
269
+
270
+ After this step, `.gate/credentials` will contain both `token` and `service_url` — all subsequent `gate` commands will work.
271
+
272
+ ---
273
+
274
+ ## Step 7: Upload Standard and config
275
+
276
+ ### Upload the Standard
277
+
278
+ The `gate` CLI handles YAML→JSON conversion automatically:
279
+
280
+ ```bash
281
+ gate standard push
282
+ ```
283
+
284
+ This reads `.gate/standard.yaml`, converts it to JSON, and uploads it. Verify the output shows `version: 1`.
285
+
286
+ ### Upload analysis config
287
+
288
+ ```bash
289
+ gate config push
290
+ ```
291
+
292
+ This reads `.codacy/codacy.config.json` and uploads it.
293
+
294
+ ---
295
+
296
+ ## Step 8: Generate GATE.md file
297
+
298
+ Create `GATE.md` at the project root with this content:
299
+
300
+ ```markdown
301
+ # GATE.md — Quality Gate
302
+
303
+ > This project uses [GATE.md](https://gate.md) to enforce quality and security standards on AI-generated code.
304
+
305
+ **URL:** ${SERVICE_URL}
306
+ **Project:** ${PROJECT_ID}
307
+ **Standard:** v1
308
+
309
+ ## Quality Dimensions
310
+ - Comprehensibility (file length, complexity, naming)
311
+ - Modularity (separation of concerns, shallow abstractions)
312
+ - Type Safety (strict types, explicit returns)
313
+ - Test Adequacy (coverage, test quality)
314
+
315
+ ## Security Patterns
316
+ - No hardcoded secrets (CWE-798)
317
+ - Input sanitization (CWE-20)
318
+ - Parameterized queries (CWE-89)
319
+ - Dependency verification (CWE-1395)
320
+ - No unsafe deserialization (CWE-502)
321
+ - Access control checks (CWE-639)
322
+ - Config file integrity (CWE-15)
323
+
324
+ ## How It Works
325
+ Every time the coding agent stops, the GATE.md hook:
326
+ 1. Runs static analysis via @codacy/analysis-cli
327
+ 2. Sends results + code to the GATE.md service
328
+ 3. Gemini independently reviews the code
329
+ 4. Returns PASS / WARN / FAIL with actionable findings
330
+ ```
331
+
332
+ ---
333
+
334
+ ## Step 9: Verify hooks
335
+
336
+ The installer already wired the Claude Code hooks via `gate hooks install`. Verify they're in place:
337
+
338
+ ```bash
339
+ gate hooks check
340
+ ```
341
+
342
+ Expected output:
343
+ ```
344
+ [gate] Stop hook (gate analyze): installed
345
+ [gate] Intent hook (gate intent capture): installed
346
+ ```
347
+
348
+ If hooks are missing (e.g., user installed manually without the installer), install them:
349
+
350
+ ```bash
351
+ gate hooks install
352
+ ```
353
+
354
+ This wires both the Stop hook (`gate analyze`) and UserPromptSubmit hook (`gate intent capture`) into `.claude/settings.json`, preserving any existing hooks.
355
+
356
+ ---
357
+
358
+ ## Step 10: Update .gitignore
359
+
360
+ Add these entries to `.gitignore` (create it if it doesn't exist, append if it does):
361
+
362
+ ```
363
+ # GATE.md
364
+ .gate/credentials
365
+ .gate/.cache/
366
+ .gate/.last-analysis
367
+ .gate/.iteration-count
368
+ .gate/.last-pass-hash
369
+ .gate/.last-intent
370
+ ```
371
+
372
+ Do NOT gitignore `.gate/standard.yaml` or `GATE.md` — those should be committed. The `.gate/credentials` file contains the project token and MUST be gitignored.
373
+
374
+ ---
375
+
376
+ ## Step 11: Show summary
377
+
378
+ Print a complete summary:
379
+
380
+ ```
381
+ === GATE.md Setup Complete ===
382
+
383
+ Project: ${PROJECT_NAME}
384
+ Languages: ${LANGUAGES}
385
+ Frameworks: ${FRAMEWORKS}
386
+ Architecture: ${ARCHITECTURE}
387
+ Mode: ${MODE}
388
+
389
+ Standard: v1 (4 quality, 7 security, N custom patterns)
390
+ Tools: ${TOOL_LIST}
391
+ Service: registered (project_id: ${PROJECT_ID})
392
+ Hooks: installed (gate analyze + gate intent capture)
393
+
394
+ Files created:
395
+ .gate/standard.yaml — Quality standard
396
+ .codacy/codacy.config.json — Analysis CLI config
397
+ GATE.md — Project quality overview
398
+ .claude/settings.json — Hook configuration (verified)
399
+ .gitignore — Updated with GATE.md entries
400
+
401
+ Next: You should now be seeing the first analysis happening below. The hook will fire automatically every time your agent stops working on something.
402
+ ```