@cleartrip/frontguard 0.3.6 → 1.0.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.
Files changed (4) hide show
  1. package/README.md +221 -193
  2. package/dist/cli.js +600 -530
  3. package/dist/cli.js.map +1 -1
  4. package/package.json +11 -6
package/README.md CHANGED
@@ -1,308 +1,336 @@
1
1
  # FrontGuard
2
2
 
3
- Org-wide frontend PR guardrails for Bitbucket Cloud. Runs automated checks on every pull request linting, type safety, bundle size, secrets, PR hygiene, and more — then posts a summary comment with a link to the full interactive report.
3
+ Automated frontend code quality checks for every pull request. Runs in CI, catches issues before merge, and posts a clean report comment with a link to the full interactive HTML report.
4
4
 
5
5
  ---
6
6
 
7
- ## Quick Start
7
+ ## What it checks
8
+
9
+ | Check | What it does | Runs on |
10
+ |:------|:------------|:--------|
11
+ | **eslint** | Linting with your project's ESLint config | Changed files |
12
+ | **prettier** | Formatting check against your Prettier config | Changed files |
13
+ | **typescript** | `tsc --noEmit` type checking | Whole project |
14
+ | **secrets** | Regex scan for leaked tokens, keys, private keys | Changed files |
15
+ | **pr-hygiene** | PR description length, required sections, AI disclosure | PR metadata |
16
+ | **pr-size** | Flags PRs that are too large to review effectively | PR diff |
17
+ | **ts-any-delta** | Counts new `any` usage introduced in this diff | PR diff |
18
+ | **cycles** | Circular import detection via `madge` | Source tree |
19
+ | **dead-code** | Unused exports via `ts-prune` | Whole project |
20
+ | **bundle** | Bundle size measured after build, compared to a baseline | Build output |
21
+ | **core-web-vitals** | Static JSX/TSX hints for LCP, CLS, FID patterns | Changed files |
22
+ | **react-native** | Metro config, SwiftLint, native file hints (RN projects only) | Changed files |
23
+ | **custom-rules** | Your own file/content checks defined in config | Changed files |
24
+ | **ai-assisted-strict** | Stricter checks on AI-generated code regions | Opt-in |
25
+
26
+ All checks are **enabled by default** except `ai-assisted-strict` and `llm` (both off by default). Every check can be disabled or tuned individually.
27
+
28
+ ---
29
+
30
+ ## Quick start
8
31
 
9
32
  ### 1. Install
10
33
 
11
34
  ```bash
12
- # yarn
13
- yarn add -D @cleartrip/frontguard
14
-
15
- # npm
16
35
  npm install -D @cleartrip/frontguard
17
-
18
- # pnpm
36
+ # or
37
+ yarn add -D @cleartrip/frontguard
38
+ # or
19
39
  pnpm add -D @cleartrip/frontguard
20
40
  ```
21
41
 
22
- ### 2. Initialize
42
+ ### 2. Initialise
23
43
 
24
44
  ```bash
25
45
  npx frontguard init
26
46
  ```
27
47
 
28
- This does three things:
29
-
30
- - **Creates `frontguard.config.mjs`** (ESM) with all available options as commented examples — works even when `package.json` is not `"type": "module"`
31
- - **Creates `pull_request_template.md`** with AI disclosure checkboxes
32
- - **Merges the FrontGuard step** into your existing `bitbucket-pipelines.yml` (or creates one if missing)
33
-
34
- > If your repo already has a `pull-requests:` section in the pipeline, `init` appends the FrontGuard step to it without touching your `image`, `clone`, or other pipeline config.
35
-
36
- ### 3. Configure
37
-
38
- Open `frontguard.config.mjs` and uncomment the checks you want. Every option is documented inline.
39
-
40
- ### 4. Set Up CI
48
+ This creates three files:
41
49
 
42
- Add `BITBUCKET_ACCESS_TOKEN` as a **secured variable** in your Bitbucket repo settings. The token needs permission to **post pull request comments**.
50
+ - **`frontguard.config.mjs`** config file with every option documented as comments
51
+ - **`pull_request_template.md`** — PR template with AI disclosure checkboxes
52
+ - **`bitbucket-pipelines.yml`** — creates or updates the pipeline with a FrontGuard step
43
53
 
44
- ---
45
-
46
- ## How It Works
54
+ ### 3. Run locally
47
55
 
