@cdot65/prisma-airs-cli 4.3.0 → 4.3.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 CHANGED
@@ -5,7 +5,7 @@
5
5
  [![CI](https://github.com/cdot65/prisma-airs-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/cdot65/prisma-airs-cli/actions/workflows/ci.yml)
6
6
  [![npm](https://img.shields.io/npm/v/@cdot65/prisma-airs-cli)](https://www.npmjs.com/package/@cdot65/prisma-airs-cli)
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
8
- [![Node 20+](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org/)
8
+ [![Node 20.17+ / 22.13+ / 24+](https://img.shields.io/badge/node-20.17%2B%20%7C%2022.13%2B%20%7C%2024%2B-brightgreen.svg)](https://nodejs.org/)
9
9
 
10
10
  **Full operational coverage over Palo Alto Prisma AIRS AI security — guardrail refinement, runtime scanning, AI red teaming, AI Gateway, and model security.**
11
11
 
@@ -30,7 +30,7 @@ npm install -g @cdot65/prisma-airs-cli
30
30
  airs --version
31
31
  ```
32
32
 
33
- Requires **Node.js >= 20**. Also available via `pnpm add -g`, `npx`, or as a [Docker image](https://github.com/cdot65/prisma-airs-cli/pkgs/container/prisma-airs-cli). See the [installation guide](https://cdot65.github.io/prisma-airs-cli/getting-started/installation/) for details.
33
+ Requires **Node.js 20.17+, 22.13+, or 24+** (exact engine range: `^20.17.0 || ^22.13.0 || >=23.5.0`). Also available via `pnpm add -g`, `npx`, or as a [Docker image](https://github.com/cdot65/prisma-airs-cli/pkgs/container/prisma-airs-cli). See the [installation guide](https://cdot65.github.io/prisma-airs-cli/getting-started/installation/) for details.
34
34
 
35
35
  ## Quick Start
36
36
 
package/dist/cli/index.js CHANGED
@@ -5220,17 +5220,23 @@ import { randomUUID } from "crypto";
5220
5220
  import { readFile as readFile4 } from "fs/promises";
5221
5221
  import { init, Scanner } from "@cdot65/prisma-airs-sdk";
5222
5222
  var DOCTOR_TIMEOUT_MS = 5e3;
5223
- var MIN_NODE_MAJOR = 20;
5223
+ var SUPPORTED_NODE_VERSIONS = "^20.17.0 || ^22.13.0 || >=23.5.0";
5224
5224
  function checkNodeVersion(version = process.version) {
5225
- const major = Number.parseInt(version.replace(/^v/, ""), 10);
5226
- if (Number.isFinite(major) && major >= MIN_NODE_MAJOR) {
5227
- return { name: "Node.js version", status: "pass", detail: `${version} (>= 20 required)` };
5225
+ const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.exec(version);
5226
+ const [major, minor, patch] = match ? match.slice(1).map(Number) : [];
5227
+ const supported = [major, minor, patch].every(Number.isSafeInteger) && (major === 20 && minor >= 17 || major === 22 && minor >= 13 || major === 23 && minor >= 5 || major >= 24);
5228
+ if (supported) {
5229
+ return {
5230
+ name: "Node.js version",
5231
+ status: "pass",
5232
+ detail: `${version} (${SUPPORTED_NODE_VERSIONS} required)`
5233
+ };
5228
5234
  }
5229
5235
  return {
5230
5236
  name: "Node.js version",
5231
5237
  status: "fail",
5232
- detail: `${version} is below the required Node ${MIN_NODE_MAJOR}`,
5233
- hint: `Upgrade to Node ${MIN_NODE_MAJOR}+ (e.g. via nvm or your package manager)`
5238
+ detail: `${version} does not satisfy ${SUPPORTED_NODE_VERSIONS}`,
5239
+ hint: "Use a supported Node runtime: 20.17+, 22.13+, or 24+ (e.g. via nvm or your package manager)"
5234
5240
  };
5235
5241
  }
5236
5242
  async function checkConfigFile(filePath) {
@@ -8489,6 +8495,30 @@ function register2(dlp) {
8489
8495
  });
8490
8496
  }
8491
8497
 
8498
+ // src/cli/renderer/dlp-generate.ts
8499
+ function renderGenerateSummary(summary, output) {
8500
+ if (output === "json") {
8501
+ console.log(JSON.stringify(summary, null, 2));
8502
+ return;
8503
+ }
8504
+ ui.header("DLP Test-File Generation");
8505
+ ui.keyValue([
8506
+ ["Output", summary.out],
8507
+ ["Seed", summary.seed],
8508
+ ["Clean", summary.clean],
8509
+ ["Dirty", summary.dirty],
8510
+ ["Manifest", summary.manifestPath]
8511
+ ]);
8512
+ ui.table(
8513
+ [
8514
+ { key: "format", label: "Format" },
8515
+ { key: "clean", label: "Clean" },
8516
+ { key: "dirty", label: "Dirty" }
8517
+ ],
8518
+ Object.entries(summary.byFormat).map(([format, counts]) => ({ format, ...counts }))
8519
+ );
8520
+ }
8521
+
8492
8522
  // src/cli/commands/dlp/generate.ts
8493
8523
  var ALL_FORMATS = ["pdf", "png", "jpeg", "svg", "docx"];
8494
8524
  var OPTIONAL_DEPS_HINT = "DLP generate requires optional dependencies. Install them with: pnpm add sharp pdf-lib docx piexifjs";
@@ -8517,39 +8547,29 @@ function parseTypes(value) {
8517
8547
  return types;
8518
8548
  }
8519
8549
  function register3(parent) {
8520
- parent.command("generate").description(
8550
+ const command = parent.command("generate").description(
8521
8551
  "Generate clean + dirty DLP test files (synthetic sensitive data) across PDF/PNG/JPEG/SVG/DOCX"
8522
- ).option("--types <list>", "Comma list: pdf,png,jpeg,svg,docx (or all)", "all").option("--count <n>", "Clean files per type", "1").option("--out <dir>", "Output base directory", "./temp").option("--techniques <list>", "all or comma list of technique ids", "all").option("--seed <n>", "Seed for reproducible payloads").option("--output <format>", "Summary format: pretty or json", "pretty").action(async (opts) => {
8552
+ ).option("--types <list>", "Comma list: pdf,png,jpeg,svg,docx (or all)", "all").option("--count <n>", "Clean files per type", "1").option("--out <dir>", "Output base directory", "./temp").option("--techniques <list>", "all or comma list of technique ids", "all").option("--seed <n>", "Safe integer seed for reproducible payloads").option("--output <format>", "Summary format: pretty or json", "pretty").action(async (opts) => {
8523
8553
  let types;
8524
8554
  try {
8525
8555
  types = parseTypes(opts.types);
8526
8556
  } catch (err) {
8527
8557
  usageError(err instanceof Error ? err.message : String(err));
8528
8558
  }
8529
- const count = Number.parseInt(opts.count, 10);
8530
- if (!Number.isInteger(count) || count < 1) {
8531
- usageError("--count must be a positive integer");
8559
+ const count = Number(opts.count);
8560
+ if (!/^\d+$/.test(opts.count) || !Number.isSafeInteger(count) || count < 1) {
8561
+ usageError("--count must be a positive safe integer");
8532
8562
  }
8533
8563
  const techniques = opts.techniques === "all" ? "all" : opts.techniques.split(",").map((t) => t.trim());
8534
- const seed = opts.seed === void 0 ? void 0 : Number.parseInt(opts.seed, 10);
8564
+ const seed = opts.seed === void 0 ? void 0 : Number(opts.seed);
8565
+ if (seed !== void 0 && (!/^-?\d+$/.test(opts.seed) || !Number.isSafeInteger(seed))) {
8566
+ usageError("--seed must be a safe integer");
8567
+ }
8535
8568
  try {
8569
+ const output = await resolveOutput(command, opts, { allowed: ["pretty", "json"] });
8536
8570
  const generateCorpus = await loadGenerateCorpus();
8537
8571
  const summary = await generateCorpus({ types, count, out: opts.out, techniques, seed });
8538
- if (opts.output === "json") {
8539
- console.log(JSON.stringify(summary, null, 2));
8540
- return;
8541
- }
8542
- ui.header("DLP Test-File Generation");
8543
- ui.keyValue([
8544
- ["Output", summary.out],
8545
- ["Seed", summary.seed],
8546
- ["Clean", summary.clean],
8547
- ["Dirty", summary.dirty],
8548
- ["Manifest", summary.manifestPath]
8549
- ]);
8550
- for (const [fmt, counts] of Object.entries(summary.byFormat)) {
8551
- ui.dim(`${fmt.padEnd(5)} clean=${counts.clean} dirty=${counts.dirty}`);
8552
- }
8572
+ renderGenerateSummary(summary, output);
8553
8573
  } catch (err) {
8554
8574
  fail(err);
8555
8575
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cdot65/prisma-airs-cli",
3
3
  "packageManager": "pnpm@10.6.5",
4
- "version": "4.3.0",
4
+ "version": "4.3.1",
5
5
  "description": "CLI and library for Palo Alto Prisma AIRS — guardrail refinement, AI red teaming, model security scanning, profile audits",
6
6
  "type": "module",
7
7
  "main": "dist/index.js",
@@ -14,11 +14,13 @@
14
14
  },
15
15
  "scripts": {
16
16
  "build": "tsup",
17
- "prepublishOnly": "pnpm run build",
17
+ "prepublishOnly": "pnpm audit:prod && pnpm run build",
18
18
  "dev": "tsx src/cli/index.ts",
19
19
  "test": "vitest run",
20
20
  "test:watch": "vitest",
21
21
  "test:coverage": "vitest run --coverage",
22
+ "test:release": "node --test .github/scripts/*.test.mjs",
23
+ "audit:prod": "pnpm audit --prod --audit-level low",
22
24
  "test:e2e": "vitest run --config vitest.e2e.config.ts",
23
25
  "test:e2e:aigateway": "vitest run --config vitest.e2e.config.ts tests/e2e/aigateway-cli.e2e.spec.ts",
24
26
  "lint": "biome check --config-path config .",
@@ -49,7 +51,7 @@
49
51
  "local:unlink": "pnpm uninstall --global @cdot65/prisma-airs-cli"
50
52
  },
51
53
  "engines": {
52
- "node": ">=20.0.0"
54
+ "node": "^20.17.0 || ^22.13.0 || >=23.5.0"
53
55
  },
54
56
  "repository": {
55
57
  "type": "git",
@@ -62,8 +64,8 @@
62
64
  "chalk": "^5.6.2",
63
65
  "commander": "^14.0.3",
64
66
  "dotenv": "^17.3.1",
65
- "js-yaml": "^4.1.1",
66
- "nanoid": "^5.0.0",
67
+ "js-yaml": "^4.3.2",
68
+ "nanoid": "^5.1.16",
67
69
  "p-limit": "^6.0.0",
68
70
  "zod": "^3.24.0"
69
71
  },
@@ -84,6 +86,6 @@
84
86
  "docx": "^9.6.1",
85
87
  "pdf-lib": "^1.17.1",
86
88
  "piexifjs": "^1.0.6",
87
- "sharp": "^0.34.5"
89
+ "sharp": "^0.35.4"
88
90
  }
89
91
  }