gadriel 0.9.8
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/CHANGELOG.md +290 -0
- package/README.md +598 -0
- package/bin/gadriel.js +91 -0
- package/package.json +45 -0
- package/scripts/postinstall.js +47 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the **gadriel CLI** are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
Pre-1.0 versions may include breaking changes between minor versions; those are called out explicitly under a **⚠ Breaking** subsection.
|
|
8
|
+
|
|
9
|
+
> **Note:** the CLI version is intentionally decoupled from the broader Preflight workspace version (currently 0.2.1). This file tracks only the CLI's user-visible behavior.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## [Unreleased]
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## [0.9.8] — 2026-05-28
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- **Build Intel macOS on an Apple-Silicon runner.** GitHub's Intel
|
|
28
|
+
macOS runners (`macos-13`) are being deprecated and are effectively
|
|
29
|
+
unavailable — in the v0.9.7 run the `x86_64-apple-darwin` job sat
|
|
30
|
+
queued for **7.5 hours** without ever getting a runner, while the
|
|
31
|
+
other 4 targets built green. Switched that matrix entry to the
|
|
32
|
+
plentiful `macos-14` (Apple Silicon) runner and cross-compile to
|
|
33
|
+
`x86_64-apple-darwin` (the Apple clang toolchain is a universal
|
|
34
|
+
cross-compiler; rustup installs the x86_64 std). Produces a genuine
|
|
35
|
+
Intel binary without depending on scarce Intel runners.
|
|
36
|
+
|
|
37
|
+
### Note about 0.9.7
|
|
38
|
+
|
|
39
|
+
v0.9.7 was tagged but never published. All five binaries are now
|
|
40
|
+
buildable (Windows + both Linux + macOS arm64 all went green; the
|
|
41
|
+
Intel-Mac binary just couldn't get a runner). 0.9.8 routes the Intel
|
|
42
|
+
build to an available runner.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## [0.9.7] — 2026-05-28
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- **Release pipeline — portable sha256 in artifact staging.** With all
|
|
51
|
+
cross-compile bugs fixed in 0.9.6, the Windows binary finally built
|
|
52
|
+
(50 min — vendored OpenSSL from source) but the run failed in the
|
|
53
|
+
`Stage artifact` step: `shasum: command not found`. Git-Bash on
|
|
54
|
+
windows-2022 ships `sha256sum` but not `shasum`; macOS ships `shasum`
|
|
55
|
+
but not `sha256sum`. The workflow now prefers `sha256sum` and falls
|
|
56
|
+
back to `shasum -a 256`, covering all three OSes.
|
|
57
|
+
|
|
58
|
+
### Note about 0.9.6
|
|
59
|
+
|
|
60
|
+
v0.9.6 was tagged but never published. It proved every cross-compile
|
|
61
|
+
fix worked — Linux x64/arm64 + macOS arm64 built green, the Windows
|
|
62
|
+
binary compiled successfully — but the sha256 sidecar step used a
|
|
63
|
+
command absent from Git-Bash. 0.9.7 is purely that one-line fix.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## [0.9.6] — 2026-05-28
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- **macOS builds — patch `rvf-runtime`'s glibc-only errno symbol.**
|
|
72
|
+
`rvf-runtime 0.2.0/src/locking.rs` declared `__errno_location` in an
|
|
73
|
+
`extern "C"` block gated on `#[cfg(unix)]`. That symbol exists on
|
|
74
|
+
glibc/musl Linux but NOT on macOS (errno lives behind `__error`),
|
|
75
|
+
so macOS release builds failed at link time with
|
|
76
|
+
`Undefined symbols for architecture arm64: ___errno_location`.
|
|
77
|
+
Fixed by vendoring `rvf-runtime` under `vendor/rvf-runtime` (wired
|
|
78
|
+
via `[patch.crates-io]`) and replacing the hand-rolled extern with
|
|
79
|
+
the portable `std::io::Error::last_os_error()`. Remove the patch
|
|
80
|
+
once the fix lands upstream (>= 0.2.1).
|
|
81
|
+
|
|
82
|
+
- **Windows builds — use Strawberry Perl for vendored OpenSSL.**
|
|
83
|
+
`webauthn-rs-core` pulls vendored OpenSSL (`openssl-src`), whose
|
|
84
|
+
build runs `perl ./Configure`. On windows-2022 the bash shell is
|
|
85
|
+
Git-Bash, which puts a minimal MSYS perl first on PATH — it lacks
|
|
86
|
+
`Locale::Maketext::Simple` / `Text::Template`, so Configure died
|
|
87
|
+
with exit code 2. The release workflow now sets
|
|
88
|
+
`OPENSSL_SRC_PERL=C:/Strawberry/perl/bin/perl.exe` on Windows runners.
|
|
89
|
+
|
|
90
|
+
### Note about 0.9.5
|
|
91
|
+
|
|
92
|
+
v0.9.5 was tagged but never published. The workspace native-tls strip
|
|
93
|
+
(below) fixed Linux x64 + arm64, but macOS (rvf-runtime errno) and
|
|
94
|
+
Windows (openssl-src perl) each had a further platform bug, both fixed
|
|
95
|
+
in 0.9.6.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## [0.9.5] — 2026-05-27
|
|
100
|
+
|
|
101
|
+
### Fixed
|
|
102
|
+
|
|
103
|
+
- **Cross-compile reliability — strip `native-tls` workspace-wide**
|
|
104
|
+
(the biome / swc / rolldown pattern). The cli-v0.9.4 release run
|
|
105
|
+
produced working Linux binaries but failed on macOS arm64 and
|
|
106
|
+
Windows because vendoring OpenSSL from source is fragile on those
|
|
107
|
+
platforms. Root cause: `reqwest`'s default-tls feature pulled
|
|
108
|
+
`native-tls` → `openssl-sys`, and `fastembed` explicitly opted into
|
|
109
|
+
`hf-hub-native-tls`. Fixed by:
|
|
110
|
+
- Setting `default-features = false` + adding `rustls-tls` to
|
|
111
|
+
every workspace `reqwest` declaration (workspace root + 9
|
|
112
|
+
individual crates).
|
|
113
|
+
- Switching `preflight-embeddings`'s `fastembed` feature from
|
|
114
|
+
`hf-hub-native-tls` to `hf-hub-rustls-tls`.
|
|
115
|
+
- Switching `sqlx`'s `runtime-tokio-native-tls` →
|
|
116
|
+
`runtime-tokio-rustls` in `preflight-auth-service`,
|
|
117
|
+
`preflight-docs`, and `infrastructure/provisioning-api`.
|
|
118
|
+
- Switching `lettre`'s `tokio1-native-tls` → `tokio1-rustls-tls`
|
|
119
|
+
in `preflight-api` and `infrastructure/provisioning-api`.
|
|
120
|
+
- Disabling `webauthn-rs`'s default `attestation` feature where
|
|
121
|
+
possible (attestation APIs aren't called by any code in the
|
|
122
|
+
workspace).
|
|
123
|
+
|
|
124
|
+
Result: `cargo tree -p gadriel-cli --invert native-tls` returns
|
|
125
|
+
empty. The only remaining `openssl-sys` consumer is
|
|
126
|
+
`webauthn-rs-core` (which hardcodes a non-optional openssl dep),
|
|
127
|
+
forced to vendored mode via a single `openssl = { features =
|
|
128
|
+
["vendored"] }` line in `gadriel-cli/Cargo.toml`. That smaller
|
|
129
|
+
openssl footprint (just webauthn cert parsing, no TLS) is what
|
|
130
|
+
should let the vendored build succeed on Mac/Windows where it
|
|
131
|
+
previously failed building the full stack.
|
|
132
|
+
|
|
133
|
+
### Note about 0.9.4
|
|
134
|
+
|
|
135
|
+
v0.9.4 was tagged but never published — the workflow built linux-x64
|
|
136
|
+
+ linux-arm64 successfully (Cargo.lock fix worked) but failed on
|
|
137
|
+
macOS / Windows because of the deeper native-tls problem fixed here.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## [0.9.4] — 2026-05-27
|
|
142
|
+
|
|
143
|
+
### Fixed
|
|
144
|
+
|
|
145
|
+
- **Release tooling** — `scripts/release/bump-cli.sh` now refreshes
|
|
146
|
+
`Cargo.lock` after bumping the crate version (via
|
|
147
|
+
`cargo update -p gadriel-cli --precise <new> --offline`). Without
|
|
148
|
+
this, every CI build using `cargo build --locked` would fail with
|
|
149
|
+
`cannot update the lock file ... because --locked was passed` —
|
|
150
|
+
which is exactly what blocked v0.9.3.
|
|
151
|
+
|
|
152
|
+
### Note about 0.9.3
|
|
153
|
+
|
|
154
|
+
v0.9.3 was tagged but never published — Cargo.lock referenced the old
|
|
155
|
+
crate version, and CI's `cargo build --locked` refused to update it.
|
|
156
|
+
0.9.4 fixes the bump script so this won't happen again.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## [0.9.3] — 2026-05-27
|
|
161
|
+
|
|
162
|
+
### Fixed
|
|
163
|
+
|
|
164
|
+
- **Release pipeline** — removed a bogus gitlink at
|
|
165
|
+
`examples/ai-hedge-fund/repo` (mode 160000) that had no corresponding
|
|
166
|
+
`.gitmodules` entry. Modern `actions/checkout@v4` treats this as a
|
|
167
|
+
fatal error (`fatal: No url found for submodule path 'examples/
|
|
168
|
+
ai-hedge-fund/repo' in .gitmodules`), which blocked **every** matrix
|
|
169
|
+
job from progressing past checkout. The inconsistent state has lived
|
|
170
|
+
on `main` since 2026-03-03 — older actions/checkout was lenient.
|
|
171
|
+
|
|
172
|
+
### Note about 0.9.2
|
|
173
|
+
|
|
174
|
+
v0.9.2 was tagged but never published — the checkout-step failure
|
|
175
|
+
above prevented any binary from building. 0.9.3 is the first
|
|
176
|
+
release that actually ships.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## [0.9.2] — 2026-05-27
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
|
|
184
|
+
- **Cross-compile reliability** — added `openssl = { features = ["vendored"] }` to
|
|
185
|
+
`crates/gadriel-cli/Cargo.toml`. A transitive workspace dependency was pulling
|
|
186
|
+
in `openssl-sys`, which broke the 4 non-linux-x64 release matrix runners
|
|
187
|
+
(no system OpenSSL available for Windows, macOS, and linux-arm64). The
|
|
188
|
+
vendored feature makes `openssl-sys` compile OpenSSL from source as part
|
|
189
|
+
of the build — works on every platform, adds ~5 MB to the binary and
|
|
190
|
+
~2 min to the build.
|
|
191
|
+
|
|
192
|
+
### Note about 0.9.1
|
|
193
|
+
|
|
194
|
+
v0.9.1 was tagged (`cli-v0.9.1`) but **never published to npm or GitHub
|
|
195
|
+
Releases** — the multi-platform build matrix failed on the openssl-sys
|
|
196
|
+
issue above. 0.9.2 is the first version with a working release artifact.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## [0.9.1] — 2026-05-27
|
|
201
|
+
|
|
202
|
+
First publicly distributed release. The CLI moves from "internal workspace tool"
|
|
203
|
+
to "installable end-user product." Everything below is what makes that
|
|
204
|
+
possible; the underlying feature surface (code-security scanning, AI-agent
|
|
205
|
+
testing, MCP server) has been baking internally for many iterations.
|
|
206
|
+
|
|
207
|
+
### Added
|
|
208
|
+
|
|
209
|
+
- **npm distribution** via the `optionalDependencies` pattern (same as esbuild
|
|
210
|
+
/ swc / biome / turbo). One install command — `npm install -g gadriel` —
|
|
211
|
+
picks the right prebuilt binary for the host OS+arch automatically.
|
|
212
|
+
- **Five prebuilt platform binaries** published as scoped npm packages:
|
|
213
|
+
- `@gadriel/cli-linux-x64`
|
|
214
|
+
- `@gadriel/cli-linux-arm64`
|
|
215
|
+
- `@gadriel/cli-darwin-x64`
|
|
216
|
+
- `@gadriel/cli-darwin-arm64`
|
|
217
|
+
- `@gadriel/cli-win32-x64`
|
|
218
|
+
- **GitHub Releases pipeline** (`.github/workflows/cli-release.yml`) that
|
|
219
|
+
cross-compiles all five targets on every `cli-v*` tag, attaches tarballs
|
|
220
|
+
+ matching `.sha256` sidecars to a GitHub Release, then atomically
|
|
221
|
+
publishes all six npm packages.
|
|
222
|
+
- **Comprehensive README** (`crates/gadriel-cli/README.md`) covering install,
|
|
223
|
+
quick start, command reference, output formats, configuration, CI/CD
|
|
224
|
+
integration, privacy model, performance, and troubleshooting.
|
|
225
|
+
- **Operator runbook** at `docs/runbooks/cli-release.md` documenting the
|
|
226
|
+
release process (one-time setup, per-release steps, dry-run, rollback).
|
|
227
|
+
- **Version-bump helper** at `scripts/release/bump-cli.sh` that updates all
|
|
228
|
+
7 manifests in one shot (Cargo.toml + 6 npm package.json files).
|
|
229
|
+
|
|
230
|
+
### Changed
|
|
231
|
+
|
|
232
|
+
- ⚠ **Versioning** — `gadriel-cli` is now detached from the workspace
|
|
233
|
+
version. Previously it inherited `version.workspace = true` and tracked
|
|
234
|
+
the engine version (0.2.1). Going forward the CLI has its own
|
|
235
|
+
user-facing version (0.9.1+), and the npm packages mirror it exactly.
|
|
236
|
+
- **README** — replaced the stale `preflight-cli` README with a
|
|
237
|
+
user-oriented one. The old README pre-dated the rename + code-security
|
|
238
|
+
surface and no longer described how the tool actually worked.
|
|
239
|
+
- **`gadriel --version`** now reports 0.9.1 (previously 0.2.1, matching the
|
|
240
|
+
workspace).
|
|
241
|
+
|
|
242
|
+
### Notes
|
|
243
|
+
|
|
244
|
+
- macOS binaries are **not yet Apple-notarized**. First-run Gatekeeper
|
|
245
|
+
prompt is expected; the README documents the `xattr -d` workaround.
|
|
246
|
+
Notarization is on the v1.0 milestone (requires Apple Developer ID).
|
|
247
|
+
- Windows binaries are **not yet code-signed**. SmartScreen will warn on
|
|
248
|
+
first run; click "More info → Run anyway". Also on the v1.0 milestone.
|
|
249
|
+
- `linux-musl`, FreeBSD, and Windows ARM are **build-from-source only**.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Pre-history (0.1.0 – 0.8.x)
|
|
254
|
+
|
|
255
|
+
These versions never had a public binary release. The CLI evolved
|
|
256
|
+
internally as part of the Preflight monorepo through many waves of
|
|
257
|
+
work; the most user-relevant landmarks were:
|
|
258
|
+
|
|
259
|
+
- **0.8.x** — Code-security surface stabilized: `gadriel code init/scan/
|
|
260
|
+
findings/watch/sbom/report/dashboard/policies/store/mcp` shipped.
|
|
261
|
+
Ruby/Rails SAST extractor + 31-rule pack (iter-33). RVF World-Class
|
|
262
|
+
HTML reports.
|
|
263
|
+
- **0.7.x** — Beta-program portal integration (`gadriel auth login`,
|
|
264
|
+
30-day token rotation, OS-keyring storage).
|
|
265
|
+
- **0.6.x** — MCP server (`gadriel code mcp`) for Claude Code / Cursor
|
|
266
|
+
integration via JSON-RPC 2.0.
|
|
267
|
+
- **0.5.x** — Layer 1 file-save watcher (300ms debounced, per-file SAST
|
|
268
|
+
+ secrets), license-gate enforcement (ADR-085), privacy-by-default
|
|
269
|
+
model (ADR-090).
|
|
270
|
+
- **0.4.x** — `.claude/` scaffold: slash-commands (gadriel-fix,
|
|
271
|
+
gadriel-scan, gadriel-watch, gadriel-status, gadriel-reports),
|
|
272
|
+
reviewer agents (security, compliance, safety, bias, coherence,
|
|
273
|
+
operational, finops, teamwork), 20+ Claude Code skills.
|
|
274
|
+
- **0.3.x** — SBOM generation (SPDX 2.3 + CycloneDX 1.4 per ADR-084),
|
|
275
|
+
per-framework compliance reports (OWASP LLM Top-10, NIST AI RMF, EU
|
|
276
|
+
AI Act per ADR-085).
|
|
277
|
+
- **0.2.x** — Initial code-security surface alongside the original
|
|
278
|
+
AI-agent testing surface (scan, target, plan, scenario, run,
|
|
279
|
+
remediate, explain, doctor, dashboard).
|
|
280
|
+
- **0.1.x** — Renamed from `preflight-cli` to `gadriel-cli`, with the
|
|
281
|
+
user-visible binary becoming `gadriel`.
|
|
282
|
+
|
|
283
|
+
For full git history of any of the above, see `git log
|
|
284
|
+
crates/gadriel-cli/` in the [Preflight
|
|
285
|
+
repository](https://github.com/Gadriel-ai/preflight).
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
[Unreleased]: https://github.com/Gadriel-ai/preflight/compare/cli-v0.9.1...HEAD
|
|
290
|
+
[0.9.1]: https://github.com/Gadriel-ai/preflight/releases/tag/cli-v0.9.1
|
package/README.md
ADDED
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
# gadriel
|
|
2
|
+
|
|
3
|
+
> **Code-security scanning + AI-agent testing CLI** — built for projects where humans and coding agents commit side-by-side.
|
|
4
|
+
|
|
5
|
+
Gadriel finds vulnerabilities, exposed secrets, license issues, and AI-specific risks (prompt injection, taint flows, agent contract violations) in any codebase. It also runs adversarial test plans against live AI agents to catch behavior issues *before* they reach production.
|
|
6
|
+
|
|
7
|
+
Everything runs **locally**. Source code never leaves your machine. See [Privacy & data handling](#privacy--data-handling).
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/gadriel)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](#supported-platforms)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Table of contents
|
|
16
|
+
|
|
17
|
+
- [Install](#install)
|
|
18
|
+
- [Quick start](#quick-start)
|
|
19
|
+
- [Authentication](#authentication)
|
|
20
|
+
- [What gadriel does](#what-gadriel-does)
|
|
21
|
+
- [Command reference](#command-reference)
|
|
22
|
+
- [Output formats](#output-formats)
|
|
23
|
+
- [Configuration](#configuration)
|
|
24
|
+
- [CI/CD integration](#cicd-integration)
|
|
25
|
+
- [Privacy & data handling](#privacy--data-handling)
|
|
26
|
+
- [Performance](#performance)
|
|
27
|
+
- [Supported platforms](#supported-platforms)
|
|
28
|
+
- [Troubleshooting](#troubleshooting)
|
|
29
|
+
- [Versioning & support](#versioning--support)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
### Via npm (recommended)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install -g gadriel
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or run once without installing:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npx gadriel code scan .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
npm picks the right prebuilt binary for your OS+arch automatically (via the `optionalDependencies` pattern). 5 platforms supported out of the box — see [Supported platforms](#supported-platforms).
|
|
49
|
+
|
|
50
|
+
### Via cargo
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/Gadriel-ai/preflight && cd preflight
|
|
54
|
+
cargo install --path crates/gadriel-cli
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Requires Rust 1.87+. Useful if you're on a platform we don't prebuild for (e.g. linux-musl, freebsd), or if you want to hack on the CLI itself.
|
|
58
|
+
|
|
59
|
+
### From a release tarball
|
|
60
|
+
|
|
61
|
+
Every release publishes binaries to [GitHub Releases](https://github.com/Gadriel-ai/preflight/releases) with matching `.sha256` sidecars:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
curl -sLo gadriel.tar.gz https://github.com/Gadriel-ai/preflight/releases/download/cli-v0.9.1/gadriel-0.9.1-linux-x64.tar.gz
|
|
65
|
+
curl -sLo gadriel.tar.gz.sha256 https://github.com/Gadriel-ai/preflight/releases/download/cli-v0.9.1/gadriel-0.9.1-linux-x64.tar.gz.sha256
|
|
66
|
+
shasum -a 256 -c gadriel.tar.gz.sha256
|
|
67
|
+
tar xzf gadriel.tar.gz && sudo mv gadriel /usr/local/bin/
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Quick start
|
|
73
|
+
|
|
74
|
+
### 1. Initialize gadriel in your project
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cd path/to/your/repo
|
|
78
|
+
gadriel code init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This scaffolds:
|
|
82
|
+
|
|
83
|
+
- `.security/` — local findings store (gitignored by default)
|
|
84
|
+
- `.claude/` — Claude Code slash-commands + reviewer agents + skills
|
|
85
|
+
- `.gadriel/config.toml` — project-level overrides
|
|
86
|
+
- Optional pre-commit hook that runs `gadriel code scan` on staged files
|
|
87
|
+
|
|
88
|
+
### 2. Run your first scan
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
gadriel code scan .
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Output (abbreviated):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
Scanning ./my-app ...
|
|
98
|
+
⚠ 12 findings (3 critical, 5 high, 4 medium)
|
|
99
|
+
⚠ 2 secrets exposed (AWS_ACCESS_KEY_ID at src/config/aws.ts:14)
|
|
100
|
+
⚠ 1 license violation (GPL-3.0 in transitive dep "foo-lib")
|
|
101
|
+
✓ SBOM generated → .security/sbom.spdx.json
|
|
102
|
+
✓ Report → .security/findings.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 3. Triage findings
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Browse findings interactively
|
|
109
|
+
gadriel code findings
|
|
110
|
+
|
|
111
|
+
# Or as JSON for scripting
|
|
112
|
+
gadriel code findings --format json | jq '.[] | select(.severity == "critical")'
|
|
113
|
+
|
|
114
|
+
# Mark a finding as a false positive (writes to .security/triage.json)
|
|
115
|
+
gadriel code fix FIND-AB12CD --dismiss "fp: test fixture, not prod code"
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 4. Generate compliance artifacts
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Software Bill of Materials (SPDX 2.3 + CycloneDX 1.4)
|
|
122
|
+
gadriel code sbom --format spdx > sbom.spdx.json
|
|
123
|
+
gadriel code sbom --format cyclonedx > sbom.cyclonedx.json
|
|
124
|
+
|
|
125
|
+
# Per-framework compliance report (Markdown, with --pdf for typst PDF source)
|
|
126
|
+
gadriel code report --framework owasp-llm-top10
|
|
127
|
+
gadriel code report --framework nist-ai-rmf --pdf
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Authentication
|
|
133
|
+
|
|
134
|
+
Most commands work fully offline. Gadriel only contacts the control plane (`app.gadriel.ai`) for:
|
|
135
|
+
|
|
136
|
+
- **License-gate verification** — one HEAD request per scan that asks "is this license still valid?". The request includes no source code, no findings, no file paths.
|
|
137
|
+
- **Sync** — `gadriel sync` uploads findings to your portal account *if you opt in*; off by default.
|
|
138
|
+
|
|
139
|
+
### Sign in
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
gadriel login
|
|
143
|
+
# or, for the new beta-program portal:
|
|
144
|
+
gadriel auth login
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Either opens `https://app.gadriel.ai/beta/login` in your browser. After you sign in, gadriel mints a 30-day API token and stores it in your OS keyring (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux).
|
|
148
|
+
|
|
149
|
+
### Check status
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
gadriel status
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
gadriel 0.9.1
|
|
157
|
+
Logged in: farshid@gadriel.ai
|
|
158
|
+
Portal: https://app.gadriel.ai
|
|
159
|
+
Token expires: 2026-06-26 (30 days)
|
|
160
|
+
License: Active (Pro, seat #1)
|
|
161
|
+
Last sync: 2 hours ago
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Sign out
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
gadriel logout
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Wipes the token from your keyring.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## What gadriel does
|
|
175
|
+
|
|
176
|
+
Gadriel has **two distinct scanning surfaces**. Most users only need the first.
|
|
177
|
+
|
|
178
|
+
### 1. Code security (`gadriel code …`)
|
|
179
|
+
|
|
180
|
+
Static analysis of your repository. Catches:
|
|
181
|
+
|
|
182
|
+
| Category | Examples |
|
|
183
|
+
|---|---|
|
|
184
|
+
| **SAST** | SQL injection, XSS, command injection, path traversal, deserialization (Java/Python/Ruby/Go/JS), Rails-specific (mass assignment, unsafe `send`), 31-rule Ruby/Rails pack |
|
|
185
|
+
| **SCA** | Vulnerable dependencies (OSV.dev integration), transitive risks |
|
|
186
|
+
| **Secrets** | AWS/GCP/Azure keys, GitHub PATs, Slack webhooks, JWT secrets, API keys, ~80 patterns |
|
|
187
|
+
| **AI-specific** | Prompt-injection sinks in agent code, taint flows through LLM APIs, agent-contract violations (A2A), output-schema drift |
|
|
188
|
+
| **License** | Copyleft contamination, license incompatibility across deps, ADR-085 license-gate enforcement |
|
|
189
|
+
| **Config** | Dockerfile best practices, Kubernetes hardening, `.env` exposure, CI/CD misconfig |
|
|
190
|
+
| **API** | OpenAPI/AsyncAPI contract violations, missing auth, overly permissive CORS |
|
|
191
|
+
|
|
192
|
+
### 2. AI agent testing (`gadriel scan`, `gadriel run`, `gadriel scenario …`)
|
|
193
|
+
|
|
194
|
+
Run adversarial test plans against **live AI agents**. Catches:
|
|
195
|
+
|
|
196
|
+
- Jailbreaks and prompt-injection escalations
|
|
197
|
+
- Output-format violations (JSON schema drift, missing required fields)
|
|
198
|
+
- Cost / token-budget runaways
|
|
199
|
+
- Bias, safety, and compliance issues (OWASP LLM Top-10, NIST AI RMF, EU AI Act mappings)
|
|
200
|
+
- Latency regressions
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
gadriel scan https://api.your-agent.com --type llm
|
|
204
|
+
gadriel run my-test-plan --target https://api.your-agent.com
|
|
205
|
+
gadriel scenario list --framework owasp-llm-top10
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
This surface is more advanced. The [docs site](https://docs.gadriel.ai) covers it in depth.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Command reference
|
|
213
|
+
|
|
214
|
+
The CLI groups commands into three tiers. The full `gadriel --help` lists everything.
|
|
215
|
+
|
|
216
|
+
### Tier 1 — daily-use commands
|
|
217
|
+
|
|
218
|
+
| Command | What it does |
|
|
219
|
+
|---|---|
|
|
220
|
+
| `gadriel code init` | Scaffold `.security/`, `.claude/`, hooks, MCP config in this repo |
|
|
221
|
+
| `gadriel code scan [path]` | Run code-security scan (SAST + SCA + secrets + license) |
|
|
222
|
+
| `gadriel code findings` | Read/filter `.security/findings.json` |
|
|
223
|
+
| `gadriel code watch` | Background file-save validator (300ms debounced, per-file scans) |
|
|
224
|
+
| `gadriel code fix <id>` | Confirm, dismiss, or hand off a finding to an AI agent for fix |
|
|
225
|
+
| `gadriel code sbom` | Export SPDX 2.3 + CycloneDX 1.4 SBOM |
|
|
226
|
+
| `gadriel code report` | Per-framework compliance report (Markdown / HTML / PDF) |
|
|
227
|
+
| `gadriel code dashboard` | Local-only web dashboard at `127.0.0.1` |
|
|
228
|
+
| `gadriel login` / `gadriel logout` | Auth |
|
|
229
|
+
| `gadriel status` | Show auth + sync state |
|
|
230
|
+
| `gadriel doctor` | Diagnose issues (paths, perms, network, configs) |
|
|
231
|
+
|
|
232
|
+
### Tier 2 — AI agent testing
|
|
233
|
+
|
|
234
|
+
| Command | What it does |
|
|
235
|
+
|---|---|
|
|
236
|
+
| `gadriel scan <url>` | Quick scan with built-in scenarios (auto-detects target type) |
|
|
237
|
+
| `gadriel quicktest` | Run a single scenario for debugging |
|
|
238
|
+
| `gadriel target` | Manage configured agent endpoints |
|
|
239
|
+
| `gadriel plan` | Manage saved test plans |
|
|
240
|
+
| `gadriel scenario` | Browse / validate / run individual scenarios |
|
|
241
|
+
| `gadriel run <plan-id>` | Execute a multi-scenario plan |
|
|
242
|
+
| `gadriel report` | View scan reports |
|
|
243
|
+
| `gadriel explain <finding-id>` | LLM-narrated explanation of a finding |
|
|
244
|
+
| `gadriel remediate <finding-id>` | Generate remediation plan |
|
|
245
|
+
|
|
246
|
+
### Tier 3 — meta / advanced
|
|
247
|
+
|
|
248
|
+
| Command | What it does |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `gadriel init` | Initialize a new gadriel project (root-level config) |
|
|
251
|
+
| `gadriel config` | Read/write `gadriel.toml` |
|
|
252
|
+
| `gadriel profile` | Switch between named auth/portal profiles |
|
|
253
|
+
| `gadriel composition` | Manage multi-agent compositions |
|
|
254
|
+
| `gadriel sync` | Push pending results to portal |
|
|
255
|
+
| `gadriel update` | Self-update (no-op on npm installs; use `npm update -g gadriel`) |
|
|
256
|
+
| `gadriel completion [shell]` | Generate bash/zsh/fish/powershell completions |
|
|
257
|
+
| `gadriel hooks` | Claude Code hook dispatcher (invoked by `.claude/settings.json`) |
|
|
258
|
+
| `gadriel version` | Print version + build info |
|
|
259
|
+
| `gadriel code mcp` | Start MCP JSON-RPC server (for Claude Code / Cursor integrations) |
|
|
260
|
+
| `gadriel code store` | RVF substrate ops (advanced; per-machine + per-repo data stores) |
|
|
261
|
+
| `gadriel code policies` | Manage GVL rule corpus + OSV advisory snapshots |
|
|
262
|
+
|
|
263
|
+
Every command supports:
|
|
264
|
+
|
|
265
|
+
- `--json` — machine-readable output (overrides `--format`)
|
|
266
|
+
- `--quiet` / `-q` — minimal output for CI
|
|
267
|
+
- `--verbose` / `-v` — more detail
|
|
268
|
+
- `--no-color` — for log files
|
|
269
|
+
- `--config <path>` — use a specific config file
|
|
270
|
+
- `--portal <url>` — override portal URL (for self-hosted deployments)
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## Output formats
|
|
275
|
+
|
|
276
|
+
Pick the right format for your downstream consumer.
|
|
277
|
+
|
|
278
|
+
| Format | Flag | Use case |
|
|
279
|
+
|---|---|---|
|
|
280
|
+
| Terminal (default) | (none) | Human-readable, color-coded, with severity icons |
|
|
281
|
+
| JSON | `--json` | Pipe to `jq`, post to Slack, ingest into Splunk |
|
|
282
|
+
| SARIF 2.1.0 | `--format sarif` | GitHub Code Scanning, Azure DevOps |
|
|
283
|
+
| SPDX 2.3 | `gadriel code sbom --format spdx` | SBOM ingestion (most enterprise tooling) |
|
|
284
|
+
| CycloneDX 1.4 | `gadriel code sbom --format cyclonedx` | OWASP-aligned SBOM |
|
|
285
|
+
| Markdown | `gadriel code report` | Human-readable compliance docs, GitHub Wiki |
|
|
286
|
+
| HTML | `gadriel code report --html` | Static RVF World-Class bundle for portal/CI hosting |
|
|
287
|
+
| PDF (typst source) | `gadriel code report --pdf` | Compliance evidence packs; render with `typst compile` |
|
|
288
|
+
|
|
289
|
+
### SARIF for GitHub Code Scanning
|
|
290
|
+
|
|
291
|
+
```yaml
|
|
292
|
+
- run: gadriel code scan --format sarif > results.sarif
|
|
293
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
294
|
+
with:
|
|
295
|
+
sarif_file: results.sarif
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Findings appear in the **Security → Code scanning** tab.
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Configuration
|
|
303
|
+
|
|
304
|
+
Configuration is layered (later overrides earlier):
|
|
305
|
+
|
|
306
|
+
1. **Built-in defaults**
|
|
307
|
+
2. **`~/.config/gadriel/config.toml`** — user-wide
|
|
308
|
+
3. **`./gadriel.toml`** or **`./.gadriel/config.toml`** — project-level
|
|
309
|
+
4. **Environment variables** (`GADRIEL_PORTAL`, `GADRIEL_NO_TELEMETRY`, etc.)
|
|
310
|
+
5. **CLI flags** (highest priority)
|
|
311
|
+
|
|
312
|
+
### Project config example
|
|
313
|
+
|
|
314
|
+
```toml
|
|
315
|
+
# .gadriel/config.toml
|
|
316
|
+
|
|
317
|
+
[scan]
|
|
318
|
+
ignore_paths = ["target/", "node_modules/", "vendor/"]
|
|
319
|
+
fail_on = "high" # exit non-zero if any finding ≥ this severity
|
|
320
|
+
max_file_size_mb = 5
|
|
321
|
+
|
|
322
|
+
[secrets]
|
|
323
|
+
allowlist = [
|
|
324
|
+
"EXAMPLE_API_KEY=changeme", # demo fixture; safe to commit
|
|
325
|
+
]
|
|
326
|
+
|
|
327
|
+
[license]
|
|
328
|
+
disallow = ["GPL-3.0-only", "AGPL-3.0-only"]
|
|
329
|
+
warn_on = ["LGPL-2.1-only"]
|
|
330
|
+
|
|
331
|
+
[code.sbom]
|
|
332
|
+
format = "spdx" # default for `gadriel code sbom`
|
|
333
|
+
include_dev_deps = false
|
|
334
|
+
|
|
335
|
+
[portal]
|
|
336
|
+
url = "https://app.gadriel.ai"
|
|
337
|
+
profile = "default"
|
|
338
|
+
|
|
339
|
+
[telemetry]
|
|
340
|
+
enabled = false # opt-in, off by default
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
### Setting values
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
gadriel config set scan.fail_on critical
|
|
347
|
+
gadriel config get scan.fail_on
|
|
348
|
+
gadriel config list
|
|
349
|
+
gadriel config unset secrets.allowlist
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Environment variables
|
|
353
|
+
|
|
354
|
+
| Variable | What it does |
|
|
355
|
+
|---|---|
|
|
356
|
+
| `GADRIEL_PORTAL` | Override portal URL (for self-hosted) |
|
|
357
|
+
| `GADRIEL_TOKEN` | Use this API token instead of the keyring (for CI) |
|
|
358
|
+
| `GADRIEL_CONFIG` | Path to config file |
|
|
359
|
+
| `GADRIEL_NO_TELEMETRY` | Force-disable telemetry regardless of config |
|
|
360
|
+
| `GADRIEL_LOG` | Log level (`error`, `warn`, `info`, `debug`, `trace`) |
|
|
361
|
+
| `NO_COLOR` | Disable ANSI colors (standard convention) |
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## CI/CD integration
|
|
366
|
+
|
|
367
|
+
### GitHub Actions
|
|
368
|
+
|
|
369
|
+
```yaml
|
|
370
|
+
name: Gadriel security scan
|
|
371
|
+
on: [push, pull_request]
|
|
372
|
+
|
|
373
|
+
jobs:
|
|
374
|
+
scan:
|
|
375
|
+
runs-on: ubuntu-latest
|
|
376
|
+
permissions:
|
|
377
|
+
contents: read
|
|
378
|
+
security-events: write # for SARIF upload
|
|
379
|
+
steps:
|
|
380
|
+
- uses: actions/checkout@v4
|
|
381
|
+
- name: Install gadriel
|
|
382
|
+
run: npm install -g gadriel
|
|
383
|
+
- name: Scan
|
|
384
|
+
env:
|
|
385
|
+
GADRIEL_TOKEN: ${{ secrets.GADRIEL_TOKEN }}
|
|
386
|
+
run: gadriel code scan --format sarif > results.sarif
|
|
387
|
+
- uses: github/codeql-action/upload-sarif@v3
|
|
388
|
+
with:
|
|
389
|
+
sarif_file: results.sarif
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### GitLab CI
|
|
393
|
+
|
|
394
|
+
```yaml
|
|
395
|
+
gadriel-scan:
|
|
396
|
+
image: node:20
|
|
397
|
+
script:
|
|
398
|
+
- npm install -g gadriel
|
|
399
|
+
- gadriel code scan --format json > gl-sast-report.json
|
|
400
|
+
artifacts:
|
|
401
|
+
reports:
|
|
402
|
+
sast: gl-sast-report.json
|
|
403
|
+
variables:
|
|
404
|
+
GADRIEL_TOKEN: $GADRIEL_TOKEN
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Jenkins
|
|
408
|
+
|
|
409
|
+
```groovy
|
|
410
|
+
pipeline {
|
|
411
|
+
agent any
|
|
412
|
+
stages {
|
|
413
|
+
stage('Gadriel scan') {
|
|
414
|
+
steps {
|
|
415
|
+
sh 'npm install -g gadriel'
|
|
416
|
+
withCredentials([string(credentialsId: 'gadriel-token', variable: 'GADRIEL_TOKEN')]) {
|
|
417
|
+
sh 'gadriel code scan --format sarif > results.sarif'
|
|
418
|
+
}
|
|
419
|
+
recordIssues tools: [sarif(pattern: 'results.sarif')]
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Pre-commit hook
|
|
427
|
+
|
|
428
|
+
`gadriel code init` offers to install one. Manually:
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
# .git/hooks/pre-commit
|
|
432
|
+
#!/bin/sh
|
|
433
|
+
gadriel code scan --staged --quiet --fail-on critical
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Privacy & data handling
|
|
439
|
+
|
|
440
|
+
Gadriel is **privacy-by-default** ([ADR-090](https://github.com/Gadriel-ai/preflight/blob/main/docs/adr/ADR-090-privacy-by-default.md)).
|
|
441
|
+
|
|
442
|
+
**What stays on your machine:**
|
|
443
|
+
- Source code (always)
|
|
444
|
+
- Findings (`.security/findings.json`, local files)
|
|
445
|
+
- SBOMs (local files)
|
|
446
|
+
- File paths, function names, identifiers
|
|
447
|
+
- Logs
|
|
448
|
+
|
|
449
|
+
**What leaves your machine (and when):**
|
|
450
|
+
|
|
451
|
+
| Event | What's sent | To where |
|
|
452
|
+
|---|---|---|
|
|
453
|
+
| `gadriel login` | OAuth flow only | `app.gadriel.ai` |
|
|
454
|
+
| Every scan | License-gate HEAD request: `{ token, license_id }` | `app.gadriel.ai/api/v1/license/verify` |
|
|
455
|
+
| `gadriel sync` (opt-in) | Findings (you control what; default = nothing) | Your portal account |
|
|
456
|
+
| Telemetry (opt-in, off by default) | Aggregate counters: scan count, command names, exit codes, latency buckets | `app.gadriel.ai/api/v1/telemetry` |
|
|
457
|
+
|
|
458
|
+
No CDNs. No third-party trackers. No source code shipping anywhere, ever. The [ADR-090 doc](https://github.com/Gadriel-ai/preflight/blob/main/docs/adr/ADR-090-privacy-by-default.md) covers the threat model in detail.
|
|
459
|
+
|
|
460
|
+
### Air-gapped mode
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
export GADRIEL_OFFLINE=true
|
|
464
|
+
gadriel code scan .
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
Skips license-gate, telemetry, and any control-plane I/O. Requires a previously-fetched license cache (`gadriel auth refresh` while online).
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## Performance
|
|
472
|
+
|
|
473
|
+
Numbers from a 2024 MacBook Pro M3 Pro / linux x64 (i7-12700K, NVMe):
|
|
474
|
+
|
|
475
|
+
| Codebase | Files | Scan time (cold) | Scan time (warm) |
|
|
476
|
+
|---|---|---|---|
|
|
477
|
+
| Small (1k LOC, Python) | 12 | 0.4s | 0.1s |
|
|
478
|
+
| Medium (50k LOC, monorepo) | 1,250 | 8s | 2s |
|
|
479
|
+
| Large (500k LOC, polyglot) | 12,000 | 45s | 12s |
|
|
480
|
+
| RVF substrate full-scan | 50,000 | 3m | 35s |
|
|
481
|
+
|
|
482
|
+
Warm runs use the `.gadriel/cache/` graph store + incremental file-hash diffing. Cold runs build the whole codebase graph from scratch.
|
|
483
|
+
|
|
484
|
+
`gadriel code watch` runs sub-300ms per file save (SAST + secrets only; SBOM / SCA happen on full scans).
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
## Supported platforms
|
|
489
|
+
|
|
490
|
+
| OS | Architecture | npm package | Status |
|
|
491
|
+
|---|---|---|---|
|
|
492
|
+
| Linux | x86_64 | `@gadriel/cli-linux-x64` | ✅ stable |
|
|
493
|
+
| Linux | aarch64 | `@gadriel/cli-linux-arm64` | ✅ stable |
|
|
494
|
+
| macOS | x86_64 (Intel) | `@gadriel/cli-darwin-x64` | ✅ stable |
|
|
495
|
+
| macOS | aarch64 (Apple Silicon) | `@gadriel/cli-darwin-arm64` | ✅ stable |
|
|
496
|
+
| Windows | x86_64 | `@gadriel/cli-win32-x64` | ✅ stable |
|
|
497
|
+
| Linux | x86_64 (musl) | — | 🛠 build from source (`cargo install`) |
|
|
498
|
+
| FreeBSD | x86_64 | — | 🛠 build from source |
|
|
499
|
+
| Windows | aarch64 | — | 🛠 build from source |
|
|
500
|
+
|
|
501
|
+
For unsupported platforms, build from source — see [Install via cargo](#via-cargo).
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## Troubleshooting
|
|
506
|
+
|
|
507
|
+
### `gadriel: command not found` after `npm install -g`
|
|
508
|
+
|
|
509
|
+
Either your npm global `bin` directory isn't on `PATH`, or the optional platform package was skipped. Check:
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
npm config get prefix # global bin lives in $PREFIX/bin
|
|
513
|
+
echo $PATH | tr ':' '\n' | grep -i npm
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
If `optionalDependencies` was skipped (common with corporate npm mirrors or `--no-optional`):
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
npm install -g gadriel --include=optional --force
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
### "platform package was not installed"
|
|
523
|
+
|
|
524
|
+
Same root cause as above — fix with `--include=optional`. The shim's error message will tell you the exact platform package name.
|
|
525
|
+
|
|
526
|
+
### macOS Gatekeeper: "cannot be opened because the developer cannot be verified"
|
|
527
|
+
|
|
528
|
+
The current beta binaries are not yet Apple-notarized (tracked for v1.0). Workaround:
|
|
529
|
+
|
|
530
|
+
```bash
|
|
531
|
+
xattr -d com.apple.quarantine "$(which gadriel)"
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
Or via UI: **System Settings → Privacy & Security → "Allow Anyway"** after the first failed launch.
|
|
535
|
+
|
|
536
|
+
### Windows SmartScreen: "Windows protected your PC"
|
|
537
|
+
|
|
538
|
+
Same root cause — binary isn't yet signed with a CA-issued cert. Click **More info → Run anyway**. Tracked for v1.0.
|
|
539
|
+
|
|
540
|
+
### `gadriel doctor` reports issues
|
|
541
|
+
|
|
542
|
+
`doctor` is the diagnostic tool — run it first whenever something feels wrong:
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
gadriel doctor
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
It checks: PATH, OS keyring access, portal connectivity, license validity, write perms to `.security/`, `.claude/` integration, MCP server health, cache integrity.
|
|
549
|
+
|
|
550
|
+
### Scan is slow on the first run
|
|
551
|
+
|
|
552
|
+
That's normal — the cold scan builds the full codebase graph. Subsequent scans use the incremental cache and are ~5–10× faster. Force a rebuild with:
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
gadriel code scan --no-cache
|
|
556
|
+
# or wipe the cache and start fresh:
|
|
557
|
+
rm -rf .gadriel/cache/ && gadriel code scan .
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### `gadriel sync` says "license expired"
|
|
561
|
+
|
|
562
|
+
Your portal token expired (30-day rotation by default):
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
gadriel login
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
Re-mints a token and stores it in the keyring.
|
|
569
|
+
|
|
570
|
+
### Issue not covered here?
|
|
571
|
+
|
|
572
|
+
- Run `gadriel doctor` and paste the output.
|
|
573
|
+
- Search [open issues](https://github.com/Gadriel-ai/preflight/issues).
|
|
574
|
+
- File a new issue with the doctor output + repro steps.
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
## Versioning & support
|
|
579
|
+
|
|
580
|
+
- **Current version:** 0.9.1 — see [CHANGELOG.md](./CHANGELOG.md) for release history.
|
|
581
|
+
- **Versioning policy:** [SemVer](https://semver.org/). Pre-1.0 releases may include breaking changes between minor versions; the CHANGELOG calls them out explicitly.
|
|
582
|
+
- **Support window:** the last 2 minor versions receive security patches. Older versions are best-effort.
|
|
583
|
+
- **Release cadence:** roughly monthly minor releases, ad-hoc patches.
|
|
584
|
+
|
|
585
|
+
### Getting help
|
|
586
|
+
|
|
587
|
+
- **Documentation:** [docs.gadriel.ai](https://docs.gadriel.ai)
|
|
588
|
+
- **Issues / bugs / feature requests:** [GitHub Issues](https://github.com/Gadriel-ai/preflight/issues)
|
|
589
|
+
- **Beta program:** [app.gadriel.ai/beta](https://app.gadriel.ai/beta) (request access)
|
|
590
|
+
- **Security disclosures:** `security@gadriel.ai` (please don't open public issues for vulns)
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
## License
|
|
595
|
+
|
|
596
|
+
MIT — see [LICENSE](https://github.com/Gadriel-ai/preflight/blob/main/LICENSE).
|
|
597
|
+
|
|
598
|
+
Copyright © Gadriel team.
|
package/bin/gadriel.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Gadriel CLI launcher.
|
|
3
|
+
//
|
|
4
|
+
// At install time, npm picks exactly one of the five
|
|
5
|
+
// `@gadriel/cli-<platform>-<arch>` packages declared as
|
|
6
|
+
// optionalDependencies — the one whose `os` + `cpu` fields in its
|
|
7
|
+
// package.json match the host. This shim resolves that package, finds
|
|
8
|
+
// its bundled binary, and execs it with stdio inherited.
|
|
9
|
+
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
import { createRequire } from "node:module";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
import { platform, arch, exit, argv, env } from "node:process";
|
|
16
|
+
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
|
|
20
|
+
// Map Node's platform/arch to our npm-package suffix. Anything outside
|
|
21
|
+
// the matrix here is genuinely unsupported (e.g. linux-mips, freebsd).
|
|
22
|
+
const SUPPORTED = {
|
|
23
|
+
"linux-x64": { pkg: "@gadriel/cli-linux-x64", ext: "" },
|
|
24
|
+
"linux-arm64": { pkg: "@gadriel/cli-linux-arm64", ext: "" },
|
|
25
|
+
"darwin-x64": { pkg: "@gadriel/cli-darwin-x64", ext: "" },
|
|
26
|
+
"darwin-arm64": { pkg: "@gadriel/cli-darwin-arm64", ext: "" },
|
|
27
|
+
"win32-x64": { pkg: "@gadriel/cli-win32-x64", ext: ".exe" },
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const key = `${platform}-${arch}`;
|
|
31
|
+
const target = SUPPORTED[key];
|
|
32
|
+
|
|
33
|
+
if (!target) {
|
|
34
|
+
console.error(
|
|
35
|
+
`gadriel: unsupported platform "${key}". Supported: ${Object.keys(SUPPORTED).join(", ")}.\n` +
|
|
36
|
+
`If you need this platform, please open an issue:\n` +
|
|
37
|
+
` https://github.com/Gadriel-ai/preflight/issues`
|
|
38
|
+
);
|
|
39
|
+
exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Resolve the platform package's directory by asking Node for its
|
|
43
|
+
// package.json — works whether npm hoisted it or kept it nested.
|
|
44
|
+
let pkgRoot;
|
|
45
|
+
try {
|
|
46
|
+
const pkgJson = require.resolve(`${target.pkg}/package.json`);
|
|
47
|
+
pkgRoot = dirname(pkgJson);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error(
|
|
50
|
+
`gadriel: platform package "${target.pkg}" was not installed.\n` +
|
|
51
|
+
`\n` +
|
|
52
|
+
`This usually means npm skipped optionalDependencies. Re-install with:\n` +
|
|
53
|
+
` npm install gadriel --include=optional\n` +
|
|
54
|
+
`\n` +
|
|
55
|
+
`Or install the platform package directly:\n` +
|
|
56
|
+
` npm install -g ${target.pkg}\n`
|
|
57
|
+
);
|
|
58
|
+
exit(1);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const binPath = join(pkgRoot, "bin", `gadriel${target.ext}`);
|
|
62
|
+
if (!existsSync(binPath)) {
|
|
63
|
+
console.error(
|
|
64
|
+
`gadriel: binary missing at ${binPath}.\n` +
|
|
65
|
+
`Reinstall: npm install -g gadriel --force --include=optional`
|
|
66
|
+
);
|
|
67
|
+
exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Exec the binary with the user's args. stdio inherited so prompts /
|
|
71
|
+
// progress bars / colors work normally. spawnSync returns control with
|
|
72
|
+
// the child's exit code, which we propagate.
|
|
73
|
+
const result = spawnSync(binPath, argv.slice(2), {
|
|
74
|
+
stdio: "inherit",
|
|
75
|
+
env,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (result.error) {
|
|
79
|
+
if (result.error.code === "EACCES") {
|
|
80
|
+
console.error(
|
|
81
|
+
`gadriel: binary at ${binPath} is not executable.\n` +
|
|
82
|
+
`Try: chmod +x "${binPath}"\n` +
|
|
83
|
+
`Or reinstall: npm install -g gadriel --force --include=optional`
|
|
84
|
+
);
|
|
85
|
+
} else {
|
|
86
|
+
console.error(`gadriel: failed to spawn binary: ${result.error.message}`);
|
|
87
|
+
}
|
|
88
|
+
exit(1);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
exit(result.status ?? 1);
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gadriel",
|
|
3
|
+
"version": "0.9.8",
|
|
4
|
+
"description": "Gadriel - Code-security CLI for AI-assisted development",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"security",
|
|
7
|
+
"sast",
|
|
8
|
+
"cli",
|
|
9
|
+
"audit",
|
|
10
|
+
"ai-coding",
|
|
11
|
+
"scanner"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://gadriel.ai",
|
|
14
|
+
"bugs": "https://github.com/Gadriel-ai/preflight/issues",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/Gadriel-ai/preflight.git",
|
|
18
|
+
"directory": "npm/gadriel"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Gadriel team",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"bin": {
|
|
24
|
+
"gadriel": "bin/gadriel.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"bin/gadriel.js",
|
|
28
|
+
"scripts/postinstall.js",
|
|
29
|
+
"README.md",
|
|
30
|
+
"CHANGELOG.md"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"postinstall": "node scripts/postinstall.js || true"
|
|
34
|
+
},
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=16"
|
|
37
|
+
},
|
|
38
|
+
"optionalDependencies": {
|
|
39
|
+
"@gadriel/cli-linux-x64": "0.9.8",
|
|
40
|
+
"@gadriel/cli-linux-arm64": "0.9.8",
|
|
41
|
+
"@gadriel/cli-darwin-x64": "0.9.8",
|
|
42
|
+
"@gadriel/cli-darwin-arm64": "0.9.8",
|
|
43
|
+
"@gadriel/cli-win32-x64": "0.9.8"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Lightweight install-time sanity check.
|
|
3
|
+
//
|
|
4
|
+
// We do NOT download anything here (the optionalDependencies pattern
|
|
5
|
+
// is the whole point: npm fetches the right binary directly). This
|
|
6
|
+
// script only verifies a platform package was resolved and prints a
|
|
7
|
+
// helpful message if it wasn't, so users find out at install time
|
|
8
|
+
// instead of at first invocation.
|
|
9
|
+
//
|
|
10
|
+
// `|| true` in package.json means a missing platform package never
|
|
11
|
+
// fails the install — `bin/gadriel.js` will give a more actionable
|
|
12
|
+
// error on the first run.
|
|
13
|
+
|
|
14
|
+
import { createRequire } from "node:module";
|
|
15
|
+
import { platform, arch } from "node:process";
|
|
16
|
+
|
|
17
|
+
const require = createRequire(import.meta.url);
|
|
18
|
+
|
|
19
|
+
const MAP = {
|
|
20
|
+
"linux-x64": "@gadriel/cli-linux-x64",
|
|
21
|
+
"linux-arm64": "@gadriel/cli-linux-arm64",
|
|
22
|
+
"darwin-x64": "@gadriel/cli-darwin-x64",
|
|
23
|
+
"darwin-arm64": "@gadriel/cli-darwin-arm64",
|
|
24
|
+
"win32-x64": "@gadriel/cli-win32-x64",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const key = `${platform}-${arch}`;
|
|
28
|
+
const target = MAP[key];
|
|
29
|
+
|
|
30
|
+
if (!target) {
|
|
31
|
+
console.warn(
|
|
32
|
+
`gadriel: no prebuilt binary for ${key}. ` +
|
|
33
|
+
`Open an issue at https://github.com/Gadriel-ai/preflight/issues`
|
|
34
|
+
);
|
|
35
|
+
process.exit(0); // don't fail npm install
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
require.resolve(`${target}/package.json`);
|
|
40
|
+
// Resolved — install is good.
|
|
41
|
+
} catch {
|
|
42
|
+
console.warn(
|
|
43
|
+
`gadriel: optional platform package "${target}" was skipped by npm.\n` +
|
|
44
|
+
` If 'gadriel' fails to run, reinstall with:\n` +
|
|
45
|
+
` npm install -g gadriel --include=optional`
|
|
46
|
+
);
|
|
47
|
+
}
|