48
- ```
49
- PR opened → Bitbucket pipeline triggers → FrontGuard runs all enabled checks
50
- → Generates HTML report → Uploads to FreeKit → Posts Markdown comment on PR
56
+ ```bash
57
+ npx frontguard run
51
58
  ```
52
59
 
53
- The PR comment includes:
54
- - **RISK score** (LOW / MEDIUM / HIGH) based on findings and PR size
55
- - **Table of failing checks** (only checks with issues — clean checks are omitted)
56
- - **Link to full interactive HTML report** hosted on FreeKit
60
+ Run the same checks locally before pushing. No CI environment needed.
57
61
 
58
62
  ---
59
63
 
60
- ## Checks
61
-
62
- | Check | What it does | Default |
63
- |-------|-------------|---------|
64
- | **eslint** | Runs ESLint with your project config (skips `frontguard.config.*` by default) | Enabled |
65
- | **prettier** | Verifies Prettier formatting (skips `frontguard.config.*` by default) | Enabled |
66
- | **typescript** | Runs `tsc --noEmit` for type errors | Enabled |
67
- | **secrets** | Scans for leaked tokens, keys, passwords | Enabled |
68
- | **pr-hygiene** | Validates PR description, sections, AI disclosure | Enabled |
69
- | **pr-size** | Flags oversized PRs by line count | Enabled |
70
- | **ts-any-delta** | Counts new `any` usage in the diff | Enabled |
71
- | **cycles** | Detects circular imports via madge | Enabled |
72
- | **dead-code** | Finds unused exports via ts-prune | Enabled |
73
- | **bundle** | Measures bundle size, compares to baseline | Enabled |
74
- | **react-native** | Metro config, optional align-deps / doctor, SwiftLint + native hints (RN deps only) | Enabled |
75
- | **core-web-vitals** | Static CWV hints in JSX/TSX | Enabled |
76
- | **ai-assisted-strict** | Static heuristics on AI-marked code / AI PRs | **Off** (under development) |
77
- | **custom-rules** | Your own pattern checks defined in config | Enabled |
78
- | **llm** | Automated diff review / fix hints | **Off** (under development) |
79
-
80
- ---
64
+ ## Configuration
81
65
 
82
- ## React Native check (`react-native`)
66
+ Config lives in `frontguard.config.mjs` (recommended), `frontguard.config.cjs`, or `frontguard.config.js` at your project root.
83
67
 
84
- Runs when `react-native` is in dependencies (skipped otherwise).
68
+ ```js
69
+ // frontguard.config.mjs
70
+ import { defineConfig } from '@cleartrip/frontguard'
85
71
 
86
- | Sub-feature | Default | Notes |
87
- |-------------|---------|--------|
88
- | Metro config | **On** | Expects `metro.config.js` (or `.mjs` / `.cjs` / `.ts`) at project root. |
89
- | `@rnx-kit/align-deps` | **Off** | Set `checks.reactNative.runAlignDeps: true` (uses `npx`, needs registry). Tune `alignDepsArgs` (e.g. `['--requirements', 'react-native@0.76']`). |
90
- | `react-native doctor` | **Off** | Set `runDoctor: true` where the local CLI exists (can be slow / macOS-heavy). |
91
- | SwiftLint | **On** (PR only) | If the PR touches `*.swift` and `swiftlint` is on `PATH`, violations are reported; otherwise an info hint. |
92
- | Android / ObjC hints | **On** (PR only) | Info reminders when `android/**/*.kt|java` or `.m` / `.mm` change — does not run Gradle or Xcode. |
72
+ export default defineConfig({
73
+ // 'warn' = advisory only, CI never fails (default)
74
+ // 'enforce' = CI exits non-zero on any block-severity finding
75
+ mode: 'warn',
93
76
 
94
- This is intentionally lightweight; you can extend CI with Detekt, Android Lint, or deeper Metro analysis later.
77
+ checks: {
78
+ // Tune any check by key — only set what you want to override
79
+ prSize: {
80
+ tiers: [
81
+ { minLines: 800, severity: 'block', message: 'PR too large (${lines} lines). Split it up.' },
82
+ { minLines: 400, severity: 'warn', message: 'Large PR (${lines} lines). Consider splitting.' },
83
+ ],
84
+ },
85
+ bundle: {
86
+ buildCommand: 'yarn build',
87
+ maxDeltaBytes: 50_000, // fail if bundle grows more than 50 kB
88
+ },
89
+ // Disable a check entirely
90
+ deadCode: { enabled: false },
91
+ // Custom rules — plain JS functions
92
+ // (see Custom rules section below)
93
+ },
94
+ })
95
+ ```
95
96
 
96
- ---
97
+ Run `frontguard init` to generate the full annotated template.
97
98
 
98
- ## Bundle Size Strategies
99
+ ### Severity levels
99
100
 
100
- The bundle check supports multiple strategies for extracting the size metric:
101
+ | Level | Meaning |
102
+ |:------|:--------|
103
+ | `info` | Informational note — never fails CI |
104
+ | `warn` | Advisory — visible in report, CI passes unless `mode: 'enforce'` |
105
+ | `block` | Failing — CI exits non-zero when `mode: 'enforce'` is set |
101
106
 
102
- | Strategy | How it works |
103
- |----------|-------------|
104
- | `auto` | Auto-detects from `package.json` — Next.js, Vite, CRA, or falls back to glob |
105
- | `next` | Parses `next build` stdout for "First Load JS shared by all" |
106
- | `vite` | Sums JS files under `dist/assets/` after build |
107
- | `cra` | Parses `react-scripts build` stdout for gzipped JS total |
108
- | `glob` | Sums raw bytes under `measureGlobs` (generic fallback) |
109
- | `custom` | Runs your `bundleSizeCommand`, reads a single number (bytes) from stdout |
107
+ ### Gate modes
110
108
 
111
- ### Examples
109
+ Most checks have a `gate` option that controls the severity of their findings:
112
110
 
113
- **Next.js (auto-detected):**
114
111
  ```js
