deepbom 1.97.0 → 1.97.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepbom",
3
- "version": "1.97.0",
3
+ "version": "1.97.4",
4
4
  "mcpName": "io.github.JunHwan-Kwon/deepbom",
5
5
  "description": "Local multi-format deployment-artifact analysis for on-device AI models",
6
6
  "type": "module",
@@ -45,6 +45,8 @@
45
45
  "sarif",
46
46
  "static-analysis",
47
47
  "agent-skills",
48
- "model-context-protocol"
48
+ "model-context-protocol",
49
+ "mcp",
50
+ "chatgpt"
49
51
  ]
50
52
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schema": "deepbom.npm_release.v1",
3
- "version": "1.97.0",
3
+ "version": "1.97.4",
4
4
  "source": {
5
- "git_commit": "95b2218267ba6eeaf54945344aa3d7c945ef7fdd",
5
+ "git_commit": "859274046529f75f7af1f322075191e27330b119",
6
6
  "git_state": "clean",
7
7
  "distribution": "public_channel"
8
8
  },
@@ -5,14 +5,26 @@ description: Statically audit serialized AI deployment artifacts with the local
5
5
 
6
6
  # Audit deployment artifacts with DEEPBOM
7
7
 
8
- Run DEEPBOM locally. Never upload artifact bytes or invent a hosted DEEPBOM endpoint.
8
+ Run DEEPBOM locally for files in the workspace. Never upload artifact bytes or invent a hosted DEEPBOM endpoint. A separately connected ChatGPT integration may analyze one authorized attachment in its browser sandbox; that is a different execution boundary.
9
+
10
+ ## Resolve a verified runtime first
11
+
12
+ Run `scripts/verify-deepbom.mjs` from this Skill directory before choosing an invocation. It checks, in order, `DEEPBOM_BIN`, the analyzer bundled with an npm installation, and an exact-version `deepbom` already on `PATH`. It does not access a package registry by default.
13
+
14
+ If no exact local installation is available, ask before running:
15
+
16
+ ```bash
17
+ node "<skill-root>/scripts/verify-deepbom.mjs" --allow-download
18
+ ```
19
+
20
+ That explicit fallback may download `deepbom@1.97.4` through npm. Use the returned `invocation.command` and `invocation.prefix_args` for subsequent commands. Do not silently replace a version mismatch or network failure with an unverified executable.
9
21
 
10
22
  ## Start with discovery
11
23
 
12
- Use the release pinned by this skill:
24
+ After resolving the exact release pinned by this Skill, discover its machine contract:
13
25
 
14
26
  ```bash
15
- npx -y deepbom@1.97.0 capabilities --format agent-json
27
+ deepbom capabilities --format agent-json
16
28
  ```
17
29
 
18
30
  Treat that machine document as authoritative for commands, supported inputs, scan modes, targets, outputs, and exit codes. Read `references/capability-selection.md` when deciding whether the task belongs to DEEPBOM.
@@ -22,15 +34,15 @@ Treat that machine document as authoritative for commands, supported inputs, sca
22
34
  Start with the bounded human result:
23
35
 
24
36
  ```bash
25
- npx -y deepbom@1.97.0 audit "./model.onnx" --summary
37
+ deepbom audit "./model.onnx" --summary
26
38
  ```
27
39
 
28
40
  Then request only the evidence needed by the question:
29
41
 
30
42
  ```bash
31
- npx -y deepbom@1.97.0 audit "./model.onnx" --section quantization --json
32
- npx -y deepbom@1.97.0 audit "./model.onnx" --pointer /mac_assessment --json
33
- npx -y deepbom@1.97.0 audit "./model.onnx" --output-format envelope
43
+ deepbom audit "./model.onnx" --section quantization --json
44
+ deepbom audit "./model.onnx" --pointer /mac_assessment --json
45
+ deepbom audit "./model.onnx" --output-format envelope
34
46
  ```
35
47
 
36
48
  For a large GGUF or SafeTensors artifact, use `--scan structure` for inventory questions. Use `integrity` or `full` only when payload evidence is necessary.
@@ -38,15 +50,15 @@ For a large GGUF or SafeTensors artifact, use `--scan structure` for inventory q
38
50
  For a concise GGUF tensor table without nested numerical-integrity ledgers, use the bounded projection (it defaults to a structure scan):
39
51
 
