@pretense/cli 0.6.21 → 0.6.23
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 +47 -0
- package/dist/{chunk-2BMR5XBU.js → chunk-Y7SXGTHU.js} +1 -1
- package/dist/index.js +30 -9
- package/dist/postinstall.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -324,6 +324,22 @@ provider automatically (`claude` → Anthropic, `cursor`/`code` → OpenAI-compa
|
|
|
324
324
|
on your `PATH`, `run` prints an install hint and exits non-zero instead of
|
|
325
325
|
crashing — and it never tears down a proxy it did not start.
|
|
326
326
|
|
|
327
|
+
### Works with your LLM
|
|
328
|
+
|
|
329
|
+
`pretense run` sets the base-URL env var that each tool reads. The proxy mutates
|
|
330
|
+
all three provider request shapes (`/v1/messages`, `/v1/chat/completions`,
|
|
331
|
+
`/v1beta/…/generateContent`), so the same mutation engine covers every tool
|
|
332
|
+
below.
|
|
333
|
+
|
|
334
|
+
| Tool | Provider | Base-URL env var(s) `run` sets |
|
|
335
|
+
| --- | --- | --- |
|
|
336
|
+
| `claude`, `claude-code` | Anthropic | `ANTHROPIC_BASE_URL` |
|
|
337
|
+
| `cursor`, `codex` | OpenAI-compatible | `OPENAI_BASE_URL` (with a `/v1` suffix) |
|
|
338
|
+
| `gemini` | Google | `GEMINI_BASE_URL` **and** `GOOGLE_GEMINI_BASE_URL` |
|
|
339
|
+
|
|
340
|
+
For any other tool, pass `--provider anthropic|openai|google` to pick the
|
|
341
|
+
mapping.
|
|
342
|
+
|
|
327
343
|
Read this before you rely on the proxy:
|
|
328
344
|
|
|
329
345
|
- **npm install only.** `start` crashes on the `curl | sh` binary
|
|
@@ -543,10 +559,41 @@ of **36** compliance frameworks vendored from the `pretense-compliance-standards
|
|
|
543
559
|
dataset (`pretense audit --list-frameworks` prints them). The two lists are not
|
|
544
560
|
the same thing and should never be conflated.
|
|
545
561
|
|
|
562
|
+
## Git hooks
|
|
563
|
+
|
|
564
|
+
`pretense install` writes Pretense Git hooks into the current repository so a
|
|
565
|
+
secret cannot reach a commit or a push:
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
pretense install # installs both pre-commit and pre-push hooks
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
<!-- docs-exec:expect "pretense install" 1 — the isolated session dir is deliberately not a git repo, so install has no .git to write into and exits 1 -->
|
|
572
|
+
|
|
573
|
+
Pass `--mode pre-commit` or `--mode pre-push` to install just one, and `--force`
|
|
574
|
+
to overwrite an existing hook. `pretense install` must be run from a repository
|
|
575
|
+
root; it exits `1` with a named error when there is no `.git` directory.
|
|
576
|
+
|
|
577
|
+
- The **pre-commit** hook runs `pretense scan pre-commit` over your staged files.
|
|
578
|
+
A commit that contains an AWS access key (`AKIA…`) is blocked with an
|
|
579
|
+
`aws-access-key` finding and never lands.
|
|
580
|
+
- The **pre-push** hook runs `pretense scan pre-push` over the commits being
|
|
581
|
+
pushed (it reads git's pre-push ref lines on stdin), catching anything that
|
|
582
|
+
slipped past pre-commit.
|
|
583
|
+
|
|
546
584
|
## Supported languages
|
|
547
585
|
|
|
548
586
|
TypeScript, JavaScript, Python, Go, Java, C#, Ruby, Rust.
|
|
549
587
|
|
|
588
|
+
## Supported platforms
|
|
589
|
+
|
|
590
|
+
The CLI runs on **macOS** (x64 and arm64), **Linux** (glibc and musl) and
|
|
591
|
+
**Windows**. L1 detection (regex, 98 patterns) runs on all of them with no native
|
|
592
|
+
dependencies. L2 detection needs the native `@pretense/scanner-rs` addon, which
|
|
593
|
+
is not published for every platform; where it is missing the CLI degrades to L1
|
|
594
|
+
in full and prints `L2 unavailable` rather than reporting less — see
|
|
595
|
+
[Detection levels](#detection-levels-l1-and-l2).
|
|
596
|
+
|
|
550
597
|
## Detection levels (L1 and L2)
|
|
551
598
|
|
|
552
599
|
<!-- OBSERVED, not specified. Every output block below was produced on
|
|
@@ -17,7 +17,7 @@ function versionFromPackageJson() {
|
|
|
17
17
|
return void 0;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
var PRETENSE_VERSION = (true ? "0.6.
|
|
20
|
+
var PRETENSE_VERSION = (true ? "0.6.23" : void 0) ?? versionFromPackageJson() ?? "0.0.0-unknown";
|
|
21
21
|
|
|
22
22
|
export {
|
|
23
23
|
PRETENSE_VERSION
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
PRETENSE_VERSION
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Y7SXGTHU.js";
|
|
5
5
|
import {
|
|
6
6
|
__commonJS,
|
|
7
7
|
__toESM,
|
|
@@ -16657,11 +16657,11 @@ function versionFromCliPackageJson() {
|
|
|
16657
16657
|
return void 0;
|
|
16658
16658
|
}
|
|
16659
16659
|
function productVersion() {
|
|
16660
|
-
return override ?? (true ? "0.6.
|
|
16660
|
+
return override ?? (true ? "0.6.23" : void 0) ?? versionFromCliPackageJson() ?? "0.0.0-unknown";
|
|
16661
16661
|
}
|
|
16662
16662
|
var UNKNOWN_COMMIT = "unknown";
|
|
16663
16663
|
function bakedCommitSha() {
|
|
16664
|
-
return "
|
|
16664
|
+
return "3bc1a6f92239a8ea27af2a6558e968baf4b94d71".length > 0 ? "3bc1a6f92239a8ea27af2a6558e968baf4b94d71" : UNKNOWN_COMMIT;
|
|
16665
16665
|
}
|
|
16666
16666
|
var FEATURE_TIERS = {
|
|
16667
16667
|
compliance_export: "pro",
|
|
@@ -18089,7 +18089,12 @@ ${_upgradeTier === "enterprise" ? "Enterprise offers unlimited mutations \u2014
|
|
|
18089
18089
|
action: "blocked",
|
|
18090
18090
|
secretsBlocked: secretsTokenized,
|
|
18091
18091
|
piiRedacted: piiTokenized,
|
|
18092
|
-
|
|
18092
|
+
// TRUTHFUL COUNT: every span this proxy rewrote before egress, of any
|
|
18093
|
+
// kind (identifier tokens + tokenized secrets/PII) — the SAME number the
|
|
18094
|
+
// audit row logs as `mutationsApplied`. `tokensMutated` alone counted
|
|
18095
|
+
// only code identifiers, so a secret-only mutation pushed mutationCount:0
|
|
18096
|
+
// to the live dashboard even though a secret WAS mutated on the wire.
|
|
18097
|
+
mutationCount: mutationsApplied,
|
|
18093
18098
|
bytesScanned: fullText.length,
|
|
18094
18099
|
provider,
|
|
18095
18100
|
findings: riskResult.factors.map((f) => f.name),
|
|
@@ -18171,7 +18176,12 @@ ${_upgradeTier === "enterprise" ? "Enterprise offers unlimited mutations \u2014
|
|
|
18171
18176
|
action: "error",
|
|
18172
18177
|
secretsBlocked: secretsTokenized,
|
|
18173
18178
|
piiRedacted: piiTokenized,
|
|
18174
|
-
|
|
18179
|
+
// TRUTHFUL COUNT: every span this proxy rewrote before egress, of any
|
|
18180
|
+
// kind (identifier tokens + tokenized secrets/PII) — the SAME number the
|
|
18181
|
+
// audit row logs as `mutationsApplied`. `tokensMutated` alone counted
|
|
18182
|
+
// only code identifiers, so a secret-only mutation pushed mutationCount:0
|
|
18183
|
+
// to the live dashboard even though a secret WAS mutated on the wire.
|
|
18184
|
+
mutationCount: mutationsApplied,
|
|
18175
18185
|
bytesScanned: originalSize,
|
|
18176
18186
|
provider,
|
|
18177
18187
|
findings: ["upstream_unreachable"],
|
|
@@ -18210,12 +18220,23 @@ ${_upgradeTier === "enterprise" ? "Enterprise offers unlimited mutations \u2014
|
|
|
18210
18220
|
action: anyTokenized ? "mutated" : "allowed",
|
|
18211
18221
|
secretsBlocked: secretsTokenized,
|
|
18212
18222
|
piiRedacted: piiTokenized,
|
|
18213
|
-
|
|
18223
|
+
// TRUTHFUL COUNT: every span rewritten before egress (identifier tokens +
|
|
18224
|
+
// tokenized secrets/PII), matching the audit row's `mutationsApplied`. Using
|
|
18225
|
+
// `tokensMutated` here made the live dashboard show mutationCount:0 for a
|
|
18226
|
+
// request whose only mutation was a tokenized secret — the exact "meter logs
|
|
18227
|
+
// 0" defect. severity now reflects it too (mutationCount>0 -> 3, not 1).
|
|
18228
|
+
mutationCount: mutationsApplied,
|
|
18214
18229
|
bytesScanned: originalSize,
|
|
18215
18230
|
provider,
|
|
18216
|
-
//
|
|
18217
|
-
//
|
|
18218
|
-
|
|
18231
|
+
// Detector KINDS that fired (e.g. "aws_access_key") — metadata only, the same
|
|
18232
|
+
// kinds the audit row records as `detectorKinds`. NEVER secret VALUES or
|
|
18233
|
+
// identifier NAMES (the SSE bus carries the usage-upload privacy contract).
|
|
18234
|
+
// Plus the unscannable-skip marker so a dashboard/SIEM can alert on coverage
|
|
18235
|
+
// gaps rather than assume full coverage.
|
|
18236
|
+
findings: [
|
|
18237
|
+
...foundTypes,
|
|
18238
|
+
...skippedUnscannable > 0 ? ["skipped_unscannable_field"] : []
|
|
18239
|
+
],
|
|
18219
18240
|
sourceIp: c.req.header("x-forwarded-for") ?? c.req.header("x-real-ip")
|
|
18220
18241
|
}));
|
|
18221
18242
|
if (anyTokenized) {
|
package/dist/postinstall.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pretense/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.23",
|
|
4
4
|
"description": "Local-first AI firewall that mutates proprietary code before sending to LLM APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"tsx": "^4.0.0",
|
|
24
24
|
"typescript": "^5.4.0",
|
|
25
25
|
"vitest": "^1.0.0",
|
|
26
|
-
"@pretense/billing": "0.1.0",
|
|
27
26
|
"@pretense/compliance-engine": "0.1.0",
|
|
28
27
|
"@pretense/protocol": "0.1.0",
|
|
29
28
|
"@pretense/learner": "0.2.0",
|
|
@@ -31,6 +30,7 @@
|
|
|
31
30
|
"@pretense/proxy": "0.1.0",
|
|
32
31
|
"@pretense/scanner": "0.2.0",
|
|
33
32
|
"@pretense/scanner-rs": "0.2.0",
|
|
33
|
+
"@pretense/billing": "0.1.0",
|
|
34
34
|
"@pretense/store": "0.2.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|