@critiq/cli 0.0.1 → 0.1.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 (3) hide show
  1. package/README.md +133 -254
  2. package/main.js +17067 -7931
  3. package/package.json +10 -5
package/README.md CHANGED
@@ -1,305 +1,184 @@
1
- # critiq CLI
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/critiq-dev/critiq-core/main/docs/assets/banner-cli-simple-transparent.png" alt="critiq.dev" style="max-height:400px" />
3
+ </p>
2
4
 
3
- `critiq` is the local developer interface for working with Critiq rules in your
4
- own repository.
5
+ <h1 align="center">Critiq CLI</h1>
6
+ <p align="center">
7
+ <strong>Open source deterministic static analysis for code review.<br/>Run high-signal checks on your codebase to identify security, performance, scaling issues before it goes to production</strong>
8
+ </p>
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/@critiq/cli"><img src="https://img.shields.io/npm/v/%40critiq%2Fcli" alt="npm version" /></a>
11
+ <a href="https://github.com/critiq-dev/critiq-core/tree/main/apps/cli"><img src="https://img.shields.io/badge/source-GitHub-181717?logo=github" alt="Source" /></a>
12
+ <a href="https://github.com/critiq-dev/critiq-core/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache%202.0-blue.svg" alt="License" /></a>
13
+ </p>
5
14
 
6
- Install it with the default OSS catalog:
7
15
 
8
- ```bash
9
- npm install -D @critiq/cli @critiq/rules
10
- npx critiq check .
11
- ```
12
-
13
- It is designed for two equally important modes:
14
-
15
- - manual invocation while a developer is authoring, debugging, or reviewing a rule
16
- - automated invocation in CI to increase confidence in a PR or run a broader repository scan
17
-
18
- Use it when you want to:
19
-
20
- - run rules against real repository code or a PR diff
21
- - validate authored rules before committing them
22
- - explain how a rule is interpreted
23
- - normalize a rule into the canonical internal form
24
- - run fixture-based `RuleSpec` tests for a rule pack
25
- - use the same deterministic checks locally and in automation
26
-
27
- The CLI now has two modes:
28
-
29
- - `critiq check` is catalog-first and loads rules from `.critiq/config.yaml`
30
- - `critiq rules ...` commands remain path-based for pack authors and maintainers
31
-
32
- If you want to run the built CLI from `dist/`, use:
33
-
34
- ```bash
35
- npm run build:release-cli
36
- node dist/publish/cli/main.js --help
37
- ```
38
-
39
- `dist/publish/cli` is the self-contained npm release artifact for
40
- `@critiq/cli`.
41
-
42
- ## Recommended Project Layout
43
-
44
- A common consumer setup is:
45
-
46
- ```text
47
- .critiq/
48
- config.yaml
49
- ```
50
-
51
- with:
52
-
53
- ```yaml
54
- apiVersion: critiq.dev/v1alpha1
55
- kind: CritiqConfig
56
- catalog:
57
- package: "@critiq/rules"
58
- preset: recommended
59
- disableRules: []
60
- disableCategories: []
61
- disableLanguages: []
62
- includeTests: false
63
- ignorePaths: []
64
- severityOverrides: {}
65
- ```
66
-
67
- If you are authoring your own rules, a common convention is:
68
-
69
- ```text
70
- .critiq/
71
- rules/
72
- no-console.rule.yaml
73
- no-console.spec.yaml
74
- fixtures/
75
- no-console/
76
- valid.ts
77
- invalid.ts
78
- ```
79
-
80
- This is only a convention. Authoring commands work with any file path or glob
81
- you give them, so you can also:
82
-
83
- - keep rules in another local folder
84
- - vendor a shared rule pack into your repo
85
- - install a rule pack and reference it from `.critiq/config.yaml`
86
-
87
- ## Commands
88
-
89
- - `critiq check [target]`
90
- - `critiq rules validate <glob>`
91
- - `critiq rules test [glob]`
92
- - `critiq rules normalize <file>`
93
- - `critiq rules explain <file>`
94
-
95
- ## What Each Command Is For
96
-
97
- ### `check`
98
-
99
- Use this to run the configured catalog against real source files in a
100
- repository.
101
-
102
- This is the runtime/CI entrypoint when you want Critiq to inspect application
103
- code rather than validate or test the rule pack itself. `check` reads
104
- `.critiq/config.yaml`, resolves the configured catalog package, applies preset
105
- selection and subtractive overrides, auto-detects repository languages from
106
- supported source files, and evaluates the active rules.
107
-
108
- Today that means:
109
-
110
- - deepest support for TypeScript and JavaScript
111
- - early phase-1 adapter coverage for Go, Java, PHP, Python, Ruby, and Rust
112
- - tests excluded from `check` by default unless `includeTests: true`
113
-
114
- Examples:
115
16
 