40
52
  ```bash
41
- npx -y deepbom@1.97.0 gguf "./model.gguf" --tensors
42
- npx -y deepbom@1.97.0 gguf "./model.gguf" --tensors --compact
43
- npx -y deepbom@1.97.0 gguf "./model.gguf" --tensors --compact --tensor-offset 100 --tensor-limit 100
53
+ deepbom gguf "./model.gguf" --tensors
54
+ deepbom gguf "./model.gguf" --tensors --compact
55
+ deepbom gguf "./model.gguf" --tensors --compact --tensor-offset 100 --tensor-limit 100
44
56
  ```
45
57
 
46
- Before relying on a newly fetched package, run:
58
+ Before relying on any resolved installation, run:
47
59
 
48
60
  ```bash
49
- npx -y deepbom@1.97.0 self-test --compact
61
+ deepbom self-test --compact
50
62
  ```
51
63
 
52
64
  ## Interpret the result
@@ -68,12 +80,12 @@ Never infer actual accelerator assignment, latency, energy, thermal behavior, ta
68
80
  ## Compare or explain
69
81
 
70
82
  ```bash
71
- npx -y deepbom@1.97.0 diff "./baseline.onnx" "./candidate.onnx" --summary
72
- npx -y deepbom@1.97.0 diff "./baseline.gguf" "./candidate.gguf" --tensors --render markdown
73
- npx -y deepbom@1.97.0 verify "./model.onnx" --bom "./supplied.cdx.json" --render markdown
74
- npx -y deepbom@1.97.0 contract capture "./model.onnx" -o "./baseline.interface-contract.json"
75
- npx -y deepbom@1.97.0 explain-rule <rule-id> --json
76
- npx -y deepbom@1.97.0 graph "./model.onnx" --view structure --format svg -o graph.svg
83
+ deepbom diff "./baseline.onnx" "./candidate.onnx" --summary
84
+ deepbom diff "./baseline.gguf" "./candidate.gguf" --tensors --render markdown
85
+ deepbom verify "./model.onnx" --bom "./supplied.cdx.json" --render markdown
86
+ deepbom contract capture "./model.onnx" -o "./baseline.interface-contract.json"
87
+ deepbom explain-rule <rule-id> --json
88
+ deepbom graph "./model.onnx" --view structure --format svg -o graph.svg
77
89
  ```
78
90
 
79
91
  Use matching serialized deployment formats for diff. Treat `verify --bom` as a reconciliation of the selected component with artifact-observable facts, not a complete BOM or compliance verdict. An automatically captured contract is an artifact-derived baseline until it is separately reviewed and approved. Do not deserialize `.pth`, `.pt`, or `.h5`; bind a conversion receipt to the deployed artifact instead.
@@ -7,3 +7,4 @@
7
7
  5. For remote input, require an immutable identity: a full Hugging Face commit, GCS object generation, or HTTPS SHA-256 fragment.
8
8
  6. Do not raise download, response, or memory limits without explaining the cost and obtaining user approval.
9
9
  7. If no shell, local MCP, or local file access exists, explain that actual analysis cannot run in that client and provide the pinned `npx` command.
10
+ 8. Registry download is opt-in. Prefer a verified exact-version installation; use `npx -y deepbom@1.97.4` only after network and installation permission is clear.
@@ -1,19 +1,71 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { spawnSync } from "node:child_process";
4
+ import { existsSync } from "node:fs";
5
+ import path from "node:path";
6
+ import process from "node:process";
7
+ import { fileURLToPath } from "node:url";
4
8
 