115
- // frontguard.config.mjs no strategy override needed
116
- bundle: {
117
- buildCommand: 'yarn build',
118
- maxDeltaBytes: 50_000,
119
- }
112
+ cycles: { gate: 'block' } // circular deps now fail CI in enforce mode
113
+ tsAnyDelta: { gate: 'warn' } // any usage is advisory (default)
120
114
  ```
121
115
 
122
- **Custom script:**
123
- ```js
124
- bundle: {
125
- bundleSizeStrategy: 'custom',
126
- bundleSizeCommand: 'node scripts/bundle-size.js',
127
- buildCommand: 'yarn build',
128
- }
129
- ```
116
+ ---
130
117
 
131
- **Baseline file** (`.frontguard/bundle-baseline.json`):
132
- ```json
133
- { "totalBytes": 245760 }
134
- ```
118
+ ## Custom rules
135
119
 
136
- Commit this to your base branch. FrontGuard compares the current build against it.
120
+ Define your own checks inline in the config file. The function receives `{ path, content }` for each file and returns `true` when the rule is violated.
121
+
122
+ ```js
123
+ export default defineConfig({
124
+ rules: {
125
+ 'no-console-log': {
126
+ severity: 'warn',
127
+ message: 'Remove console.log before merging',
128
+ check: (file) =>
129
+ /\.(ts|tsx|js|jsx)$/.test(file.path) && /console\.log\(/.test(file.content),
130
+ },
131
+ 'no-todo-comments': {
132
+ severity: 'info',
133
+ message: 'Unresolved TODO comment',
134
+ check: (file) => /\bTODO\b/.test(file.content),
135
+ },
136
+ 'no-inline-styles': {
137
+ severity: 'info',
138
+ message: 'Prefer CSS classes over inline style objects',
139
+ check: (file) => /\.tsx$/.test(file.path) && file.content.includes('style={{'),
140
+ },
141
+ },
142
+ })
143
+ ```
137
144
 
138
145
  ---
139
146
 
140
- ## Configuration
147
+ ## Bundle size
141
148
 
142
- FrontGuard loads the first file that exists, in order: **`frontguard.config.mjs`** **`frontguard.config.cjs`** **`frontguard.config.js`**.
149
+ The bundle check builds your project and compares the output size against a baseline file you commit to your repo.
143
150
 
144
- - **`.mjs`** — ESM (`import` / `export default`). Use this in CommonJS-only repos (no `"type": "module"` needed). **Recommended.**
145
- - **`.cjs`** — CommonJS without importing the package (plain object merges like `defineConfig`):
151
+ ### Setup
146
152
 
147
- ```js
148
- // frontguard.config.cjs
149
- module.exports = {
150
- checks: {
151
- bundle: { buildCommand: 'yarn build:prod', bundleSizeStrategy: 'next' },
152
- },
153
- }
154
- ```
153
+ 1. Run your build once and create the baseline:
154
+ ```bash
155
+ echo '{ "totalBytes": 245760 }' > .frontguard/bundle-baseline.json
156
+ git add .frontguard/bundle-baseline.json
157
+ ```
155
158
 
156
- - **`.js`** Only reliable as ESM if your `package.json` has `"type": "module"`; otherwise Node may refuse to load it (you will see an ESM warning and defaults will apply).
159
+ 2. Configure the check:
160
+ ```js
161
+ bundle: {
162
+ buildCommand: 'yarn build',
163
+ maxDeltaBytes: 50_000, // warn/block if bundle grows > 50 kB
164
+ maxTotalBytes: null, // or set an absolute cap
165
+ }
166
+ ```
157
167
 
158
- **CI / monorepos:** Run `frontguard` with `cwd` set to the app root that contains `package.json` and the config file. **Git:** If you see `fatal: Needed a single revision`, increase clone depth or fetch the PR destination branch (e.g. `git fetch origin main:refs/remotes/origin/main`) so diff and baseline reads can resolve `origin/<branch>`.
168
+ 3. FrontGuard reads the baseline from `baselineRef` (default: `main`) when the file is not on disk, so it works in PR pipelines automatically.
159
169
 
160
- All configuration lives in one of those files at your project root (same directory you run `frontguard` from):
170
+ ### Size strategies
161
171
 
162
- ```js
163
- import { defineConfig } from '@cleartrip/frontguard'
172
+ | Strategy | Use when |
173
+ |:---------|:---------|
174
+ | `auto` | Most projects — auto-detects Next.js, Vite, CRA, or falls back to glob |
175
+ | `next` | Next.js — reads "First Load JS shared by all" from build output |
176
+ | `vite` | Vite — sums `dist/assets/*.js` |
177
+ | `cra` | Create React App — reads gzipped JS total from build output |
178
+ | `glob` | Custom build tools — sums files matching `measureGlobs` |
179
+ | `custom` | Anything else — runs `bundleSizeCommand`, reads bytes from stdout |
164
180
 
165
- export default defineConfig({
166
- mode: 'warn', // 'warn' or 'enforce'
167
- checks: {
168
- bundle: {
169
- buildCommand: 'yarn build',
170
- bundleSizeStrategy: 'auto',
171
- maxDeltaBytes: 50_000,
172
- },
173
- prSize: {
174
- tiers: [
175
- { minLines: 1000, severity: 'block', message: 'PR too large (${lines} lines)' },
176
- { minLines: 500, severity: 'warn', message: 'Consider splitting (${lines} lines)' },
177
- ],
178
- },
179
- // AI-assisted + LLM are WIP — leave off unless you opt in explicitly:
180
- // aiAssistedReview: { enabled: true },
181
- // llm: { enabled: true, provider: 'ollama', model: 'llama3.2' },
182
- },
183
- })
184
- ```
181
+ ---
185
182
 
186
- Run `frontguard init` to generate a config file with every option documented as comments.
183
+ ## PR hygiene
187
184
 
188
- ### ESLint / Prettier vs `frontguard.config.*`
185
+ Validates the PR description when running in CI (requires `FRONTGUARD_PR_BODY` env var):
189
186
 
190
- Defaults exclude `frontguard.config.mjs`, `frontguard.config.js`, and `frontguard.config.cjs` via `checks.eslint.ignorePatterns` and `checks.prettier.ignorePatterns` (picomatch globs, repo-relative). That keeps tool config from being judged by product rules. Set `ignorePatterns: []` on either check if you want those files linted/formatted. To extend the list in shared config, spread `DEFAULT_FRONTGUARD_CONFIG_IGNORE_PATTERNS` from `@cleartrip/frontguard`.
187
+ ```js
188
+ prHygiene: {
189
+ minBodyLength: 80, // minimum characters in description
190
+ requireSections: true, // require headers from sectionHints
191
+ sectionHints: ['what', 'why', 'test', 'screenshot'],
192
+ requireAiDisclosureSection: true, // expect an ## AI disclosure section
193
+ }
194
+ ```
191
195
 
192
- ### Bitbucket PR comment table
196
+ The `pull_request_template.md` created by `frontguard init` includes the AI disclosure section automatically.
193
197
 
194
- The short PR comment lists **only checks that reported findings**. Skipped checks stay out of that table; the full HTML report still shows every check, including skips.
198
+ ---
195
199
 
196
- ### Shared Org Config
200
+ ## Shared org config
197
201
 
198
- Publish a shared config package and extend it:
202
+ Publish defaults to an npm package and extend them in each repo:
199
203
 
200
204
  ```js
205
+ // frontguard.config.mjs
201
206
  export default defineConfig({
202
- extends: '@your-org/frontguard-config/base',
207
+ extends: '@your-org/frontguard-config',
203
208
  checks: {
204
- // project-specific overrides
209
+ // repo-specific overrides
205
210
  },
206
211
  })
207
212
  ```
208
213
 
214
+ The org config is deep-merged as a base layer. Individual repos only need to set what differs.
215
+
209
216
  ---
210
217
 
211
- ## CLI
218
+ ## CLI reference
212
219
 
213
220
  ```bash
214
- # Initialize project (config + pipeline + PR template)
221
+ # Scaffold config, PR template, and pipeline step
215
222
  frontguard init
216
223
 
217
- # Run all checks (console + markdown output)
224
+ # Run all checks (console output + markdown report)
218
225
  frontguard run
219
226
 
220
- # Run with markdown-only output
227
+ # Fail CI on block-severity findings
228
+ frontguard run --enforce
229
+
230
+ # Output markdown only (good for capturing in CI logs)
221
231
  frontguard run --markdown
222
232
 
223
- # Run in enforce mode (exit 1 on blocking findings)
224
- frontguard run --enforce
233
+ # Generate HTML report file
234
+ frontguard run --htmlOut report.html
225
235
 
226
- # Generate HTML report + PR comment markdown
227
- frontguard run --htmlOut report.html --prCommentOut comment.md
236
+ # Generate Bitbucket PR comment markdown
237
+ frontguard run --prCommentOut comment.md
228
238
 
229
- # Append manual review notes
239
+ # Append manual review notes to the report
230
240
  frontguard run --append ./notes.md
231
241
  ```
232
242
 
233
243
  ---
234
244
 
235
- ## Pipeline Integration
245
+ ## CI integration (Bitbucket)
236
246
 
237
- ### How `init` handles your pipeline
247
+ `frontguard init` creates or updates `bitbucket-pipelines.yml` with a ready-to-use step. It:
238
248
 
239
- | Scenario | What `init` does |
240
- |----------|-----------------|
241
- | No `bitbucket-pipelines.yml` | Creates one with `image`, `clone`, and the FrontGuard step |
242
- | File exists, no `pull-requests:` section | Appends a `pull-requests:` section with the FrontGuard step |
243
- | File exists, `pull-requests:` with existing steps | Appends the FrontGuard step after your existing steps |
244
- | FrontGuard step already present | Skips (no duplicate) |
245
-
246
- Your `image`, `clone`, `definitions`, and other pipeline sections are **never modified**.
249
+ 1. Runs all checks
250
+ 2. Generates an HTML report
251
+ 3. Uploads it to [FreeKit](https://freekit.dev) (static hosting, free, no login)
252
+ 4. Posts a comment on the PR with the risk score and a link to the full report
247
253
 
248
- ### Required Variables
254
+ ### Required variables
249
255
 
250
- | Variable | Type | Purpose |
251
- |----------|------|---------|
252
- | `BITBUCKET_ACCESS_TOKEN` | Secured | Post PR comments |
253
- | `FREEKIT_BASE_URL` | Optional | Override report hosting endpoint |
256
+ Add these as secured variables in your Bitbucket repo settings:
254
257
 
255
- ---
258
+ | Variable | Required | Purpose |
259
+ |:---------|:---------|:--------|
260
+ | `BITBUCKET_ACCESS_TOKEN` | Yes | Post PR comments |
261
+ | `FREEKIT_BASE_URL` | No | Override report hosting (default: `https://freekit.dev`) |
262
+ | `FRONTGUARD_PR_BODY` | No | Pass PR description to `pr-hygiene` check |
256
263
 
257
- ## Risk Scoring
264
+ ### Pipeline init scenarios
258
265
 
259
- The composite risk score is a heuristic combining:
266
+ | Situation | What `init` does |
267
+ |:----------|:----------------|
268
+ | No `bitbucket-pipelines.yml` | Creates one with `image`, `clone`, and the FrontGuard step |
269
+ | File exists, no `pull-requests:` section | Appends a `pull-requests:` section |
270
+ | File exists, `pull-requests:` present | Appends the FrontGuard step after existing steps |
271
+ | FrontGuard step already present | Skips (no duplicates) |
260
272
 
261
- | Signal | LOW | MEDIUM | HIGH |
262
- |--------|-----|--------|------|
263
- | Blocking findings | 0 | — | 1+ |
264
- | Warning count | < 3 | 3–7 | 8+ |
265
- | PR size (lines) | < 400 | 400–799 | 800+ |
266
- | Changed files | < 25 | — | 25+ |
273
+ Your `image`, `clone`, `definitions`, and other pipeline config are never modified.
267
274
 
268
275
  ---
269
276
 
270
- ## AI-assisted review and LLM (under development)
277
+ ## Risk scoring
271
278
 
272
- These features are **implemented in code but turned off by default** so day-to-day CI stays predictable.
279
+ The risk score is a heuristic shown at the top of every report.
273
280
 
274
- | Feature | Config | Default |
275
- |---------|--------|---------|
276
- | **AI-assisted strict** (`ai-assisted-strict` check) | `checks.aiAssistedReview.enabled` | `false` |
277
- | **LLM appendix + Cursor rules context** | `checks.llm.enabled` | `false` |
281
+ | Score | When |
282
+ |:------|:-----|
283
+ | 🔴 HIGH | 1+ blocking findings, or 8+ warnings, or 800+ changed lines |
284
+ | 🟡 MEDIUM | 3–7 warnings, or 400–799 changed lines, or 25+ files changed |
285
+ | 🟢 LOW | No significant findings |
278
286
 
279
- When you are ready to try them:
287
+ The score is informational it does not affect CI pass/fail by itself.
280
288
 
281
- 1. Set `checks.aiAssistedReview.enabled: true` for static heuristics on `@frontguard-ai` regions or AI-disclosed PRs (see `frontguard.config.mjs` comments).
282
- 2. Set `checks.llm.enabled: true` and choose `provider: 'ollama' | 'openai' | 'anthropic'` for automated review text.
289
+ ---
283
290
 
284
- **PR template:** The init flow still adds an **AI disclosure** section to `pull_request_template.md` for human reviewers. With AI-assisted review off, that disclosure is recorded as an info finding and does not enable extra static checks until you opt in.
291
+ ## React Native
285
292
 
286
- ### Cursor rules (LLM only)
293
+ The `react-native` check runs automatically when `react-native` is in your dependencies.
287
294
 
288
- When **`checks.llm.enabled`** is true, FrontGuard loads `.cursor/rules/*.{md,mdc}`, `.cursorrules`, and `AGENTS.md` (up to ~32 kB) and injects them into the LLM prompts. With LLM off, those files are not read.
295
+ | Sub-check | Default | What it does |
296
+ |:----------|:--------|:-------------|
297
+ | Metro config | On | Warns if `metro.config.*` is missing |
298
+ | SwiftLint | On | Runs `swiftlint` when PR touches `.swift` files |
299
+ | Android hint | On | Reminds to run Android Lint when `.kt`/`.java` change |
300
+ | `@rnx-kit/align-deps` | Off | Validates RN dependency alignment (opt-in, needs network) |
301
+ | `react-native doctor` | Off | Runs the RN doctor CLI (opt-in, slow) |
289
302
 
290
303
  ---
291
304
 
292
- ## Local Development
305
+ ## AI-assisted review (opt-in)
293
306
 
294
- ```bash
295
- # Run checks locally (same as CI)
296
- npx frontguard run
307
+ Stricter checks for code written by AI tools. Disabled by default.
308
+
309
+ ```js
310
+ aiAssistedReview: {
311
+ enabled: true,
312
+ gate: 'warn',
313
+ strictScanMode: 'decorator', // 'decorator' | 'pr-disclosure' | 'both'
314
+ }
297
315
  ```
298
316
 
317
+ Mark AI-generated code with inline comments:
318
+
319
+ ```ts
320
+ // @frontguard-ai:start
321
+ const result = eval(userInput) // flagged: eval in AI region
322
+ // @frontguard-ai:end
323
+ ```
324
+
325
+ Detects: `eval()`, `dangerouslySetInnerHTML`, `@ts-ignore`, empty `catch`, `new Function()`, plain HTTP URLs, tokens in `localStorage`, dynamic SQL, and more.
326
+
299
327
  ---
300
328
 
301
329
  ## Requirements
302
330
 
303
- - **Node.js** >= 18
304
- - **Bitbucket Cloud** pipelines
305
- - `BITBUCKET_ACCESS_TOKEN` for PR comments
331
+ - **Node.js** 18
332
+ - Git (for diff and baseline operations)
333
+ - Bitbucket Cloud pipelines (for PR context and comment posting)
306
334
 
307
335
  ---
308
336