@vibgrate/cli 2026.618.2 → 2026.623.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/DOCS.md CHANGED
@@ -185,9 +185,28 @@ vibgrate scan [path] [--format text|json|sarif|md] [--out <file>] [--fail-on war
185
185
  | `--package-manifest <file>` | — | JSON or ZIP package-version manifest used for offline/latest lookups (latest bundle: `https://github.com/vibgrate/manifests/latest-packages.zip`) |
186
186
  | `--no-local-artifacts` | — | Do not write `.vibgrate/*.json` scan artifacts to disk |
187
187
  | `--max-privacy` | — | Hardened privacy mode with minimal scanners and no local artifacts |
188
+ | `--emit-facts` | — | Emit the schema-validated HCS fact payload (an in-toto attestation predicate) to stdout instead of a scan report. Runs offline and writes nothing to the scanned tree |
188
189
 
189
190
  By default, the scan writes `.vibgrate/scan_result.json`. Use `--no-local-artifacts` or `--max-privacy` to suppress local JSON artifact files.
190
191
 
192
+ #### Emitting a fact payload for attestation (`--emit-facts`)
193
+
194
+ `--emit-facts` turns a scan into machine-readable evidence: it runs offline,
195
+ writes only a single JSON document to stdout (no source code — drift facts and
196
+ counts), and is deterministic for a given commit so re-runs are byte-stable. The
197
+ document is the predicate body for the `https://vibgrate.com/attestations/hcs/v0.5`
198
+ in-toto attestation, ready to bind to a published artifact:
199
+
200
+ ```bash
201
+ vibgrate scan . --emit-facts > vibgrate-facts.json
202
+ cosign attest --yes \
203
+ --type https://vibgrate.com/attestations/hcs/v0.5 \
204
+ --predicate vibgrate-facts.json "$IMAGE_REF"
205
+ ```
206
+
207
+ See [`docs/SIGNING-AND-PROVENANCE.md`](../../docs/SIGNING-AND-PROVENANCE.md) for the
208
+ full signing & provenance pipeline.
209
+
191
210
  For offline drift scoring, pass `--package-manifest <file>` with a downloaded manifest bundle such as `https://github.com/vibgrate/manifests/latest-packages.zip`.
192
211
 
193
212
  #### Excluding paths from a scan
@@ -274,18 +293,50 @@ vibgrate report [--in <file>] [--format md|text|json]
274
293
 
275
294
  Export SBOMs from an existing scan artifact or compare two artifacts.
276
295
 
296
+ The `sbom` command family covers supply-chain evidence — SBOM export/delta and
297
+ OpenVEX generation.
298
+
277
299
  ```bash
278
300
  vibgrate sbom export [--in <file>] [--format cyclonedx|spdx] [--out <file>]
279
301
  vibgrate sbom delta --from <file> --to <file> [--out <file>]
302
+ vibgrate sbom vex [--from <file>] [--statement <json>...] [--product <ref>] [--out <file>]
280
303
  ```
281
304
 
282
305
  | Command | Description |
283
306
  |---------|-------------|
284
307
  | `vibgrate sbom export` | Emit CycloneDX or SPDX JSON from a scan artifact |
285
308
  | `vibgrate sbom delta` | Compare dependencies between two artifacts (added/removed/changed + drift delta) |
309
+ | `vibgrate sbom vex` | Emit a spec-compliant OpenVEX document (exploitability statements) |
286
310
 
287
311
  Use this to treat SBOMs as operational intelligence instead of static compliance output.
288
312
 
313
+ #### vibgrate sbom vex
314
+
315
+ Generate a spec-compliant **OpenVEX** document (exploitability statements) for
316
+ attestation, consistent with the rest of the `sbom` family. The generator is
317
+ input-agnostic — it assembles a complete document from statements you supply, so
318
+ it works regardless of which scanner flagged the components. A zero-statement
319
+ document is valid and honest: it asserts no known affected components.
320
+
321
+ | Flag | Description |
322
+ |------|-------------|
323
+ | `--from <file>` | Read statements from a JSON file (an array, or an object with a `statements` array) |
324
+ | `--statement <json>` | Add a statement as inline JSON. Repeatable |
325
+ | `--product <ref>` | Default product applied to statements without their own (e.g. an image digest) |
326
+ | `--author <name>` | Document author (default `Vibgrate`) |
327
+ | `--timestamp <iso>` / `--id <uri>` | Pin for reproducible output |
328
+ | `--out <file>` | Write to a file (default: stdout) |
329
+
330
+ ```bash
331
+ # Attest exploitability alongside the image
332
+ vibgrate sbom vex --product "$IMAGE_REF" \
333
+ --statement '{"vulnerability":"CVE-2024-1","status":"not_affected","justification":"vulnerable_code_not_present"}' \
334
+ > openvex.json
335
+ cosign attest --yes --type openvex --predicate openvex.json "$IMAGE_REF"
336
+ ```
337
+
338
+ See [`docs/SIGNING-AND-PROVENANCE.md`](../../docs/SIGNING-AND-PROVENANCE.md).
339
+
289
340
  ---
290
341
 
291
342
  ### vibgrate push
@@ -373,15 +424,15 @@ This makes drift a formal quality gate (fitness function), not just reporting.
373
424
 
374
425
  The Upgrade Drift Score is a deterministic, versioned metric (0–100) that represents how far behind your codebase is relative to the current stable ecosystem baseline.
375
426
 
376
- **Higher score = healthier upgrade posture.**
427
+ **Lower score = healthier upgrade posture.** 0 means no drift (fully current); 100 means maximum drift. Higher is worse.
377
428
 
378
429
  ### Risk Levels
379
430
 
380
431
  | Score | Risk Level |
381
432
  | ------ | ------------------------------------ |
382
- | 70100 | **Low** — You're in good shape |
383
- | 4069 | **Moderate** — Some attention needed |
384
- | 039 | **High** — Significant upgrade debt |
433
+ | 030 | **Low** — You're in good shape |
434
+ | 3160 | **Moderate** — Some attention needed |
435
+ | 61100 | **High** — Significant upgrade debt |
385
436
 
386
437
  ### Score Components
387
438
 
package/README.md CHANGED
@@ -363,6 +363,8 @@ The CLI writes per-project score files to `.vibgrate/` inside each detected proj
363
363
  | `vibgrate report` | Generate a report from a scan artifact |
364
364
  | `vibgrate sbom export` | Export scan artifact as CycloneDX or SPDX SBOM |
365
365
  | `vibgrate sbom delta` | Compare two artifacts and report SBOM drift delta |
366
+ | `vibgrate sbom vex` | Generate an OpenVEX document (exploitability statements) for attestation |
367
+ | `vibgrate scan --emit-facts` | Emit the HCS fact payload (in-toto predicate) for artifact attestation |
366
368
  | `vibgrate init [path]` | Initialise config and `.vibgrate/` directory |
367
369
  | `vibgrate push` | Upload scan results to dashboard |
368
370
  | `vibgrate dsn create` | Generate a DSN token |
@@ -0,0 +1 @@
1
+ export{h as baselineCommand,g as runBaseline}from'./chunk-BHWXSLTQ.js';import'./chunk-I65B3ZRL.js';import'./chunk-MKDRULJ6.js';import'./chunk-XTHPCEME.js';import'./chunk-EK7ODJWE.js';
@@ -0,0 +1,2 @@
1
+ import {ua}from'./chunk-I65B3ZRL.js';import*as s from'path';import {Command}from'commander';import r from'chalk';import {execFile}from'child_process';import*as i from'fs/promises';import'os';import {promisify}from'util';var o=class{available;queue=[];constructor(t){this.available=t;}async run(t){await this.acquire();try{return await t()}finally{this.release();}}acquire(){return this.available>0?(this.available--,Promise.resolve()):new Promise(t=>this.queue.push(t))}release(){let t=this.queue.shift();t?t():this.available++;}};promisify(execFile);function v(e){return e.charCodeAt(0)===65279?e.slice(1):e}async function j(e){let t=await i.readFile(e,"utf8");return JSON.parse(v(t))}async function D(e){try{return await i.access(e),!0}catch{return false}}async function m(e){await i.mkdir(e,{recursive:true});}async function h(e,t){await m(s.dirname(e)),await i.writeFile(e,JSON.stringify(t,null,2)+`
2
+ `,"utf8");}async function E(e,t){await m(s.dirname(e)),await i.writeFile(e,t,"utf8");}var n;async function f(){if(n!==void 0)return n??void 0;try{n=(await import('./dist-AP3RH35M.js')).advancedScanHook??null;}catch{n=null;}return n??void 0}async function b(e){console.log(r.dim("Creating baseline..."));let t=await f(),c=await ua(e,{format:"text",concurrency:8},t),p=s.join(e,".vibgrate","baseline.json");await h(p,c),console.log(r.green("\u2714")+` Baseline saved to ${r.bold(".vibgrate/baseline.json")}`),console.log(r.dim(` Baseline score: ${c.drift.score}/100`));}var N=new Command("baseline").description("Create a drift baseline snapshot").argument("[path]","Path to baseline",".").action(async e=>{let t=s.resolve(e);await b(t);});export{o as a,j as b,D as c,m as d,E as e,f,b as g,N as h};
@@ -0,0 +1 @@
1
+ var g=Object.create;var f=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var m=(b,a)=>()=>(a||b((a={exports:{}}).exports,a),a.exports);var l=(b,a,c,e)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of i(a))!k.call(b,d)&&d!==c&&f(b,d,{get:()=>a[d],enumerable:!(e=h(a,d))||e.enumerable});return b};var n=(b,a,c)=>(c=b!=null?g(j(b)):{},l(a||!b||!b.__esModule?f(c,"default",{value:b,enumerable:true}):c,b));export{m as a,n as b};