5
- const VERSION = "1.97.0";
6
- const executable = process.platform === "win32" ? process.env.ComSpec || "cmd.exe" : "npx";
7
- const args = process.platform === "win32"
8
- ? ["/d", "/s", "/c", "npx.cmd", "-y", `deepbom@${VERSION}`, "self-test", "--compact"]
9
- : ["-y", `deepbom@${VERSION}`, "self-test", "--compact"];
10
- const result = spawnSync(executable, args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
11
- if (result.status !== 0) {
12
- process.stderr.write(result.stderr || result.stdout || `DEEPBOM self-test exited ${result.status}.\n`);
13
- process.exit(result.status || 1);
9
+ const VERSION = "1.97.4";
10
+ const allowDownload = process.argv.slice(2).includes("--allow-download");
11
+ const attempts = [];
12
+ const candidates = localCandidates();
13
+ if (allowDownload) candidates.push({ source: "npm_exact_version", command: process.platform === "win32" ? "npx.cmd" : "npx", prefix_args: ["-y", `deepbom@${VERSION}`], network: true });
14
+
15
+ for (const candidate of candidates) {
16
+ const versionRun = invoke(candidate, ["--version"]);
17
+ if (versionRun.status !== 0 || versionRun.stdout.trim() !== VERSION) {
18
+ attempts.push({ source: candidate.source, status: versionRun.status, observed_version: versionRun.stdout.trim() || null, error: bounded(versionRun.stderr) });
19
+ continue;
20
+ }
21
+ const selfTest = invoke(candidate, ["self-test", "--compact"]);
22
+ try {
23
+ const document = JSON.parse(selfTest.stdout);
24
+ if (selfTest.status !== 0 || document.schema !== "deepbom.cli_self_test.v1" || document.status !== "pass" || document.version !== VERSION) throw new Error("self-test contract mismatch");
25
+ process.stdout.write(`${JSON.stringify({ schema: "deepbom.skill_runtime_resolution.v1", version: VERSION, status: "pass", source: candidate.source, network_used: candidate.network, invocation: { command: candidate.command, prefix_args: candidate.prefix_args }, self_test: document })}\n`);
26
+ process.exit(0);
27
+ } catch (error) {
28
+ attempts.push({ source: candidate.source, status: selfTest.status, error: bounded(selfTest.stderr || selfTest.stdout || error.message) });
29
+ }
30
+ }
31
+
32
+ process.stderr.write(`${JSON.stringify({ schema: "deepbom.skill_runtime_resolution.v1", version: VERSION, status: "unavailable", registry_download_attempted: allowDownload, attempts, suggested_action: allowDownload ? "Review the recorded installation or network error; do not claim an analysis ran." : "Install the exact release or rerun with --allow-download only after registry access is authorized." })}\n`);
33
+ process.exit(3);
34
+
35
+ function localCandidates() {
36
+ const rows = [];
37
+ if (process.env.DEEPBOM_BIN?.trim()) rows.push(candidateForPath(path.resolve(process.env.DEEPBOM_BIN.trim()), "DEEPBOM_BIN"));
38
+ const packaged = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../../bin/deepbom.mjs");
39
+ if (existsSync(packaged)) rows.push(candidateForPath(packaged, "bundled_npm_package"));
40
+ const installed = findOnPath("deepbom");
41
+ if (installed && !rows.some((row) => path.resolve(row.identity) === path.resolve(installed))) rows.push(candidateForPath(installed, "installed_path"));
42
+ return rows;
43
+ }
44
+
45
+ function candidateForPath(file, source) {
46
+ return /\.(?:mjs|js|cjs)$/i.test(file)
47
+ ? { source, identity: file, command: process.execPath, prefix_args: [file], network: false }
48
+ : { source, identity: file, command: file, prefix_args: [], network: false };
14
49
  }
15
- const document = JSON.parse(result.stdout);
16
- if (document.schema !== "deepbom.cli_self_test.v1" || document.status !== "pass") {
17
- throw new Error("DEEPBOM self-test did not return a passing deepbom.cli_self_test.v1 document.");
50
+
51
+ function findOnPath(name) {
52
+ const extensions = process.platform === "win32" ? (process.env.PATHEXT || ".EXE;.CMD;.BAT").split(";") : [""];
53
+ for (const directory of (process.env.PATH || "").split(path.delimiter).filter(Boolean)) {
54
+ for (const extension of extensions) {
55
+ const file = path.join(directory.replace(/^"|"$/g, ""), process.platform === "win32" ? `${name}${extension.toLowerCase()}` : name);
56
+ if (existsSync(file)) return file;
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function invoke(candidate, args) {
63
+ const shell = process.platform === "win32" && /\.(?:cmd|bat)$/i.test(candidate.command);
64
+ const result = spawnSync(candidate.command, [...candidate.prefix_args, ...args], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], shell, timeout: 120000, windowsHide: true });
65
+ return { status: Number.isInteger(result.status) ? result.status : 1, stdout: result.stdout || "", stderr: result.stderr || result.error?.message || "" };
66
+ }
67
+
68
+ function bounded(value) {
69
+ const text = String(value || "").trim();
70
+ return text ? text.slice(0, 1000) : null;
18
71
  }
19
- process.stdout.write(`${JSON.stringify(document)}\n`);