@westbayberry/dg 1.3.3 → 2.0.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.
Files changed (126) hide show
  1. package/LICENSE +1 -201
  2. package/NOTICE +1 -4
  3. package/README.md +293 -0
  4. package/dist/api/analyze.js +210 -0
  5. package/dist/audit/deep.js +180 -0
  6. package/dist/audit/detectors.js +247 -0
  7. package/dist/audit/events.js +41 -0
  8. package/dist/audit/rules.js +426 -0
  9. package/dist/audit-ui/AuditApp.js +39 -0
  10. package/dist/audit-ui/components/AuditHeader.js +24 -0
  11. package/dist/audit-ui/components/AuditResultsView.js +307 -0
  12. package/dist/audit-ui/components/DeepStatusRow.js +11 -0
  13. package/dist/audit-ui/export.js +85 -0
  14. package/dist/audit-ui/format.js +34 -0
  15. package/dist/audit-ui/launch.js +34 -0
  16. package/dist/auth/device-login.js +271 -0
  17. package/dist/auth/env-token.js +6 -0
  18. package/dist/auth/login-app.js +156 -0
  19. package/dist/auth/store.js +147 -0
  20. package/dist/bin/dg.js +71 -0
  21. package/dist/commands/audit.js +362 -0
  22. package/dist/commands/completion.js +116 -0
  23. package/dist/commands/config.js +99 -0
  24. package/dist/commands/doctor.js +39 -0
  25. package/dist/commands/explain.js +100 -0
  26. package/dist/commands/guard-commit.js +158 -0
  27. package/dist/commands/help.js +74 -0
  28. package/dist/commands/licenses.js +435 -0
  29. package/dist/commands/login.js +81 -0
  30. package/dist/commands/logout.js +37 -0
  31. package/dist/commands/router.js +98 -0
  32. package/dist/commands/scan.js +18 -0
  33. package/dist/commands/service.js +475 -0
  34. package/dist/commands/setup.js +302 -0
  35. package/dist/commands/status.js +115 -0
  36. package/dist/commands/suggest.js +35 -0
  37. package/dist/commands/types.js +4 -0
  38. package/dist/commands/unavailable.js +11 -0
  39. package/dist/commands/uninstall.js +111 -0
  40. package/dist/commands/update.js +210 -0
  41. package/dist/commands/verify.js +151 -0
  42. package/dist/commands/version.js +22 -0
  43. package/dist/commands/wrap.js +55 -0
  44. package/dist/config/settings.js +302 -0
  45. package/dist/install-ui/LiveInstall.js +24 -0
  46. package/dist/install-ui/block-render.js +85 -0
  47. package/dist/install-ui/live-install-app.js +48 -0
  48. package/dist/install-ui/prompt.js +24 -0
  49. package/dist/launcher/classify.js +116 -0
  50. package/dist/launcher/env.js +53 -0
  51. package/dist/launcher/live-install.js +50 -0
  52. package/dist/launcher/output-redaction.js +77 -0
  53. package/dist/launcher/preflight-prompt.js +139 -0
  54. package/dist/launcher/resolve-real-binary.js +73 -0
  55. package/dist/launcher/run.js +417 -0
  56. package/dist/policy/evaluate.js +128 -0
  57. package/dist/presentation/mode.js +52 -0
  58. package/dist/presentation/theme.js +29 -0
  59. package/dist/proxy/buffer-budget.js +64 -0
  60. package/dist/proxy/ca.js +126 -0
  61. package/dist/proxy/classify-host.js +26 -0
  62. package/dist/proxy/enforcement.js +102 -0
  63. package/dist/proxy/metadata-map.js +336 -0
  64. package/dist/proxy/server.js +919 -0
  65. package/dist/proxy/upstream-proxy.js +102 -0
  66. package/dist/proxy/worker.js +39 -0
  67. package/dist/publish-set/collect.js +51 -0
  68. package/dist/publish-set/no-exec-shell.js +19 -0
  69. package/dist/publish-set/npm.js +109 -0
  70. package/dist/publish-set/pack.js +36 -0
  71. package/dist/publish-set/pypi.js +59 -0
  72. package/dist/runtime/cli.js +17 -0
  73. package/dist/runtime/first-run.js +60 -0
  74. package/dist/runtime/node-version.js +58 -0
  75. package/dist/runtime/nudges.js +105 -0
  76. package/dist/scan/analyze-worker.js +21 -0
  77. package/dist/scan/collect.js +153 -0
  78. package/dist/scan/command.js +159 -0
  79. package/dist/scan/discovery.js +209 -0
  80. package/dist/scan/render.js +240 -0
  81. package/dist/scan/scanner-report.js +82 -0
  82. package/dist/scan/staged.js +173 -0
  83. package/dist/scan/types.js +1 -0
  84. package/dist/scan-ui/LegacyApp.js +156 -0
  85. package/dist/scan-ui/alt-screen.js +84 -0
  86. package/dist/scan-ui/api-aliases.js +1 -0
  87. package/dist/scan-ui/components/ErrorView.js +23 -0
  88. package/dist/scan-ui/components/InteractiveResultsView.js +1179 -0
  89. package/dist/scan-ui/components/ProgressBar.js +89 -0
  90. package/dist/scan-ui/components/ProjectSelector.js +62 -0
  91. package/dist/scan-ui/components/ScoreHeader.js +20 -0
  92. package/dist/scan-ui/components/SetupBanner.js +13 -0
  93. package/dist/scan-ui/components/Spinner.js +4 -0
  94. package/dist/scan-ui/format-helpers.js +40 -0
  95. package/dist/scan-ui/hooks/useExpandAnimation.js +40 -0
  96. package/dist/scan-ui/hooks/useScan.js +113 -0
  97. package/dist/scan-ui/hooks/useTerminalSize.js +24 -0
  98. package/dist/scan-ui/launch.js +27 -0
  99. package/dist/scan-ui/logo.js +91 -0
  100. package/dist/scan-ui/shims.js +30 -0
  101. package/dist/security/sanitize.js +28 -0
  102. package/dist/service/state.js +837 -0
  103. package/dist/service/trust-store.js +234 -0
  104. package/dist/service/worker.js +88 -0
  105. package/dist/setup/git-hook.js +244 -0
  106. package/dist/setup/optional-support.js +58 -0
  107. package/dist/setup/plan.js +935 -0
  108. package/dist/state/cleanup-registry.js +60 -0
  109. package/dist/state/index.js +5 -0
  110. package/dist/state/locks.js +161 -0
  111. package/dist/state/paths.js +24 -0
  112. package/dist/state/sessions.js +170 -0
  113. package/dist/state/store.js +50 -0
  114. package/dist/telemetry/events.js +40 -0
  115. package/dist/util/git.js +20 -0
  116. package/dist/util/tty-prompt.js +43 -0
  117. package/dist/verify/local.js +400 -0
  118. package/dist/verify/package-check.js +240 -0
  119. package/dist/verify/preflight.js +698 -0
  120. package/dist/verify/render.js +184 -0
  121. package/dist/verify/types.js +1 -0
  122. package/package.json +33 -50
  123. package/dist/index.mjs +0 -54116
  124. package/dist/postinstall.mjs +0 -731
  125. package/dist/python-hook/dg_pip_hook.pth +0 -1
  126. package/dist/python-hook/dg_pip_hook.py +0 -130
