critical-gate 2.3.1 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -35
- package/dist/agent-onboarding/agent-instructions.d.ts.map +1 -1
- package/dist/agent-onboarding/agent-instructions.js +2 -2
- package/dist/agent-onboarding/agent-instructions.js.map +1 -1
- package/dist/cli/args.d.ts +57 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +209 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/commands.d.ts +8 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +170 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/entrypoint.d.ts +2 -0
- package/dist/cli/entrypoint.d.ts.map +1 -0
- package/dist/cli/entrypoint.js +18 -0
- package/dist/cli/entrypoint.js.map +1 -0
- package/dist/cli/git-hooks.d.ts +2 -0
- package/dist/cli/git-hooks.d.ts.map +1 -0
- package/dist/cli/git-hooks.js +31 -0
- package/dist/cli/git-hooks.js.map +1 -0
- package/dist/cli/help.d.ts +4 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +151 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/io.d.ts +3 -0
- package/dist/cli/io.d.ts.map +1 -0
- package/dist/cli/io.js +16 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/main.d.ts +4 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +76 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/result.d.ts +4 -0
- package/dist/cli/result.d.ts.map +1 -0
- package/dist/cli/result.js +107 -0
- package/dist/cli/result.js.map +1 -0
- package/dist/cli/types.d.ts +30 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli.d.ts +5 -18
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -759
- package/dist/cli.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -217,7 +217,7 @@ Critical Gate has one analysis core and multiple surfaces:
|
|
|
217
217
|
- **Codex hook**: repair-oriented stop hook for agent workflows.
|
|
218
218
|
- **VS Code extension**: Activity Bar dashboard, status bar state, Problems diagnostics, full report
|
|
219
219
|
output, evidence navigation, and repair-copy actions.
|
|
220
|
-
- **Agent onboarding**: `critical-gate init-agent` and the VS Code initialization command add a
|
|
220
|
+
- **Agent onboarding**: `npx critical-gate init-agent` and the VS Code initialization command add a
|
|
221
221
|
managed Critical Gate section to `AGENTS.md` while preserving existing repository instructions.
|
|
222
222
|
|
|
223
223
|
The CLI remains the source of truth. The editor and CI surfaces consume CLI output rather than
|
|
@@ -241,44 +241,44 @@ Recommended sequence:
|
|
|
241
241
|
See [docs/usage-guide.md](docs/usage-guide.md) for local rollout advice and
|
|
242
242
|
[docs/github-integration.md](docs/github-integration.md) for CI thresholds.
|
|
243
243
|
|
|
244
|
-
## Quick Start
|
|
244
|
+
## Quick Start
|
|
245
245
|
|
|
246
|
-
Critical Gate
|
|
247
|
-
`node dist/cli.js`. Package-registry publishing and prebuilt action releases are intentionally held
|
|
248
|
-
until repository metadata, external dogfooding, and release artifacts are stable enough for broader
|
|
249
|
-
public use.
|
|
246
|
+
Run Critical Gate directly against the current repository diff:
|
|
250
247
|
|
|
251
248
|
Requirements:
|
|
252
249
|
|
|
253
|
-
- Node.js
|
|
254
|
-
- pnpm 11.1.2.
|
|
250
|
+
- Node.js 20 or newer.
|
|
255
251
|
- Git history for baseline comparisons.
|
|
256
252
|
|
|
257
253
|
```bash
|
|
258
|
-
|
|
259
|
-
cd critical-gate
|
|
260
|
-
pnpm install --frozen-lockfile
|
|
261
|
-
pnpm build
|
|
254
|
+
npx critical-gate check --task "Add signup validation" --base main --format markdown
|
|
262
255
|
```
|
|
263
256
|
|
|
264
|
-
|
|
257
|
+
With pnpm:
|
|
265
258
|
|
|
266
259
|
```bash
|
|
267
|
-
|
|
260
|
+
pnpm dlx critical-gate check --task "Add signup validation" --base main --format markdown
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
Install it in a repository for repeated local and CI use:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npm install -D critical-gate
|
|
267
|
+
npx critical-gate check --task "Add signup validation" --base main
|
|
268
268
|
```
|
|
269
269
|
|
|
270
270
|
Common output formats:
|
|
271
271
|
|
|
272
272
|
```bash
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
npx critical-gate check --task "Add signup validation" --format json --output critical-gate.json
|
|
274
|
+
npx critical-gate check --task "Add signup validation" --format sarif --output critical-gate.sarif
|
|
275
|
+
npx critical-gate check --task "Add signup validation" --format repair
|
|
276
276
|
```
|
|
277
277
|
|
|
278
278
|
Create a public API contract snapshot for repositories that expose TS/JS entrypoints:
|
|
279
279
|
|
|
280
280
|
```bash
|
|
281
|
-
|
|
281
|
+
npx critical-gate snapshot-api
|
|
282
282
|
git add .critical-gate/api-surface.json
|
|
283
283
|
```
|
|
284
284
|
|
|
@@ -293,12 +293,29 @@ Exit codes:
|
|
|
293
293
|
- `2`: usage or configuration error.
|
|
294
294
|
- `3`: internal error.
|
|
295
295
|
|
|
296
|
+
## Development From Source
|
|
297
|
+
|
|
298
|
+
Contributors who are changing Critical Gate itself should use the source workflow:
|
|
299
|
+
|
|
300
|
+
Requirements:
|
|
301
|
+
|
|
302
|
+
- Node.js 20 or newer.
|
|
303
|
+
- pnpm 10.34.4.
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
git clone git@github.com:criticaldeveloper/critical-gate.git
|
|
307
|
+
cd critical-gate
|
|
308
|
+
pnpm install --frozen-lockfile
|
|
309
|
+
pnpm build
|
|
310
|
+
node dist/cli.js check --task "Add signup validation" --base main --format markdown
|
|
311
|
+
```
|
|
312
|
+
|
|
296
313
|
## Task Intent And Baselines
|
|
297
314
|
|
|
298
315
|
The task intent tells the gate what the diff is supposed to satisfy. Good task text is specific:
|
|
299
316
|
|
|
300
317
|
```bash
|
|
301
|
-
|
|
318
|
+
npx critical-gate check \
|
|
302
319
|
--task "Add email validation to signup form without changing authentication flow" \
|
|
303
320
|
--base origin/main \
|
|
304
321
|
--format markdown
|
|
@@ -336,7 +353,7 @@ jobs:
|
|
|
336
353
|
fetch-depth: 0
|
|
337
354
|
|
|
338
355
|
- id: critical-gate
|
|
339
|
-
uses:
|
|
356
|
+
uses: criticaldeveloper/critical-gate@v2
|
|
340
357
|
continue-on-error: true
|
|
341
358
|
with:
|
|
342
359
|
task: ${{ github.event.pull_request.title }}
|
|
@@ -361,8 +378,7 @@ Critical Gate can run as a Codex `Stop` hook so an agent receives compact repair
|
|
|
361
378
|
task is considered complete.
|
|
362
379
|
|
|
363
380
|
```bash
|
|
364
|
-
|
|
365
|
-
node dist/cli.js hook --base main
|
|
381
|
+
npx critical-gate hook --base main
|
|
366
382
|
```
|
|
367
383
|
|
|
368
384
|
This repository includes `.codex/hooks.json` as a reviewable project hook example. See
|
|
@@ -370,17 +386,9 @@ This repository includes `.codex/hooks.json` as a reviewable project hook exampl
|
|
|
370
386
|
|
|
371
387
|
## VS Code Extension
|
|
372
388
|
|
|
373
|
-
|
|
389
|
+
Install the Marketplace extension:
|
|
374
390
|
|
|
375
|
-
|
|
376
|
-
pnpm package:vscode
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
Install locally:
|
|
380
|
-
|
|
381
|
-
```bash
|
|
382
|
-
code --install-extension artifacts/vscode/critical-gate-vscode.vsix --force
|
|
383
|
-
```
|
|
391
|
+
[Critical Gate for VS Code](https://marketplace.visualstudio.com/items?itemName=criticaldeveloper.critical-gate-vscode)
|
|
384
392
|
|
|
385
393
|
The extension adds:
|
|
386
394
|
|
|
@@ -438,7 +446,8 @@ Branch and commit conventions for this repository:
|
|
|
438
446
|
- [docs/detector-quality.md](docs/detector-quality.md): detector quality boundaries, blind spots,
|
|
439
447
|
and coverage expectations.
|
|
440
448
|
- [docs/usage-guide.md](docs/usage-guide.md): practical usage examples and troubleshooting.
|
|
441
|
-
- [docs/installation.md](docs/installation.md): CLI, GitHub Action, Codex hook, and
|
|
449
|
+
- [docs/installation.md](docs/installation.md): CLI, GitHub Action, Codex hook, and VS Code
|
|
450
|
+
installation.
|
|
442
451
|
- [docs/editor-surface.md](docs/editor-surface.md): VS Code dashboard and diagnostics behavior.
|
|
443
452
|
- [docs/github-integration.md](docs/github-integration.md): GitHub Action, SARIF, and threshold guidance.
|
|
444
453
|
- [docs/policy-file.md](docs/policy-file.md): `.critical-gate.json` policy-as-code reference and
|
|
@@ -458,8 +467,8 @@ Branch and commit conventions for this repository:
|
|
|
458
467
|
## Project Status
|
|
459
468
|
|
|
460
469
|
The repository contains the TypeScript CLI implementation, deterministic detectors, Codex hook
|
|
461
|
-
integration, GitHub Action integration, optional LLM explanation boundaries,
|
|
462
|
-
|
|
470
|
+
integration, GitHub Action integration, optional LLM explanation boundaries, npm CLI distribution,
|
|
471
|
+
and a VS Code Marketplace extension surface.
|
|
463
472
|
|
|
464
473
|
## License
|
|
465
474
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../src/agent-onboarding/agent-instructions.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,cAAc,CAAC;AAQnD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,EAAE,EAAE,mBAAmB,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,
|
|
1
|
+
{"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../src/agent-onboarding/agent-instructions.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,uBAAuB,cAAc,CAAC;AAQnD,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACnC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,EAAE,EAAE,mBAAmB,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,IAAI,EACJ,UAAgC,EAChC,qBAA4B,EAC5B,EAAE,EACH,EAAE,4BAA4B,GAAG,2BAA2B,CAgB5D;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAcnF;AAED,wBAAgB,4BAA4B,CAC1C,UAAU,SAAsB,EAChC,qBAAqB,UAAO,GAC3B,MAAM,CAkCR"}
|
|
@@ -3,7 +3,7 @@ export const AGENT_INSTRUCTIONS_FILE = "AGENTS.md";
|
|
|
3
3
|
const blockStart = "<!-- critical-gate:start -->";
|
|
4
4
|
const blockEnd = "<!-- critical-gate:end -->";
|
|
5
5
|
const managedBlockPattern = new RegExp(`${escapeRegExp(blockStart)}[\\s\\S]*?${escapeRegExp(blockEnd)}`);
|
|
6
|
-
export function initAgentInstructions({ root, cliCommand = "critical-gate", includePolicyReminder = true, io }) {
|
|
6
|
+
export function initAgentInstructions({ root, cliCommand = "npx critical-gate", includePolicyReminder = true, io }) {
|
|
7
7
|
const path = join(root, AGENT_INSTRUCTIONS_FILE);
|
|
8
8
|
const existing = io.exists?.(path) === true ? (io.readFile?.(path) ?? "") : "";
|
|
9
9
|
const block = renderCriticalGateAgentBlock(cliCommand, includePolicyReminder);
|
|
@@ -29,7 +29,7 @@ export function mergeCriticalGateAgentBlock(existing, block) {
|
|
|
29
29
|
}
|
|
30
30
|
return `${trimmedExisting}\n\n${normalizedBlock}`;
|
|
31
31
|
}
|
|
32
|
-
export function renderCriticalGateAgentBlock(cliCommand = "critical-gate", includePolicyReminder = true) {
|
|
32
|
+
export function renderCriticalGateAgentBlock(cliCommand = "npx critical-gate", includePolicyReminder = true) {
|
|
33
33
|
const lines = [
|
|
34
34
|
blockStart,
|
|
35
35
|
"## Critical Gate Agent Instructions",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../src/agent-onboarding/agent-instructions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;AAEnD,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAClD,MAAM,QAAQ,GAAG,4BAA4B,CAAC;AAC9C,MAAM,mBAAmB,GAAG,IAAI,MAAM,CACpC,GAAG,YAAY,CAAC,UAAU,CAAC,aAAa,YAAY,CAAC,QAAQ,CAAC,EAAE,CACjE,CAAC;AAqBF,MAAM,UAAU,qBAAqB,CAAC,EACpC,IAAI,EACJ,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../src/agent-onboarding/agent-instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { CommandName } from "./help.js";
|
|
2
|
+
import type { CheckOptions } from "./types.js";
|
|
3
|
+
export declare function parseCheckArgs(args: string[], command: CommandName): {
|
|
4
|
+
ok: true;
|
|
5
|
+
options: CheckOptions;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
error: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function isCommandName(value: string): value is CommandName;
|
|
11
|
+
export declare function parseFlagArgs(args: string[], allowedFlags: string[]): {
|
|
12
|
+
ok: true;
|
|
13
|
+
values: Record<string, string>;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
error: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseSnapshotApiArgs(args: string[]): {
|
|
19
|
+
ok: true;
|
|
20
|
+
options: {
|
|
21
|
+
output?: string;
|
|
22
|
+
entrypoints?: string[];
|
|
23
|
+
};
|
|
24
|
+
} | {
|
|
25
|
+
ok: false;
|
|
26
|
+
error: string;
|
|
27
|
+
};
|
|
28
|
+
export declare function parseInstallHooksArgs(args: string[]): {
|
|
29
|
+
ok: true;
|
|
30
|
+
options: {
|
|
31
|
+
hook: "pre-commit" | "pre-push" | "all";
|
|
32
|
+
cli: string;
|
|
33
|
+
force: boolean;
|
|
34
|
+
};
|
|
35
|
+
} | {
|
|
36
|
+
ok: false;
|
|
37
|
+
error: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function parseInitPolicyArgs(args: string[]): {
|
|
40
|
+
ok: true;
|
|
41
|
+
options: {
|
|
42
|
+
force: boolean;
|
|
43
|
+
};
|
|
44
|
+
} | {
|
|
45
|
+
ok: false;
|
|
46
|
+
error: string;
|
|
47
|
+
};
|
|
48
|
+
export declare function parseInitAgentArgs(args: string[]): {
|
|
49
|
+
ok: true;
|
|
50
|
+
options: {
|
|
51
|
+
cli: string;
|
|
52
|
+
};
|
|
53
|
+
} | {
|
|
54
|
+
ok: false;
|
|
55
|
+
error: string;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,EAAE,WAAW,GAElB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE,YAAY,CAAC;CACvB,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CA2FJ;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAWjE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EAAE,EACd,YAAY,EAAE,MAAM,EAAE,GAEpB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAqBJ;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAC/C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC;CACH,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAqCJ;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAChD;IACE,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE;QACP,IAAI,EAAE,YAAY,GAAG,UAAU,GAAG,KAAK,CAAC;QACxC,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;CACH,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAuCJ;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAC9C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE;QACP,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;CACH,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAcJ;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAC7C;IACE,EAAE,EAAE,IAAI,CAAC;IACT,OAAO,EAAE;QACP,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf,CAuBJ"}
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
export function parseCheckArgs(args, command) {
|
|
2
|
+
const options = {
|
|
3
|
+
format: "markdown",
|
|
4
|
+
strict: false,
|
|
5
|
+
staged: false
|
|
6
|
+
};
|
|
7
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
8
|
+
const arg = args[index];
|
|
9
|
+
if (arg === "--strict") {
|
|
10
|
+
options.strict = true;
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
if (arg === "--staged") {
|
|
14
|
+
options.staged = true;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (arg === "--task" ||
|
|
18
|
+
arg === "--base" ||
|
|
19
|
+
arg === "--format" ||
|
|
20
|
+
arg === "--output" ||
|
|
21
|
+
arg === "--fail-on") {
|
|
22
|
+
const value = args[index + 1];
|
|
23
|
+
if (value === undefined || value.startsWith("--")) {
|
|
24
|
+
return { ok: false, error: `Missing value for ${arg}.` };
|
|
25
|
+
}
|
|
26
|
+
index += 1;
|
|
27
|
+
if (arg === "--task") {
|
|
28
|
+
options.task = value;
|
|
29
|
+
}
|
|
30
|
+
else if (arg === "--base") {
|
|
31
|
+
options.base = value;
|
|
32
|
+
}
|
|
33
|
+
else if (arg === "--format") {
|
|
34
|
+
if (!isReportFormat(value)) {
|
|
35
|
+
return {
|
|
36
|
+
ok: false,
|
|
37
|
+
error: "Invalid --format value. Expected json, markdown, sarif, repair, or pr-comment."
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
options.format = value;
|
|
41
|
+
}
|
|
42
|
+
else if (arg === "--fail-on") {
|
|
43
|
+
if (!isFailOnSeverity(value)) {
|
|
44
|
+
return {
|
|
45
|
+
ok: false,
|
|
46
|
+
error: "Invalid --fail-on value. Expected blocker, high, or medium."
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
options.failOn = value;
|
|
50
|
+
}
|
|
51
|
+
else if (arg === "--output") {
|
|
52
|
+
options.output = value;
|
|
53
|
+
}
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
return { ok: false, error: `Unknown option: ${arg}` };
|
|
57
|
+
}
|
|
58
|
+
if (options.task === undefined || options.task.trim().length === 0) {
|
|
59
|
+
if (command === "hook") {
|
|
60
|
+
options.task = "Codex completed feature implementation";
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
return { ok: false, error: "Missing required --task value." };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (options.task.trim().length === 0) {
|
|
67
|
+
return { ok: false, error: "Missing required --task value." };
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
ok: true,
|
|
71
|
+
options: {
|
|
72
|
+
task: options.task,
|
|
73
|
+
base: options.base,
|
|
74
|
+
format: options.format ?? "markdown",
|
|
75
|
+
strict: options.strict ?? false,
|
|
76
|
+
staged: options.staged ?? false,
|
|
77
|
+
failOn: options.failOn,
|
|
78
|
+
output: options.output
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export function isCommandName(value) {
|
|
83
|
+
return (value === "check" ||
|
|
84
|
+
value === "hook" ||
|
|
85
|
+
value === "accept" ||
|
|
86
|
+
value === "teach" ||
|
|
87
|
+
value === "snapshot-api" ||
|
|
88
|
+
value === "install-hooks" ||
|
|
89
|
+
value === "init-policy" ||
|
|
90
|
+
value === "init-agent");
|
|
91
|
+
}
|
|
92
|
+
export function parseFlagArgs(args, allowedFlags) {
|
|
93
|
+
const values = {};
|
|
94
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
95
|
+
const arg = args[index];
|
|
96
|
+
if (!allowedFlags.includes(arg)) {
|
|
97
|
+
return { ok: false, error: `Unknown option: ${arg}.` };
|
|
98
|
+
}
|
|
99
|
+
const value = args[index + 1];
|
|
100
|
+
if (value === undefined || value.startsWith("--")) {
|
|
101
|
+
return { ok: false, error: `Missing value for ${arg}.` };
|
|
102
|
+
}
|
|
103
|
+
values[arg] = value;
|
|
104
|
+
index += 1;
|
|
105
|
+
}
|
|
106
|
+
return { ok: true, values };
|
|
107
|
+
}
|
|
108
|
+
export function parseSnapshotApiArgs(args) {
|
|
109
|
+
const options = {
|
|
110
|
+
entrypoints: []
|
|
111
|
+
};
|
|
112
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
113
|
+
const arg = args[index];
|
|
114
|
+
if (arg !== "--entrypoint" && arg !== "--output") {
|
|
115
|
+
return { ok: false, error: `Unknown option: ${arg}.` };
|
|
116
|
+
}
|
|
117
|
+
const value = args[index + 1];
|
|
118
|
+
if (value === undefined || value.startsWith("--")) {
|
|
119
|
+
return { ok: false, error: `Missing value for ${arg}.` };
|
|
120
|
+
}
|
|
121
|
+
if (arg === "--entrypoint") {
|
|
122
|
+
options.entrypoints.push(value);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
options.output = value;
|
|
126
|
+
}
|
|
127
|
+
index += 1;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
ok: true,
|
|
131
|
+
options: {
|
|
132
|
+
output: options.output,
|
|
133
|
+
entrypoints: options.entrypoints.length > 0 ? options.entrypoints : undefined
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export function parseInstallHooksArgs(args) {
|
|
138
|
+
const options = {
|
|
139
|
+
hook: "all",
|
|
140
|
+
cli: "critical-gate",
|
|
141
|
+
force: false
|
|
142
|
+
};
|
|
143
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
144
|
+
const arg = args[index];
|
|
145
|
+
if (arg === "--force") {
|
|
146
|
+
options.force = true;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (arg !== "--hook" && arg !== "--cli") {
|
|
150
|
+
return { ok: false, error: `Unknown option: ${arg}.` };
|
|
151
|
+
}
|
|
152
|
+
const value = args[index + 1];
|
|
153
|
+
if (value === undefined || value.startsWith("--")) {
|
|
154
|
+
return { ok: false, error: `Missing value for ${arg}.` };
|
|
155
|
+
}
|
|
156
|
+
if (arg === "--hook") {
|
|
157
|
+
if (value !== "pre-commit" && value !== "pre-push" && value !== "all") {
|
|
158
|
+
return { ok: false, error: "Invalid --hook value. Expected pre-commit, pre-push, or all." };
|
|
159
|
+
}
|
|
160
|
+
options.hook = value;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
options.cli = value;
|
|
164
|
+
}
|
|
165
|
+
index += 1;
|
|
166
|
+
}
|
|
167
|
+
return { ok: true, options };
|
|
168
|
+
}
|
|
169
|
+
export function parseInitPolicyArgs(args) {
|
|
170
|
+
const options = {
|
|
171
|
+
force: false
|
|
172
|
+
};
|
|
173
|
+
for (const arg of args) {
|
|
174
|
+
if (arg !== "--force") {
|
|
175
|
+
return { ok: false, error: `Unknown option: ${arg}.` };
|
|
176
|
+
}
|
|
177
|
+
options.force = true;
|
|
178
|
+
}
|
|
179
|
+
return { ok: true, options };
|
|
180
|
+
}
|
|
181
|
+
export function parseInitAgentArgs(args) {
|
|
182
|
+
const options = {
|
|
183
|
+
cli: "npx critical-gate"
|
|
184
|
+
};
|
|
185
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
186
|
+
const arg = args[index];
|
|
187
|
+
if (arg !== "--cli") {
|
|
188
|
+
return { ok: false, error: `Unknown option: ${arg}.` };
|
|
189
|
+
}
|
|
190
|
+
const value = args[index + 1];
|
|
191
|
+
if (value === undefined || value.startsWith("--")) {
|
|
192
|
+
return { ok: false, error: `Missing value for ${arg}.` };
|
|
193
|
+
}
|
|
194
|
+
options.cli = value;
|
|
195
|
+
index += 1;
|
|
196
|
+
}
|
|
197
|
+
return { ok: true, options };
|
|
198
|
+
}
|
|
199
|
+
function isReportFormat(value) {
|
|
200
|
+
return (value === "json" ||
|
|
201
|
+
value === "markdown" ||
|
|
202
|
+
value === "sarif" ||
|
|
203
|
+
value === "repair" ||
|
|
204
|
+
value === "pr-comment");
|
|
205
|
+
}
|
|
206
|
+
function isFailOnSeverity(value) {
|
|
207
|
+
return value === "blocker" || value === "high" || value === "medium";
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ExitCode, type CliIo } from "./types.js";
|
|
2
|
+
export declare function runSnapshotApiCommand(args: string[], io: CliIo): ExitCode;
|
|
3
|
+
export declare function runInstallHooksCommand(args: string[], io: CliIo): ExitCode;
|
|
4
|
+
export declare function runInitPolicyCommand(args: string[], io: CliIo): ExitCode;
|
|
5
|
+
export declare function runInitAgentCommand(args: string[], io: CliIo): ExitCode;
|
|
6
|
+
export declare function runAcceptCommand(args: string[], io: CliIo): ExitCode;
|
|
7
|
+
export declare function runTeachCommand(args: string[], io: CliIo): ExitCode;
|
|
8
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAElD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CA6BzE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CA8B1E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CAqBxE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CAyBvE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CA4CpE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,QAAQ,CAwDnE"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { CRITICAL_GATE_CONFIG_FILE, buildApiSurfaceSnapshot, createDefaultPolicyConfig, getApiSnapshotOutputPath, getConfiguredPublicApiEntrypoints, initAgentInstructions, loadCriticalGateConfig, updateCriticalGateConfig } from "../index.js";
|
|
3
|
+
import { parseFlagArgs, parseInitAgentArgs, parseInitPolicyArgs, parseInstallHooksArgs, parseSnapshotApiArgs } from "./args.js";
|
|
4
|
+
import { renderGitHookScript } from "./git-hooks.js";
|
|
5
|
+
import { ExitCode } from "./types.js";
|
|
6
|
+
export function runSnapshotApiCommand(args, io) {
|
|
7
|
+
const parsed = parseSnapshotApiArgs(args);
|
|
8
|
+
if (!parsed.ok) {
|
|
9
|
+
io.stderr(parsed.error);
|
|
10
|
+
io.stderr("Run critical-gate snapshot-api --help for usage.");
|
|
11
|
+
return ExitCode.UsageError;
|
|
12
|
+
}
|
|
13
|
+
const root = io.readDiff().root;
|
|
14
|
+
const configResult = loadCriticalGateConfig(root, {
|
|
15
|
+
exists: io.exists,
|
|
16
|
+
readFile: io.readFile
|
|
17
|
+
});
|
|
18
|
+
const snapshot = buildApiSurfaceSnapshot({
|
|
19
|
+
root,
|
|
20
|
+
generatedAt: io.now(),
|
|
21
|
+
entrypoints: parsed.options.entrypoints,
|
|
22
|
+
policyEntrypoints: getConfiguredPublicApiEntrypoints(configResult.config),
|
|
23
|
+
reader: io
|
|
24
|
+
});
|
|
25
|
+
const outputPath = getApiSnapshotOutputPath(root, parsed.options.output);
|
|
26
|
+
io.writeFile(outputPath, `${JSON.stringify(snapshot, null, 2)}\n`);
|
|
27
|
+
io.stdout(`Wrote public API snapshot to ${outputPath} (${snapshot.exports.length} exports across ${snapshot.entrypoints.length} entrypoints).`);
|
|
28
|
+
return ExitCode.Pass;
|
|
29
|
+
}
|
|
30
|
+
export function runInstallHooksCommand(args, io) {
|
|
31
|
+
const parsed = parseInstallHooksArgs(args);
|
|
32
|
+
if (!parsed.ok) {
|
|
33
|
+
io.stderr(parsed.error);
|
|
34
|
+
io.stderr("Run critical-gate install-hooks --help for usage.");
|
|
35
|
+
return ExitCode.UsageError;
|
|
36
|
+
}
|
|
37
|
+
const root = io.readDiff().root;
|
|
38
|
+
const hooks = parsed.options.hook === "all" ? ["pre-commit", "pre-push"] : [parsed.options.hook];
|
|
39
|
+
const installed = [];
|
|
40
|
+
for (const hook of hooks) {
|
|
41
|
+
const path = join(root, ".git", "hooks", hook);
|
|
42
|
+
if (io.exists?.(path) === true && parsed.options.force !== true) {
|
|
43
|
+
io.stderr(`Refusing to overwrite existing ${hook} hook at ${path}. Re-run with --force.`);
|
|
44
|
+
return ExitCode.UsageError;
|
|
45
|
+
}
|
|
46
|
+
io.writeFile(path, renderGitHookScript(hook, parsed.options.cli));
|
|
47
|
+
io.chmodFile?.(path, 0o755);
|
|
48
|
+
installed.push(path);
|
|
49
|
+
}
|
|
50
|
+
io.stdout(`Installed Critical Gate hook(s): ${installed.join(", ")}`);
|
|
51
|
+
return ExitCode.Pass;
|
|
52
|
+
}
|
|
53
|
+
export function runInitPolicyCommand(args, io) {
|
|
54
|
+
const parsed = parseInitPolicyArgs(args);
|
|
55
|
+
if (!parsed.ok) {
|
|
56
|
+
io.stderr(parsed.error);
|
|
57
|
+
io.stderr("Run critical-gate init-policy --help for usage.");
|
|
58
|
+
return ExitCode.UsageError;
|
|
59
|
+
}
|
|
60
|
+
const root = io.readDiff().root;
|
|
61
|
+
const path = join(root, CRITICAL_GATE_CONFIG_FILE);
|
|
62
|
+
if (io.exists?.(path) === true && parsed.options.force !== true) {
|
|
63
|
+
io.stderr(`Refusing to overwrite existing ${CRITICAL_GATE_CONFIG_FILE}. Re-run with --force.`);
|
|
64
|
+
return ExitCode.UsageError;
|
|
65
|
+
}
|
|
66
|
+
io.writeFile(path, `${JSON.stringify(createDefaultPolicyConfig(io.now()), null, 2)}\n`);
|
|
67
|
+
io.stdout(`Wrote reviewable Critical Gate policy to ${path}.`);
|
|
68
|
+
return ExitCode.Pass;
|
|
69
|
+
}
|
|
70
|
+
export function runInitAgentCommand(args, io) {
|
|
71
|
+
const parsed = parseInitAgentArgs(args);
|
|
72
|
+
if (!parsed.ok) {
|
|
73
|
+
io.stderr(parsed.error);
|
|
74
|
+
io.stderr("Run critical-gate init-agent --help for usage.");
|
|
75
|
+
return ExitCode.UsageError;
|
|
76
|
+
}
|
|
77
|
+
const root = io.readDiff().root;
|
|
78
|
+
const result = initAgentInstructions({
|
|
79
|
+
root,
|
|
80
|
+
cliCommand: parsed.options.cli,
|
|
81
|
+
io
|
|
82
|
+
});
|
|
83
|
+
if (result.updated) {
|
|
84
|
+
io.stdout(`${result.created ? "Created" : "Updated"} ${result.path} with Critical Gate agent instructions.`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
io.stdout(`${result.path} already contains the current Critical Gate agent instructions.`);
|
|
88
|
+
}
|
|
89
|
+
return ExitCode.Pass;
|
|
90
|
+
}
|
|
91
|
+
export function runAcceptCommand(args, io) {
|
|
92
|
+
const parsed = parseFlagArgs(args, ["--finding", "--reason"]);
|
|
93
|
+
if (!parsed.ok) {
|
|
94
|
+
io.stderr(parsed.error);
|
|
95
|
+
io.stderr("Run critical-gate accept --help for usage.");
|
|
96
|
+
return ExitCode.UsageError;
|
|
97
|
+
}
|
|
98
|
+
const finding = parsed.values["--finding"];
|
|
99
|
+
const reason = parsed.values["--reason"];
|
|
100
|
+
if (finding === undefined || reason === undefined) {
|
|
101
|
+
io.stderr("Missing required --finding or --reason value.");
|
|
102
|
+
io.stderr("Run critical-gate accept --help for usage.");
|
|
103
|
+
return ExitCode.UsageError;
|
|
104
|
+
}
|
|
105
|
+
const root = io.readDiff().root;
|
|
106
|
+
const updated = updateCriticalGateConfig(root, (config) => ({
|
|
107
|
+
...config,
|
|
108
|
+
learning: {
|
|
109
|
+
...config.learning,
|
|
110
|
+
acceptedFindings: upsertById(config.learning?.acceptedFindings ?? [], {
|
|
111
|
+
id: finding,
|
|
112
|
+
reason,
|
|
113
|
+
createdAt: io.now().toISOString()
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
}), {
|
|
117
|
+
exists: io.exists,
|
|
118
|
+
readFile: io.readFile,
|
|
119
|
+
writeFile: io.writeFile
|
|
120
|
+
});
|
|
121
|
+
io.stdout(`Accepted finding ${finding} in ${CRITICAL_GATE_CONFIG_FILE} (${updated.learning?.acceptedFindings?.length ?? 0} accepted finding rules).`);
|
|
122
|
+
return ExitCode.Pass;
|
|
123
|
+
}
|
|
124
|
+
export function runTeachCommand(args, io) {
|
|
125
|
+
const parsed = parseFlagArgs(args, ["--id", "--when-changed", "--allow", "--reason"]);
|
|
126
|
+
if (!parsed.ok) {
|
|
127
|
+
io.stderr(parsed.error);
|
|
128
|
+
io.stderr("Run critical-gate teach --help for usage.");
|
|
129
|
+
return ExitCode.UsageError;
|
|
130
|
+
}
|
|
131
|
+
const id = parsed.values["--id"];
|
|
132
|
+
const whenChanged = parsed.values["--when-changed"];
|
|
133
|
+
const allow = parsed.values["--allow"]
|
|
134
|
+
?.split(",")
|
|
135
|
+
.map((entry) => entry.trim())
|
|
136
|
+
.filter(Boolean);
|
|
137
|
+
const reason = parsed.values["--reason"];
|
|
138
|
+
if (id === undefined ||
|
|
139
|
+
whenChanged === undefined ||
|
|
140
|
+
allow === undefined ||
|
|
141
|
+
reason === undefined) {
|
|
142
|
+
io.stderr("Missing required --id, --when-changed, --allow, or --reason value.");
|
|
143
|
+
io.stderr("Run critical-gate teach --help for usage.");
|
|
144
|
+
return ExitCode.UsageError;
|
|
145
|
+
}
|
|
146
|
+
const root = io.readDiff().root;
|
|
147
|
+
const updated = updateCriticalGateConfig(root, (config) => ({
|
|
148
|
+
...config,
|
|
149
|
+
learning: {
|
|
150
|
+
...config.learning,
|
|
151
|
+
expectedSupportFiles: upsertById(config.learning?.expectedSupportFiles ?? [], {
|
|
152
|
+
id,
|
|
153
|
+
whenChanged,
|
|
154
|
+
allow,
|
|
155
|
+
reason,
|
|
156
|
+
createdAt: io.now().toISOString()
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
}), {
|
|
160
|
+
exists: io.exists,
|
|
161
|
+
readFile: io.readFile,
|
|
162
|
+
writeFile: io.writeFile
|
|
163
|
+
});
|
|
164
|
+
io.stdout(`Taught expected support rule ${id} in ${CRITICAL_GATE_CONFIG_FILE} (${updated.learning?.expectedSupportFiles?.length ?? 0} support rules).`);
|
|
165
|
+
return ExitCode.Pass;
|
|
166
|
+
}
|
|
167
|
+
function upsertById(entries, next) {
|
|
168
|
+
return [...entries.filter((entry) => entry.id !== next.id), next];
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=commands.js.map
|