cbom-tools 0.1.0 → 0.1.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
@@ -40,6 +40,19 @@ Exit codes:
40
40
  - `0` — no changes
41
41
  - `1` — changes detected
42
42
  - `2` — file not found or parse error
43
+ - `3` — (reserved) quantum-vulnerable/weak algorithm detection (planned for 0.2.0)
44
+
45
+ ## Testing
46
+
47
+ ```
48
+ npm test
49
+ ```
50
+
51
+ 17 CLI contract tests (Node built-in `node:test`, zero dependencies):
52
+ both binaries are spawned as child processes and checked against edge
53
+ inputs — empty directory, dependencies-only, source-only, an 800-file
54
+ tree (occurrence cap, `node_modules` / `.git` / dotfile skipping),
55
+ unreachable directories, missing argument values, and malformed JSON.
43
56
 
44
57
  ## Example (real output)
45
58
 
package/cbom-diff.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * 0 — 无变更
18
18
  * 1 — 有信息性变更(算法属性升级等)
19
19
  * 2 — 有警告性变更(算法删除、新经典算法引用等)
20
- * 3 — 有严重变更(量子脆弱算法被引入)
20
+ * 3 — (reserved) 量子脆弱/弱算法引入检测(0.2.0 规划)
21
21
  */
22
22
 
23
23
  const { execSync } = require('child_process');
@@ -55,7 +55,12 @@ function loadCBOM(hash) {
55
55
  console.error(`✕ cbom-diff: file not found: ${filePath}`);
56
56
  process.exit(2);
57
57
  }
58
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
58
+ try {
59
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
60
+ } catch (e) {
61
+ console.error(`✕ cbom-diff: invalid JSON in ${filePath}: ${e.message}`);
62
+ process.exit(2);
63
+ }
59
64
  }
60
65
  // 2. Git mode
61
66
  if (gitMode) {
@@ -121,7 +126,7 @@ if (oldCBOM && newCBOM) {
121
126
  ref,
122
127
  name: c.name,
123
128
  type: assetType,
124
- risk: classifyRisk(assetType),
129
+ risk: classifyRisk(crypto),
125
130
  });
126
131
  }
127
132
  });
@@ -206,8 +211,8 @@ if (hasCriticalAdd) {
206
211
  // ════════════════════════════
207
212
  // 算法风险分类
208
213
  // ════════════════════════════
209
- function classifyRisk(assetType) {
210
- const type = (assetType || '').toLowerCase();
214
+ function classifyRisk(cryptoProps) {
215
+ const type = ((cryptoProps && cryptoProps.assetType) || '').toLowerCase();
211
216
  // PQC algorithms: safe additions
212
217
  if (/kem|sign|signature|post.quantum|pqc|mlkem|mldsa|slh/i.test(type)) return 'info';
213
218
  // Primitive/verification: neutral
@@ -216,6 +221,8 @@ function classifyRisk(assetType) {
216
221
  if (/ecc|ecdh|p-256|sm2|curve/i.test(type)) return 'warning';
217
222
  // Classic symmetric: info (still safe with large keys)
218
223
  if (/sym|sm4|aes|gcm/i.test(type)) return 'info';
224
+ // TODO(v0.2.0): add 'critical' exit code for quantum-vulnerable algorithms
225
+ // using cryptoProps.quantumSecurity?.level
219
226
  // Unknown: treat as warning
220
227
  return 'warning';
221
228
  }
package/cbom-scan.cjs CHANGED
@@ -146,7 +146,16 @@ function toCycloneDX(algorithms) {
146
146
 
147
147
  function main() {
148
148
  const args = process.argv.slice(2);
149
- const dir = args.includes('--dir') ? args[args.indexOf('--dir') + 1] : process.cwd();
149
+ const dirFlag = args.indexOf('--dir');
150
+ let dir = process.cwd();
151
+ if (dirFlag !== -1) {
152
+ const v = args[dirFlag + 1];
153
+ if (!v || v.startsWith('--')) {
154
+ console.error('usage: cbom-scan [--dir <path>] [--out <file>]');
155
+ process.exit(2);
156
+ }
157
+ dir = v;
158
+ }
150
159
  const outPath = args.includes('--out') ? args[args.indexOf('--out') + 1] : null;
151
160
 
152
161
  const deps = loadPackageDeps(dir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cbom-tools",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Crypto Bill of Materials — scan, diff, report (CycloneDX 1.6 CBOM)",
5
5
  "license": "Apache-2.0",
6
6
  "author": "刘天赫 <research@fibemate.net>",
@@ -14,5 +14,8 @@
14
14
  "algo-metadata.json",
15
15
  "README.md",
16
16
  "LICENSE"
17
- ]
17
+ ],
18
+ "scripts": {
19
+ "test": "node --test \"test/*.test.cjs\""
20
+ }
18
21
  }