116
- ```bash
117
- critiq check
118
- critiq check . --format json
119
- critiq check . --base origin/main --head HEAD --format json
120
- ```
17
+ Think of Critiq as an extra code reviewer that scans your project for bugs, security issues, performance problems, and risky changes before they turn into production incidents. Instead of only checking style, it focuses on the kinds of problems that usually slip through review and cause real trouble later. You run it locally or in CI, and it gives you deterministic findings you can act on before merging code.
121
18
 
122
- Migration:
123
19
 
124
- ```bash
125
- # old
126
- critiq check ".critiq/rules/*.rule.yaml" .
20
+ It does this by parsing your code, matching it against a curated catalog of explicit rules, and reporting findings with concrete evidence tied to the code that triggered them. That means the output is based on repeatable checks for things like unsafe SQL, missing authorization, repeated IO in loops, and untested critical logic changes, not vague heuristics or style-only linting.
127
21
 
128
- # new
129
- critiq check .
130
- ```
22
+ <p align="center">
23
+ <img
24
+ src="https://raw.githubusercontent.com/critiq-dev/critiq-core/main/docs/assets/cli-architecture-transparent.png"
25
+ alt="Cli Architecture"
26
+ />
27
+ </p>
131
28
 
132
- ### `validate`
29
+ `@critiq/cli` runs Critiq checks against real code and exposes the public rule-pack commands for validation, testing, normalization, and explanation. By default it uses [`@critiq/rules`](https://www.npmjs.com/package/@critiq/rules) as the open source catalog with recommended rules. You can configure this by adding a `.critiq/config.yaml` configuration file.
133
30
 
134
- Use this while authoring rules.
31
+ <br/>
32
+ <p align="left">
33
+ <img
34
+ src="https://raw.githubusercontent.com/critiq-dev/critiq-core/main/docs/assets/languages.png"
35
+ alt="TypeScript, JavaScript, Node.js, Go, Java, Python, PHP, Ruby and Rust support"
36
+ />
37
+ </p>
135
38
 
136
- It loads the YAML, validates the public contract, runs semantic validation, and
137
- returns diagnostics only.
39
+ `@critiq/cli` is capable of scanning codebases written in TypeScript, JavaScript, Node.js, Go, Java, Python, PHP, Ruby, and Rust.
138
40
 
139
- This is the command you would commonly use in a PR-focused workflow to make
140
- sure authored rules are valid before the rules are executed elsewhere.
41
+ ## Start In 60 Seconds
141
42
 
142
- Examples:
43
+ Run Critiq on your project:
143
44
 
144
45
  ```bash
145
- critiq rules validate ".critiq/rules/*.rule.yaml"
146
- critiq rules validate "packages/my-pack/rules/*.rule.yaml"
46
+ npm install -D @critiq/cli @critiq/rules
47
+ npx critiq check .
147
48
  ```
148
49
 
149
- ### `test`
150
-
151
- Use this to run `RuleSpec` fixtures and prove rule behavior end to end.
152
-
153
- This is the command that gives you confidence that a rule pack behaves the way
154
- you expect before using it in an automated PR check or a repository scan.
155
-
156
- If you omit the glob, it defaults to `**/*.spec.yaml` from the current working
157
- directory.
158
-
159
- Examples:
50
+ Run Critiq against a diff:
160
51
 
161
52
  ```bash
162
- critiq rules test
163
- critiq rules test ".critiq/rules/*.spec.yaml"
53
+ npx critiq check . --base origin/main --head HEAD
164
54
  ```
165
55
 
166
- ### `normalize`
167
-
168
- Use this when you want to inspect the canonical normalized IR for one rule.
169
-
170
- Example:
56
+ ## GitHub Actions
171
57
 
172
- ```bash
173
- critiq rules normalize .critiq/rules/no-console.rule.yaml --format json
174
- ```
58
+ To run the same checks on **pull requests** in GitHub Actions—with optional **inline PR review comments** and severity-based merge gates—use the official composite action **[critiq-dev/critiq-action](https://github.com/critiq-dev/critiq-action)** ([README](https://github.com/critiq-dev/critiq-action/blob/main/README.md)). The action wraps `critiq check`, honors `.critiq/config.yaml`, and can install published `@critiq/cli` / `@critiq/rules` when they are not already declared on the repository root `package.json`.
175
59
 
176
- ### `explain`
60
+ Example `.github/workflows/critiq.yml`:
177
61
 
178
- Use this when you want a readable breakdown of:
62
+ ```yaml
63
+ name: Critiq
179
64
 
180
- - parsed rule metadata
181
- - validation status
182
- - normalized rule content
183
- - inferred template variables
65
+ on:
66
+ pull_request:
184
67
 
185
- Example:
68
+ permissions:
69
+ contents: read
70
+ pull-requests: write
186
71
 
187
- ```bash
188
- critiq rules explain .critiq/rules/no-console.rule.yaml
72
+ jobs:
73
+ critiq:
74
+ runs-on: ubuntu-latest
75
+ steps:
76
+ - name: Checkout
77
+ uses: actions/checkout@v4
78
+ with:
79
+ fetch-depth: 0
80
+
81
+ - name: Run Critiq
82
+ uses: critiq-dev/critiq-action@v1
83
+ with:
84
+ fail-on-severity: off
189
85
  ```
190
86
 
191
- ## Flags
87
+ Use a **major tag** (`@v1`) or pin a **commit SHA** for supply-chain control. More options (inputs, outputs, monorepos, reusable workflow) are in the [action README](https://github.com/critiq-dev/critiq-action/blob/main/README.md).
192
88
 
193
- - `--format pretty|json`
194
- - `--help`
89
+ ## Public Commands
195
90
 
196
- `pretty` is the default.
91
+ `critiq check` also runs an **advisory** built-in secret scan (same scope as the rule engine, plus optional `--staged` for index-only staging review) and prints a short summary before rule results. That scan does **not** change the `critiq check` exit code; use `critiq audit secrets` for full output and for gating in CI.
197
92
 
198
- ## Exit Codes
93
+ **What "staged review" means**
199
94
 
200
- - `0`: success
201
- - `1`: findings or non-internal command failures
202
- - `2`: internal/runtime errors
95
+ - "Staged" means Git index content (what `git add` has queued), not all local edits.
96
+ - Critiq reads staged content the same way Git does for commit previews (`git diff --cached`).
97
+ - Use this when you want pre-commit checks to match exactly what will be committed.
203
98
 
204
- ## Typical Developer Workflow
99
+ | Command | What it does |
100
+ | --- | --- |
101
+ | `critiq check [target]` | Runs deterministic checks against a codebase, directory, or single file. |
102
+ | `critiq check . --base origin/main --head HEAD` | Limits scanning to changed files and changed ranges in a diff. |
103
+ | `critiq check . --staged` | Rule scan unchanged; the advisory secret scan reads only what is staged in Git index (`git diff --cached`). |
104
+ | `critiq check . --format sarif` | Exports findings as SARIF 2.1.0 for code scanning and security platforms. |
105
+ | `critiq check . --format html` | Exports a shareable HTML report for human review and audit handoff. |
106
+ | `critiq audit secrets [target]` | Runs the dedicated secret-pattern scanner (exit non-zero when matches are found). |
107
+ | `critiq audit secrets . --base origin/main --head HEAD` | Secret scan over changed files only (includes non-code paths such as `.env`). |
108
+ | `critiq audit secrets . --staged` | Secret scan over staged paths/blobs from Git index (`git diff --cached`) (pre-commit friendly). |
109
+ | `critiq audit` / `critiq audit --help` | Lists audit subcommands. |
110
+ | `critiq rules validate <glob>` | Validates rule YAML files and returns diagnostics. |
111
+ | `critiq rules test [glob]` | Runs fixture-backed `RuleSpec` files end to end. |
112
+ | `critiq rules normalize <file>` | Prints the canonical normalized form of one rule. |
113
+ | `critiq rules explain <file>` | Shows a readable breakdown of how one rule is interpreted. |
205
114
 
206
- Authoring a new rule:
115
+ ## Runtime Config
207
116
 
208
- ```bash
209
- npm run nx -- run cli:prune
210
- critiq rules validate ".critiq/rules/*.rule.yaml"
211
- critiq rules explain .critiq/rules/no-console.rule.yaml
212
- critiq rules test ".critiq/rules/*.spec.yaml"
213
- ```
214
-
215
- Working from the separate `critiq-rules` repo:
216
-
217
- ```bash
218
- npm run nx -- run cli:prune
219
- critiq rules validate "../critiq-rules/examples/starter-pack/rules/*.rule.yaml"
220
- critiq rules explain ../critiq-rules/examples/starter-pack/rules/ts.logging.no-console-log.rule.yaml
221
- critiq rules test "../critiq-rules/examples/starter-pack/rules/*.spec.yaml"
222
- ```
223
-
224
- Running in automation:
225
-
226
- ```bash
227
- npm run nx -- run cli:prune
228
- critiq check . --format json
229
- critiq rules validate ".critiq/rules/*.rule.yaml" --format json
230
- critiq rules test ".critiq/rules/*.spec.yaml" --format json
231
- ```
232
-
233
- ### Reusable GitHub Workflow
234
-
235
- Consumer repositories can call the reusable workflow published from this repo
236
- instead of copying the CLI setup into every workflow file.
237
-
238
- Example:
117
+ `critiq check` is catalog-first. When `.critiq/config.yaml` is present, it controls the catalog package, preset, and filters used for the run.
239
118
 
240
119
  ```yaml
241
- jobs:
242
- critiq:
243
- uses: critiq-dev/critiq-core/.github/workflows/run-critiq-cli.yml@ref
244
- with:
245
- critiq-version: x.y.z
246
- run-check: true
247
- check-target: .
248
- check-base: origin/main
249
- check-head: HEAD
250
- validate-glob: .critiq/rules/*.rule.yaml
251
- test-glob: .critiq/rules/*.spec.yaml
120
+ apiVersion: critiq.dev/v1alpha1
121
+ kind: CritiqConfig
122
+ catalog:
123
+ package: "@critiq/rules"
124
+ preset: recommended
125
+ disableRules: []
126
+ disableCategories: []
127
+ disableLanguages: []
128
+ includeTests: false
129
+ ignorePaths: []
130
+ severityOverrides: {}
252
131
  ```
253
132
 
254
- The workflow:
255
-
256
- - checks out the consumer repository
257
- - installs Node.js
258
- - installs the requested `@critiq/cli` package version
259
- - optionally runs `check`, `validate`, and `test` with JSON output
260
- - uploads the JSON results as workflow artifacts
261
-
262
- For production use, pin both the workflow ref and `critiq-version`.
263
-
264
- ## JSON Output
133
+ Supported presets are `recommended`, `strict`, `security`, and `experimental`.
265
134
 
266
- All commands support `--format json`.
135
+ Optional `secretsScan` in the same file merges extra `ignorePaths` (in addition to top-level `ignorePaths`), disables individual detectors by id (match the `detectorId` field in JSON output; published ids are exported as `SECRETS_SCAN_DETECTOR_IDS` from `@critiq/check-runner`), and drops findings listed under `suppressFingerprints` (64 lowercase hex characters from JSON `fingerprint`).
267
136
 
268
- That makes the CLI usable as:
137
+ ## Git hooks
269
138
 
270
- - a terminal tool for humans
271
- - a machine-readable step in CI
272
- - a building block for custom wrappers
139
+ Sample scripts ship under `scripts/hooks/` in this package (for example `pre-commit.sample.sh` runs `critiq audit secrets . --staged`; `pre-push.sample.sh` runs a diff against `origin/main` or `CRITIQ_PRE_PUSH_BASE`). Copy one to `.git/hooks/` and mark it executable, or wire the same commands into Husky.
273
140
 
274
- That means the same CLI can sit behind:
141
+ ## Default OSS Rule Catalog
275
142
 
276
- - a developer manually checking a rule before commit
277
- - a repository or PR gate that emits findings from real source files
278
- - a PR workflow that wants confidence before merge
279
- - a scheduled or on-demand full repository scan
143
+ The default open source catalog in [`@critiq/rules`](https://www.npmjs.com/package/@critiq/rules) currently includes `112` rules across `10` categories.
280
144
 
281
- See [docs/reference/cli.md](../../docs/reference/cli.md) for the envelope
282
- shapes.
145
+ | Category | Rules | What it looks after |
146
+ | --- | ---: | --- |
147
+ | Security | 70 | Injection, auth and session gaps, unsafe transport, sensitive data exposure, unsafe file and HTML handling |
148
+ | Correctness | 15 | Async bugs, null access, control-flow mistakes, missing fallbacks, race conditions |
149
+ | Performance | 10 | Repeated IO, wasted async sequencing, hot-path loops, large retained objects, render churn |
150
+ | Quality | 10 | Error handling gaps, oversized functions, coupling, duplicated logic, and weak test coverage |
151
+ | Logging | 2 | Console usage and unsafe logging patterns |
152
+ | Config | 1 | Configuration access boundaries |
153
+ | Next | 1 | Server and client boundary leaks |
154
+ | Random | 1 | Unsafe randomness in core logic |
155
+ | React | 1 | Cascaded effect fetch patterns |
156
+ | Runtime | 1 | Debug-only statements left in shipped code |
283
157
 
284
- ## Relationship To The Rest Of The Repo
158
+ ## High-Value Rules In The Default Catalog
285
159
 
286
- The CLI is intentionally thin. It composes the OSS packages rather than
287
- re-implementing their logic.
160
+ | Rule title | Description |
161
+ | --- | --- |
162
+ | `Hardcoded API keys or credentials` | Source files should not embed credential-like string literals. |
163
+ | `Avoid raw or interpolated SQL`| Database query sinks must not receive request-driven or dynamically interpolated SQL text. |
164
+ | `Path traversal via user input` | File access calls must not use request-controlled paths directly. |
165
+ | `Protect deserialization trust boundaries`| Deserializers should not consume untrusted payloads directly across a trust boundary. |
166
+ | `Server-side request forgery` (`ts.security.ssrf`) | Outbound requests should not use attacker-controlled targets or private hosts. |
167
+ | `Open redirect via request-controlled target`| Redirect and navigation sinks should not use request-controlled destinations without validation. |
168
+ | `Missing authorization before sensitive action` | Sensitive backend actions should be guarded by an authorization or permission check. |
169
+ | `Use authenticated encryption for secrets and tokens` | Session, cookie, and token encryption should provide integrity protection in the same helper. |
170
+ | `Missing await on async call` | Async functions should not drop direct async calls without awaiting them. |
171
+ | `Repeated IO call inside loop` | Database or network calls inside loops can multiply latency and load. |
172
+ | `Logic change without corresponding test updates` | Diffs that change critical logic should usually update the matching tests in the same change. |
173
+ | `Avoid server/client boundary leaks in Next.js` | Server components should not use browser-only APIs or client-only hooks without an explicit client boundary. |
288
174
 
289
- - repository scanning comes from `@critiq/check-runner`
290
- - adapter-backed source analysis comes from `@critiq/adapter-typescript`
291
- - rule loading and validation come from `@critiq/core-rules-dsl`
292
- - normalization comes from `@critiq/core-ir`
293
- - diagnostics rendering comes from `@critiq/core-diagnostics`
294
- - fixture-based testing comes from `@critiq/testing-harness`
175
+ ## Reference
295
176
 
296
- That means you can use the CLI directly, or use the underlying packages inside
297
- your own tooling if you need more control.
177
+ - [Getting started](https://github.com/critiq-dev/critiq-core/blob/main/docs/guides/getting-started.md)
178
+ - [CLI reference](https://github.com/critiq-dev/critiq-core/blob/main/docs/reference/cli.md)
179
+ - [`@critiq/rules` package](https://www.npmjs.com/package/@critiq/rules)
180
+ - [Critiq GitHub Action](https://github.com/critiq-dev/critiq-action/blob/main/README.md) (CI and PR comments)
298
181
 
299
- ## Development Commands
182
+ ## License
300
183
 
301
- - `npm run nx -- build cli`
302
- - `npm run nx -- run cli:prune`
303
- - `npm run nx -- test cli`
304
- - `npm run nx -- lint cli`
305
- - `npm run nx -- typecheck cli`
184
+ `@critiq/cli` is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). See the source [LICENSE](https://github.com/critiq-dev/critiq-core/blob/main/LICENSE).