@pretense/cli 0.6.22 → 0.6.24
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-BWS6UMKL.js → chunk-AWXABIHH.js} +1 -1
- package/dist/index.js +38 -10
- package/dist/postinstall.js +1 -1
- package/package.json +3 -3
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.24" : 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-AWXABIHH.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.24" : void 0) ?? versionFromCliPackageJson() ?? "0.0.0-unknown";
|
|
16661
16661
|
}
|
|
16662
16662
|
var UNKNOWN_COMMIT = "unknown";
|
|
16663
16663
|
function bakedCommitSha() {
|
|
16664
|
-
return "
|
|
16664
|
+
return "b258672fe5eb6d72b12faf92d12452d06dfa8ab2".length > 0 ? "b258672fe5eb6d72b12faf92d12452d06dfa8ab2" : UNKNOWN_COMMIT;
|
|
16665
16665
|
}
|
|
16666
16666
|
var FEATURE_TIERS = {
|
|
16667
16667
|
compliance_export: "pro",
|
|
@@ -18634,6 +18634,20 @@ function planToTier(plan) {
|
|
|
18634
18634
|
return null;
|
|
18635
18635
|
}
|
|
18636
18636
|
}
|
|
18637
|
+
function parseEntitlement(body) {
|
|
18638
|
+
const raw2 = body["entitlement"];
|
|
18639
|
+
if (!raw2 || typeof raw2 !== "object") return void 0;
|
|
18640
|
+
const e = raw2;
|
|
18641
|
+
const effectivePlan = planToTier(e["effectivePlan"]);
|
|
18642
|
+
const planOnRecord = planToTier(e["planOnRecord"]);
|
|
18643
|
+
if (effectivePlan === null && planOnRecord === null) return void 0;
|
|
18644
|
+
return {
|
|
18645
|
+
effectivePlan,
|
|
18646
|
+
planOnRecord,
|
|
18647
|
+
comped: e["comped"] === true,
|
|
18648
|
+
hasActiveSubscription: e["hasActiveSubscription"] === true
|
|
18649
|
+
};
|
|
18650
|
+
}
|
|
18637
18651
|
async function tierFromBackend(apiKey) {
|
|
18638
18652
|
const url = `${getConfiguredApiRoot()}/api/cli/auth/validate`;
|
|
18639
18653
|
const controller = new AbortController();
|
|
@@ -18668,7 +18682,7 @@ async function tierFromBackend(apiKey) {
|
|
|
18668
18682
|
detail: "the plan service did not report a recognizable plan"
|
|
18669
18683
|
};
|
|
18670
18684
|
}
|
|
18671
|
-
return { tier, source: "backend" };
|
|
18685
|
+
return { tier, source: "backend", entitlement: parseEntitlement(body) };
|
|
18672
18686
|
} catch (err) {
|
|
18673
18687
|
const aborted = err?.name === "AbortError";
|
|
18674
18688
|
return {
|
|
@@ -18743,8 +18757,21 @@ function tierLabel(tier) {
|
|
|
18743
18757
|
if (tier === "free") return "Free";
|
|
18744
18758
|
return `${tierName(tier)} (${priceLabel(tier)})`;
|
|
18745
18759
|
}
|
|
18760
|
+
function entitlementMismatchLines(ent) {
|
|
18761
|
+
const paidOnRecord = ent.planOnRecord === "pro" || ent.planOnRecord === "enterprise";
|
|
18762
|
+
if (ent.effectivePlan !== "free" || !paidOnRecord) return [];
|
|
18763
|
+
const planName = ent.planOnRecord === "enterprise" ? "Enterprise" : "Pro";
|
|
18764
|
+
return [
|
|
18765
|
+
`${planName} plan present, but no active subscription or comp \u2014 running as Free.`,
|
|
18766
|
+
"Attach a Stripe subscription or set the org comp flag \u2014 pretense.ai/dashboard/settings."
|
|
18767
|
+
];
|
|
18768
|
+
}
|
|
18746
18769
|
function planMismatchHint(resolution) {
|
|
18747
|
-
if (resolution.
|
|
18770
|
+
if (resolution.source !== "backend") return [];
|
|
18771
|
+
if (resolution.entitlement) {
|
|
18772
|
+
return entitlementMismatchLines(resolution.entitlement);
|
|
18773
|
+
}
|
|
18774
|
+
if (resolution.tier !== "free") return [];
|
|
18748
18775
|
return [
|
|
18749
18776
|
"Not the plan you expected? An org flagged PRO without an active",
|
|
18750
18777
|
"subscription/comp resolves to Free \u2014 see pretense.ai/dashboard/settings or contact support."
|
|
@@ -20376,7 +20403,7 @@ async function verifyApiKey(apiKey) {
|
|
|
20376
20403
|
return { outcome: "rejected", url, detail: "the API reported the key as not valid" };
|
|
20377
20404
|
}
|
|
20378
20405
|
const plan = typeof body["plan"] === "string" ? body["plan"] : void 0;
|
|
20379
|
-
return { outcome: "valid", url, plan };
|
|
20406
|
+
return { outcome: "valid", url, plan, entitlement: parseEntitlement(body) };
|
|
20380
20407
|
} catch (err) {
|
|
20381
20408
|
const aborted = err?.name === "AbortError";
|
|
20382
20409
|
return {
|
|
@@ -20495,14 +20522,15 @@ function authCommand() {
|
|
|
20495
20522
|
};
|
|
20496
20523
|
writeCredentials(creds);
|
|
20497
20524
|
if (verified) {
|
|
20498
|
-
const
|
|
20525
|
+
const mismatchLines = verification.entitlement ? entitlementMismatchLines(verification.entitlement) : String(verification.plan ?? "").trim().toLowerCase() === "free" ? [
|
|
20526
|
+
"Not the plan you expected? A PRO-flagged org without an active",
|
|
20527
|
+
"subscription/comp resolves to Free \u2014 see pretense.ai/dashboard/settings."
|
|
20528
|
+
] : [];
|
|
20499
20529
|
console.log(
|
|
20500
20530
|
chalk10.green("\n Authenticated. The key was verified by the Pretense API.") + chalk10.dim(`
|
|
20501
20531
|
Key: ${maskApiKey(opts.apiKey)}`) + chalk10.dim(`
|
|
20502
20532
|
Server: ${verification.url}`) + (verification.plan ? chalk10.dim(`
|
|
20503
|
-
Plan: ${verification.plan}`) : "") + (
|
|
20504
|
-
"\n Not the plan you expected? A PRO-flagged org without an active\n subscription/comp resolves to Free \u2014 see pretense.ai/dashboard/settings."
|
|
20505
|
-
) : "") + "\n" + storageNotice()
|
|
20533
|
+
Plan: ${verification.plan}`) : "") + (mismatchLines.length > 0 ? chalk10.dim("\n " + mismatchLines.join("\n ")) : "") + "\n" + storageNotice()
|
|
20506
20534
|
);
|
|
20507
20535
|
return;
|
|
20508
20536
|
}
|
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.24",
|
|
4
4
|
"description": "Local-first AI firewall that mutates proprietary code before sending to LLM APIs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
"vitest": "^1.0.0",
|
|
26
26
|
"@pretense/billing": "0.1.0",
|
|
27
27
|
"@pretense/compliance-engine": "0.1.0",
|
|
28
|
+
"@pretense/protocol": "0.1.0",
|
|
28
29
|
"@pretense/learner": "0.2.0",
|
|
29
30
|
"@pretense/mutator": "0.2.0",
|
|
30
31
|
"@pretense/proxy": "0.1.0",
|
|
31
32
|
"@pretense/scanner": "0.2.0",
|
|
32
33
|
"@pretense/scanner-rs": "0.2.0",
|
|
33
|
-
"@pretense/store": "0.2.0"
|
|
34
|
-
"@pretense/protocol": "0.1.0"
|
|
34
|
+
"@pretense/store": "0.2.0"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public",
|