@@ -0,0 +1,184 @@
1
+ import { createTheme } from "../presentation/theme.js";
2
+ const STATUS_ROLE = {
3
+ pass: "pass",
4
+ warn: "warn",
5
+ block: "block",
6
+ unknown: "unknown",
7
+ error: "block"
8
+ };
9
+ const STATUS_ACTION = {
10
+ pass: "pass",
11
+ warn: "warn",
12
+ block: "block",
13
+ unknown: "analysis_incomplete",
14
+ error: "block"
15
+ };
16
+ export function renderVerifyText(report, theme = createTheme(false), verbose = false) {
17
+ return verbose ? renderVerifyVerbose(report, theme) : renderVerifyCompact(report, theme);
18
+ }
19
+ function renderVerifyCompact(report, theme) {
20
+ const badge = report.status === "error" ? theme.paint("block", "✘ ERROR") : theme.badge(STATUS_ACTION[report.status]);
21
+ const phrase = summaryPhrase(report);
22
+ const lines = [phrase ? `${badge} ${targetLabel(report)} — ${phrase}` : `${badge} ${targetLabel(report)}`];
23
+ if (report.sha256) {
24
+ lines.push(theme.paint("muted", ` sha256 ${shortSha(report.sha256)}`));
25
+ }
26
+ for (const finding of report.findings) {
27
+ const glyph = theme.paint(finding.severity === "block" ? "block" : "warn", finding.severity === "block" ? "✘" : "⚠");
28
+ lines.push(` ${glyph} ${finding.id} ${finding.message}`);
29
+ }
30
+ for (const error of report.errors) {
31
+ lines.push(` ${theme.paint("block", "✘")} ${error}`);
32
+ }
33
+ return `${lines.join("\n")}\n`;
34
+ }
35
+ function targetLabel(report) {
36
+ if (report.packages.length === 1) {
37
+ const identity = report.packages[0];
38
+ const version = identity.version ? `@${identity.version}` : "";
39
+ return `${identity.name}${version} (${identity.ecosystem})`;
40
+ }
41
+ if (report.workspaceScan) {
42
+ const count = report.workspaceScan.summary.projectCount;
43
+ return `${report.target} (${count} project${plural(count)})`;
44
+ }
45
+ if (report.preflight && report.preflight.packageCount > 1) {
46
+ return `${report.target} (${report.preflight.packageCount} packages)`;
47
+ }
48
+ return report.target;
49
+ }
50
+ function summaryPhrase(report) {
51
+ const { findingCount, warnCount, blockCount } = report.summary;
52
+ if (report.status === "error") {
53
+ return report.errors.length > 0 ? "verification failed" : "verification error";
54
+ }
55
+ if (findingCount === 0 && report.errors.length === 0) {
56
+ return "";
57
+ }
58
+ if (blockCount > 0) {
59
+ return `${blockCount} blocking finding${plural(blockCount)}${warnCount > 0 ? `, ${warnCount} warn` : ""}`;
60
+ }
61
+ if (warnCount > 0) {
62
+ return `${warnCount} advisory finding${plural(warnCount)}`;
63
+ }
64
+ return "see details";
65
+ }
66
+ function shortSha(sha) {
67
+ return sha.length > 12 ? `${sha.slice(0, 4)}…${sha.slice(-4)}` : sha;
68
+ }
69
+ function plural(count) {
70
+ return count === 1 ? "" : "s";
71
+ }
72
+ function renderVerifyVerbose(report, theme) {
73
+ const lines = [
74
+ "Dependency Guardian verify",
75
+ `Target: ${report.target}`,
76
+ `Input: ${report.inputKind}`,
77
+ `Status: ${theme.paint(STATUS_ROLE[report.status], report.status)}`,
78
+ `SHA-256: ${report.sha256 ?? "not applicable"}`,
79
+ `Findings: ${report.summary.findingCount} (${report.summary.warnCount} warn, ${report.summary.blockCount} block)`,
80
+ ""
81
+ ];
82
+ if (report.archive) {
83
+ lines.push(`Archive entries: ${report.archive.entryCount}`);
84
+ lines.push(`Package manifests: ${report.archive.packageManifestCount}`);
85
+ lines.push(`Unpacked bytes: ${report.archive.unpackedSizeBytes ?? "unknown"}`);
86
+ lines.push("");
87
+ }
88
+ if (report.workspaceScan) {
89
+ lines.push(`Projects: ${report.workspaceScan.summary.projectCount}`);
90
+ lines.push(`Dependencies: ${report.workspaceScan.summary.dependencyCount}`);
91
+ lines.push("");
92
+ }
93
+ if (report.preflight) {
94
+ lines.push(`Packages: ${report.preflight.packageCount}`);
95
+ lines.push(`Identity source: ${report.preflight.identitySource}`);
96
+ lines.push(`Advisory: ${report.preflight.message}`);
97
+ lines.push("");
98
+ }
99
+ if (report.packages.length > 0) {
100
+ lines.push("Package identities:");
101
+ for (const identity of report.packages) {
102
+ const version = identity.version ? `@${identity.version}` : "";
103
+ const integrity = identity.integrity ? " integrity" : " no-integrity";
104
+ const license = identity.license ? ` license=${identity.license}` : "";
105
+ lines.push(`- ${identity.ecosystem}:${identity.name}${version} (${identity.sourceKind}${integrity}${license})`);
106
+ }
107
+ lines.push("");
108
+ }
109
+ if (report.findings.length === 0 && report.errors.length === 0) {
110
+ lines.push(report.preflight ? "No advisory preflight issues found." : "No local verification issues found.");
111
+ }
112
+ for (const finding of report.findings) {
113
+ lines.push(`${theme.paint(finding.severity === "block" ? "block" : "warn", finding.severity.toUpperCase())} ${finding.id} ${finding.location}: ${finding.message}`);
114
+ }
115
+ for (const error of report.errors) {
116
+ lines.push(`ERROR ${error}`);
117
+ }
118
+ return `${lines.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd()}\n`;
119
+ }
120
+ export function renderVerifyJson(report) {
121
+ return `${JSON.stringify(report, null, 2)}\n`;
122
+ }
123
+ export function renderVerifySarif(report) {
124
+ const rules = uniqueFindings(report.findings).map((finding) => ({
125
+ id: finding.id,
126
+ name: finding.title,
127
+ shortDescription: {
128
+ text: finding.title
129
+ },
130
+ fullDescription: {
131
+ text: finding.message
132
+ },
133
+ defaultConfiguration: {
134
+ level: finding.severity === "block" ? "error" : "warning"
135
+ }
136
+ }));
137
+ const sarif = {
138
+ version: "2.1.0",
139
+ $schema: "https://json.schemastore.org/sarif-2.1.0.json",
140
+ runs: [
141
+ {
142
+ tool: {
143
+ driver: {
144
+ name: "Dependency Guardian",
145
+ informationUri: "https://westbayberry.com",
146
+ rules
147
+ }
148
+ },
149
+ results: report.findings.map((finding) => ({
150
+ ruleId: finding.id,
151
+ level: finding.severity === "block" ? "error" : "warning",
152
+ message: {
153
+ text: finding.message
154
+ },
155
+ locations: [
156
+ {
157
+ physicalLocation: {
158
+ artifactLocation: {
159
+ uri: artifactUri(finding.location)
160
+ }
161
+ }
162
+ }
163
+ ]
164
+ }))
165
+ }
166
+ ]
167
+ };
168
+ return `${JSON.stringify(sarif, null, 2)}\n`;
169
+ }
170
+ function artifactUri(location) {
171
+ return location.replace(/:\d+$/, "");
172
+ }
173
+ function uniqueFindings(findings) {
174
+ const seen = new Set();
175
+ const unique = [];
176
+ for (const finding of findings) {
177
+ if (seen.has(finding.id)) {
178
+ continue;
179
+ }
180
+ seen.add(finding.id);
181
+ unique.push(finding);
182
+ }
183
+ return unique;
184
+ }
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,69 +1,52 @@
1
1
  {
2
2
  "name": "@westbayberry/dg",
3
- "version": "1.3.3",
3
+ "version": "2.0.1",
4
+ "description": "Dependency Guardian supply-chain firewall CLI",
4
5
  "type": "module",
5
- "description": "Supply chain security scanner for npm and Python dependencies",
6
6
  "bin": {
7
- "dependency-guardian": "dist/index.mjs",
8
- "dg": "dist/index.mjs"
7
+ "dg": "./dist/bin/dg.js"
9
8
  },
10
9
  "files": [
11
10
  "dist",
12
11
  "LICENSE",
13
- "NOTICE"
12
+ "NOTICE",
13
+ "package.json"
14
14
  ],
15
- "license": "Apache-2.0",
16
- "author": "WestBayBerry",
17
- "homepage": "https://westbayberry.com",
18
- "bugs": {
19
- "url": "https://github.com/WestBayBerry/WestBayBerry/issues"
20
- },
21
- "repository": {
22
- "type": "git",
23
- "url": "git+https://github.com/WestBayBerry/WestBayBerry.git"
24
- },
25
- "keywords": [
26
- "security",
27
- "npm",
28
- "pypi",
29
- "supply-chain",
30
- "scanner",
31
- "cli",
32
- "dependencies",
33
- "malware",
34
- "typosquatting",
35
- "dependency-confusion"
36
- ],
37
- "publishConfig": {
38
- "access": "public"
15
+ "engines": {
16
+ "node": ">=22.14.0"
39
17
  },
40
18
  "scripts": {
41
19
  "build": "node build.mjs",
42
- "dev": "npx tsx src/bin.ts",
43
20
  "test": "vitest run",
44
- "pretest": "node build.mjs",
45
- "lint": "eslint src",
46
- "postinstall": "node dist/postinstall.mjs || true",
47
- "prepublishOnly": "npm run lint && npm test && npm run build"
48
- },
49
- "engines": {
50
- "node": ">=18"
21
+ "test:unit": "vitest run test/unit",
22
+ "test:integration": "vitest run test/integration",
23
+ "typecheck": "tsc --noEmit",
24
+ "lint": "node scripts/lint.mjs",
25
+ "format:check": "node scripts/format-check.mjs",
26
+ "check:package": "node scripts/check-package-contract.mjs",
27
+ "check:tarball": "node scripts/check-tarball.mjs",
28
+ "check:legacy": "node scripts/check-legacy-absence.mjs",
29
+ "check:architecture-cracks": "node scripts/validate-architecture-crack-closure.mjs",
30
+ "check:release-docs": "node scripts/check-release-docs.mjs",
31
+ "check:plan-coverage": "node scripts/validate-plan-coverage.mjs",
32
+ "check:adversarial-plan": "node scripts/validate-adversarial-validation-plan.mjs",
33
+ "check": "npm run typecheck && npm run lint && npm run format:check && npm run check:package && npm run check:legacy && npm run check:release-docs && npm run check:plan-coverage && npm run check:adversarial-plan && npm run build && npm run test && npm run check:tarball && npm run check:architecture-cracks"
51
34
  },
52
35
  "devDependencies": {
53
- "@types/node": "^20.0.0",
54
- "@types/react": "^18.3.28",
55
- "@vitest/coverage-v8": "^3.2.4",
56
- "esbuild": "^0.25.12",
57
- "eslint": "^9.39.4",
58
- "ink-testing-library": "^4.0.0",
59
- "typescript": "^5.9.3",
60
- "typescript-eslint": "^8.58.1",
61
- "vitest": "^3.0.0"
36
+ "@types/node": "22.15.30",
37
+ "@types/react": "18.3.28",
38
+ "ink-testing-library": "4.0.0",
39
+ "node-pty": "1.0.0",
40
+ "typescript": "5.8.3",
41
+ "vitest": "3.1.4"
62
42
  },
43
+ "license": "UNLICENSED",
44
+ "private": false,
63
45
  "dependencies": {
64
- "chalk": "^4.1.2",
65
- "ink": "^5.2.1",
66
- "ink-spinner": "^5.0.0",
67
- "react": "^18.3.1"
46
+ "chalk": "4.1.2",
47
+ "ink": "5.2.1",
48
+ "ink-spinner": "5.0.0",
49
+ "node-forge": "1.4.0",
50
+ "react": "18.3.1"
68
51
  }
69
52
  }