yakmesh 2.8.2 → 3.0.0

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 (232) hide show
  1. package/CHANGELOG.md +637 -0
  2. package/CONTRIBUTING.md +42 -0
  3. package/Caddyfile +77 -0
  4. package/README.md +119 -29
  5. package/adapters/adapter-mlv-bible/README.md +124 -0
  6. package/adapters/adapter-mlv-bible/index.js +400 -0
  7. package/adapters/chat-mod-adapter.js +532 -0
  8. package/adapters/content-adapter.js +273 -0
  9. package/content/api.js +50 -41
  10. package/content/index.js +2 -2
  11. package/content/store.js +355 -173
  12. package/dashboard/index.html +19 -3
  13. package/database/replication.js +117 -37
  14. package/docs/CRYPTO-AGILITY.md +204 -0
  15. package/docs/MTLS-RESEARCH.md +367 -0
  16. package/docs/NAMCHE-SPEC.md +681 -0
  17. package/docs/PEERQUANTA-YAKMESH-INTEGRATION.md +407 -0
  18. package/docs/PRECISION-DISCLOSURE.md +96 -0
  19. package/docs/README.md +76 -0
  20. package/docs/ROADMAP-2.4.0.md +447 -0
  21. package/docs/ROADMAP-2.5.0.md +244 -0
  22. package/docs/SECURITY-AUDIT-REPORT.md +306 -0
  23. package/docs/SST-INTEGRATION.md +712 -0
  24. package/docs/STEADYWATCH-IMPLEMENTATION.md +303 -0
  25. package/docs/TERNARY-AUDIT-REPORT.md +247 -0
  26. package/docs/TME-FAQ.md +221 -0
  27. package/docs/WHITEPAPER.md +623 -0
  28. package/docs/adapters.html +1001 -0
  29. package/docs/advanced-systems.html +1045 -0
  30. package/docs/annex.html +1046 -0
  31. package/docs/api.html +970 -0
  32. package/docs/business/response-templates.md +160 -0
  33. package/docs/c2c.html +1225 -0
  34. package/docs/cli.html +1332 -0
  35. package/docs/configuration.html +1248 -0
  36. package/docs/darshan.html +1085 -0
  37. package/docs/dharma.html +966 -0
  38. package/docs/docs-bundle.html +1075 -0
  39. package/docs/docs.css +3120 -0
  40. package/docs/docs.js +556 -0
  41. package/docs/doko.html +969 -0
  42. package/docs/geo-proof.html +858 -0
  43. package/docs/getting-started.html +840 -0
  44. package/docs/gumba-tutorial.html +1144 -0
  45. package/docs/gumba.html +1098 -0
  46. package/docs/index.html +914 -0
  47. package/docs/jhilke.html +1312 -0
  48. package/docs/karma.html +1100 -0
  49. package/docs/katha.html +1037 -0
  50. package/docs/lama.html +978 -0
  51. package/docs/mandala.html +1067 -0
  52. package/docs/mani.html +964 -0
  53. package/docs/mantra.html +967 -0
  54. package/docs/mesh.html +1409 -0
  55. package/docs/nakpak.html +869 -0
  56. package/docs/namche.html +928 -0
  57. package/docs/nav-order.json +53 -0
  58. package/docs/prahari.html +1043 -0
  59. package/docs/prism-bash.min.js +1 -0
  60. package/docs/prism-javascript.min.js +1 -0
  61. package/docs/prism-json.min.js +1 -0
  62. package/docs/prism-tomorrow.min.css +1 -0
  63. package/docs/prism.min.js +1 -0
  64. package/docs/privacy.html +699 -0
  65. package/docs/quick-reference.html +1181 -0
  66. package/docs/sakshi.html +1402 -0
  67. package/docs/sandboxing.md +386 -0
  68. package/docs/seva.html +911 -0
  69. package/docs/sherpa.html +871 -0
  70. package/docs/studio.html +860 -0
  71. package/docs/stupa.html +995 -0
  72. package/docs/tailwind.min.css +2 -0
  73. package/docs/tattva.html +1332 -0
  74. package/docs/terms.html +686 -0
  75. package/docs/time-server-deployment.md +166 -0
  76. package/docs/time-sources.html +1392 -0
  77. package/docs/tivra.html +1127 -0
  78. package/docs/trademark-policy.html +686 -0
  79. package/docs/tribhuj.html +1183 -0
  80. package/docs/trust-security.html +1029 -0
  81. package/docs/tutorials/backup-recovery.html +654 -0
  82. package/docs/tutorials/dashboard.html +604 -0
  83. package/docs/tutorials/domain-setup.html +605 -0
  84. package/docs/tutorials/host-website.html +456 -0
  85. package/docs/tutorials/mesh-network.html +505 -0
  86. package/docs/tutorials/mobile-access.html +445 -0
  87. package/docs/tutorials/privacy.html +467 -0
  88. package/docs/tutorials/raspberry-pi.html +600 -0
  89. package/docs/tutorials/security-basics.html +539 -0
  90. package/docs/tutorials/share-files.html +431 -0
  91. package/docs/tutorials/troubleshooting.html +637 -0
  92. package/docs/tutorials/trust-karma.html +419 -0
  93. package/docs/tutorials/yak-protocol.html +456 -0
  94. package/docs/tutorials.html +1034 -0
  95. package/docs/vani.html +1270 -0
  96. package/docs/webserver.html +809 -0
  97. package/docs/yak-protocol.html +940 -0
  98. package/docs/yak-timeserver-design.md +475 -0
  99. package/docs/yakapp.html +1015 -0
  100. package/docs/ypc27.html +1069 -0
  101. package/docs/yurt.html +1344 -0
  102. package/embedded-docs/bundle.js +334 -74
  103. package/gossip/protocol.js +247 -27
  104. package/identity/key-resolver.js +262 -0
  105. package/identity/machine-seed.js +632 -0
  106. package/identity/node-key.js +669 -368
  107. package/identity/tribhuj-ratchet.js +506 -0
  108. package/knowledge-base.js +37 -8
  109. package/launcher/yakmesh.bat +62 -0
  110. package/launcher/yakmesh.sh +70 -0
  111. package/mesh/annex.js +462 -108
  112. package/mesh/beacon-broadcast.js +113 -1
  113. package/mesh/darshan.js +1718 -0
  114. package/mesh/gumba.js +1567 -0
  115. package/mesh/jhilke.js +651 -0
  116. package/mesh/katha.js +1012 -0
  117. package/mesh/nakpak-routing.js +8 -5
  118. package/mesh/network.js +724 -34
  119. package/mesh/pulse-sync.js +4 -1
  120. package/mesh/rate-limiter.js +127 -15
  121. package/mesh/seva.js +526 -0
  122. package/mesh/sherpa-discovery.js +89 -8
  123. package/mesh/sybil-defense.js +19 -5
  124. package/mesh/temporal-encoder.js +4 -3
  125. package/mesh/vani.js +1364 -0
  126. package/mesh/yurt.js +1340 -0
  127. package/models/entropy-sentinel.onnx +0 -0
  128. package/models/karma-trust.onnx +0 -0
  129. package/models/manifest.json +43 -0
  130. package/models/sakshi-anomaly.onnx +0 -0
  131. package/oracle/code-proof-protocol.js +7 -6
  132. package/oracle/codebase-lock.js +257 -28
  133. package/oracle/index.js +74 -15
  134. package/oracle/ma902-snmp.js +678 -0
  135. package/oracle/module-sealer.js +5 -3
  136. package/oracle/network-identity.js +16 -0
  137. package/oracle/packet-checksum.js +201 -0
  138. package/oracle/sst.js +579 -0
  139. package/oracle/ternary-144t.js +714 -0
  140. package/oracle/ternary-ml.js +481 -0
  141. package/oracle/time-api.js +239 -0
  142. package/oracle/time-source.js +137 -47
  143. package/oracle/validation-oracle-hardened.js +1111 -1071
  144. package/oracle/validation-oracle.js +4 -2
  145. package/oracle/ypc27.js +211 -0
  146. package/package.json +20 -3
  147. package/protocol/yak-handler.js +35 -9
  148. package/protocol/yak-protocol.js +28 -13
  149. package/reference/cpp/yakmesh_mceliece_shard.cpp +168 -0
  150. package/reference/cpp/yakmesh_ypc27.cpp +179 -0
  151. package/sbom.json +87 -0
  152. package/scripts/security-audit.mjs +264 -0
  153. package/scripts/update-docs-nav.js +194 -0
  154. package/scripts/update-docs-sidebar.cjs +164 -0
  155. package/security/crypto-config.js +4 -3
  156. package/security/dharma-moderation.js +517 -0
  157. package/security/doko-identity.js +193 -143
  158. package/security/domain-consensus.js +86 -85
  159. package/security/fs-hardening.js +620 -0
  160. package/security/hardware-attestation.js +5 -3
  161. package/security/hybrid-trust.js +227 -87
  162. package/security/karma-rate-limiter.js +692 -0
  163. package/security/khata-protocol.js +22 -21
  164. package/security/khata-trust-integration.js +277 -150
  165. package/security/memory-safety.js +635 -0
  166. package/security/mesh-auth.js +11 -10
  167. package/security/mesh-revocation.js +373 -5
  168. package/security/namche-gateway.js +298 -69
  169. package/security/sakshi.js +460 -3
  170. package/security/sangha.js +770 -0
  171. package/security/secure-config.js +473 -0
  172. package/security/silicon-parity.js +13 -10
  173. package/security/steadywatch.js +1142 -0
  174. package/security/strike-system.js +32 -3
  175. package/security/temporal-signing.js +488 -0
  176. package/security/trit-commitment.js +464 -0
  177. package/server/crypto/annex.js +247 -0
  178. package/server/darshan-api.js +343 -0
  179. package/server/index.js +3259 -362
  180. package/server/komm-api.js +668 -0
  181. package/utils/accel.js +2273 -0
  182. package/utils/ternary-id.js +79 -0
  183. package/utils/verify-worker.js +57 -0
  184. package/webserver/index.js +95 -5
  185. package/assets/yakmesh-logo.png +0 -0
  186. package/assets/yakmesh-logo.svg +0 -80
  187. package/assets/yakmesh-logo2.png +0 -0
  188. package/assets/yakmesh-logo2sm.png +0 -0
  189. package/assets/ymsm.png +0 -0
  190. package/website/assets/silhouettes/adapters.svg +0 -107
  191. package/website/assets/silhouettes/api-endpoints.svg +0 -115
  192. package/website/assets/silhouettes/atomic-clock.svg +0 -83
  193. package/website/assets/silhouettes/base-camp.svg +0 -81
  194. package/website/assets/silhouettes/bridge.svg +0 -69
  195. package/website/assets/silhouettes/docs-bundle.svg +0 -113
  196. package/website/assets/silhouettes/doko-basket.svg +0 -70
  197. package/website/assets/silhouettes/fortress.svg +0 -93
  198. package/website/assets/silhouettes/gateway.svg +0 -54
  199. package/website/assets/silhouettes/gears.svg +0 -93
  200. package/website/assets/silhouettes/globe-satellite.svg +0 -67
  201. package/website/assets/silhouettes/karma-wheel.svg +0 -137
  202. package/website/assets/silhouettes/lama-council.svg +0 -141
  203. package/website/assets/silhouettes/mandala-network.svg +0 -169
  204. package/website/assets/silhouettes/mani-stones.svg +0 -149
  205. package/website/assets/silhouettes/mantra-wheel.svg +0 -116
  206. package/website/assets/silhouettes/mesh-nodes.svg +0 -113
  207. package/website/assets/silhouettes/nakpak.svg +0 -56
  208. package/website/assets/silhouettes/peak-lightning.svg +0 -73
  209. package/website/assets/silhouettes/sherpa.svg +0 -69
  210. package/website/assets/silhouettes/stupa-tower.svg +0 -119
  211. package/website/assets/silhouettes/tattva-eye.svg +0 -78
  212. package/website/assets/silhouettes/terminal.svg +0 -74
  213. package/website/assets/silhouettes/webserver.svg +0 -145
  214. package/website/assets/silhouettes/yak.svg +0 -78
  215. package/website/assets/yakmesh-logo.png +0 -0
  216. package/website/assets/yakmesh-logo.webp +0 -0
  217. package/website/assets/yakmesh-logo128x140.webp +0 -0
  218. package/website/assets/yakmesh-logo2.png +0 -0
  219. package/website/assets/yakmesh-logo2.svg +0 -51
  220. package/website/assets/yakmesh-logo40x44.webp +0 -0
  221. package/website/assets/yakmesh.gif +0 -0
  222. package/website/assets/yakmesh.ico +0 -0
  223. package/website/assets/yakmesh.jpg +0 -0
  224. package/website/assets/yakmesh.pdf +0 -0
  225. package/website/assets/yakmesh.png +0 -0
  226. package/website/assets/yakmesh.svg +0 -70
  227. package/website/assets/yakmesh128.webp +0 -0
  228. package/website/assets/yakmesh32.png +0 -0
  229. package/website/assets/yakmesh32.svg +0 -65
  230. package/website/assets/yakmesh32o.ico +0 -2
  231. package/website/assets/yakmesh32o.svg +0 -65
  232. package/website/assets/yakmesh32o.svgz +0 -0
@@ -0,0 +1,179 @@
1
+ #include <iostream>
2
+ #include <vector>
3
+ #include <array>
4
+ #include <cstdint>
5
+ #include <numeric>
6
+ #include <iomanip>
7
+
8
+ // ============================================================================
9
+ // YAKMESH CORE: YPC-27 (27-Trit Polynomial Checksum)
10
+ // Ring: R = Z[x] / (x^27 - 1) mod 3
11
+ // Coefficients: Balanced Ternary {-1, 0, 1}
12
+ // ============================================================================
13
+
14
+ namespace yakmesh {
15
+
16
+ constexpr int N = 27;
17
+
18
+ // Balanced Ternary Trit: Can be -1, 0, or 1
19
+ using Trit = int8_t;
20
+
21
+ struct Poly27 {
22
+ std::array<Trit, N> coeffs;
23
+
24
+ Poly27() { coeffs.fill(0); }
25
+
26
+ // Print representation (e.g., + - 0 + ...)
27
+ void print() const {
28
+ std::cout << "[ ";
29
+ for (int i = 0; i < N; ++i) {
30
+ if (coeffs[i] == 1) std::cout << "+";
31
+ else if (coeffs[i] == -1) std::cout << "-";
32
+ else std::cout << "0";
33
+ }
34
+ std::cout << " ]" << std::endl;
35
+ }
36
+ };
37
+
38
+ // ------------------------------------------------------------------------
39
+ // MATH HELPERS (Mod 3)
40
+ // ------------------------------------------------------------------------
41
+
42
+ // Canonical reduction to balanced ternary {-1, 0, 1}
43
+ // (val % 3) -> {0, 1, 2} -> {-1, 0, 1}
44
+ constexpr Trit reduce3(int val) {
45
+ int r = val % 3;
46
+ if (r < 0) r += 3; // Handle C++ negative modulo behavior
47
+ // Map {0, 1, 2} => {0, 1, -1}
48
+ return (r == 2) ? -1 : static_cast<Trit>(r);
49
+ }
50
+
51
+ // Polynomial Addition: A + B mod 3
52
+ Poly27 add(const Poly27& a, const Poly27& b) {
53
+ Poly27 res;
54
+ for (int i = 0; i < N; ++i) {
55
+ res.coeffs[i] = reduce3(a.coeffs[i] + b.coeffs[i]);
56
+ }
57
+ return res;
58
+ }
59
+
60
+ // Polynomial Multiplication: A * B mod (x^27 - 1) mod 3
61
+ // Since N=27 is small, we use direct convolution O(N^2).
62
+ // For x^N - 1, index wraps simply: (i + j) % N
63
+ Poly27 multiply(const Poly27& a, const Poly27& b) {
64
+ Poly27 res;
65
+ for (int i = 0; i < N; ++i) {
66
+ for (int j = 0; j < N; ++j) {
67
+ int idx = (i + j) % N; // Cyclic convolution
68
+ int prod = a.coeffs[i] * b.coeffs[j];
69
+ // Accumulate without immediate reduction for speed (optional)
70
+ // But doing it step-wise keeps ints small.
71
+ int current = res.coeffs[idx] + prod;
72
+ res.coeffs[idx] = reduce3(current);
73
+ }
74
+ }
75
+ return res;
76
+ }
77
+
78
+ // ------------------------------------------------------------------------
79
+ // DATA CONVERSION
80
+ // ------------------------------------------------------------------------
81
+
82
+ // Convert raw Bytes to Trits (5 Trits per Byte)
83
+ // 3^5 = 243, so we can map 0-242 exactly.
84
+ // Values 243-255 are wrapped (mod 243) to avoid bias, or just simple mod 3 loop.
85
+ std::vector<Trit> bytesToTrits(const std::vector<uint8_t>& data) {
86
+ std::vector<Trit> trits;
87
+ trits.reserve(data.size() * 5);
88
+
89
+ for (uint8_t b : data) {
90
+ int val = static_cast<int>(b);
91
+ // Extract 5 trits (Little Endian)
92
+ for (int k = 0; k < 5; ++k) {
93
+ trits.push_back(reduce3(val % 3));
94
+ val /= 3;
95
+ }
96
+ }
97
+ return trits;
98
+ }
99
+
100
+ // ------------------------------------------------------------------------
101
+ // CHECKSUM ENGINE
102
+ // ------------------------------------------------------------------------
103
+
104
+ class YPC27Checksum {
105
+ Poly27 state;
106
+ Poly27 seed; // The "Challenge" or "Key" polynomial
107
+
108
+ public:
109
+ // Initialize with a "Seed" (e.g., derived from PeerID or Network Key)
110
+ YPC27Checksum(const Poly27& network_seed) : seed(network_seed) {
111
+ state.coeffs.fill(0);
112
+ }
113
+
114
+ // Rolling Update: State = (State + Input_Poly) * Seed
115
+ // This makes order significant and diffuses the bits across the lattice.
116
+ void update(const std::vector<uint8_t>& data) {
117
+ std::vector<Trit> raw_trits = bytesToTrits(data);
118
+
119
+ // Process in chunks of N (27) trits
120
+ size_t num_chunks = (raw_trits.size() + N - 1) / N;
121
+
122
+ for (size_t k = 0; k < num_chunks; ++k) {
123
+ Poly27 chunk_poly;
124
+ for (int i = 0; i < N; ++i) {
125
+ size_t src_idx = k * N + i;
126
+ if (src_idx < raw_trits.size()) {
127
+ chunk_poly.coeffs[i] = raw_trits[src_idx];
128
+ } else {
129
+ chunk_poly.coeffs[i] = 0; // Padding
130
+ }
131
+ }
132
+
133
+ // The Core "Lattice" Mix: S_new = (S_old + M) * G
134
+ Poly27 sum = add(state, chunk_poly);
135
+ state = multiply(sum, seed);
136
+ }
137
+ }
138
+
139
+ Poly27 digest() const {
140
+ return state;
141
+ }
142
+ };
143
+ }
144
+
145
+ // ----------------------------------------------------------------------------
146
+ // TEST HARNESS
147
+ // ----------------------------------------------------------------------------
148
+ int main() {
149
+ using namespace yakmesh;
150
+
151
+ // 1. Define a Network Seed (e.g., The "Yakmesh Gen 1" constant)
152
+ // In production, this would be hardcoded or derived from the PeerID.
153
+ Poly27 seed;
154
+ for(int i=0; i<N; ++i) seed.coeffs[i] = (i % 3 == 0) ? 1 : (i % 3 == 1) ? -1 : 0;
155
+
156
+ std::cout << "Yakmesh YPC-27 Initialization..." << std::endl;
157
+ std::cout << "Seed Poly: "; seed.print();
158
+
159
+ // 2. Create the Checksum Engine
160
+ YPC27Checksum hasher(seed);
161
+
162
+ // 3. Simulate a Packet (Hello World)
163
+ std::string msg = "Yakmesh_Packet_v1:Keep_It_Ternary";
164
+ std::vector<uint8_t> packet(msg.begin(), msg.end());
165
+
166
+ // 4. Update
167
+ hasher.update(packet);
168
+
169
+ // 5. Final Digest
170
+ Poly27 checksum = hasher.digest();
171
+
172
+ std::cout << "\nInput Data: \"" << msg << "\"" << std::endl;
173
+ std::cout << "YPC-27 Checksum: ";
174
+ checksum.print();
175
+
176
+ // Verification Logic:
177
+ // A receiver does the same. If (Checksum_Calc - Checksum_Header) != 0, drop packet.
178
+ return 0;
179
+ }
package/sbom.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "bomFormat": "CycloneDX",
3
+ "specVersion": "1.4",
4
+ "version": 1,
5
+ "metadata": {
6
+ "timestamp": "2026-02-24T21:17:21.964Z",
7
+ "component": {
8
+ "type": "application",
9
+ "name": "yakmesh",
10
+ "version": "3.0.0"
11
+ }
12
+ },
13
+ "components": [
14
+ {
15
+ "type": "library",
16
+ "name": "@noble/hashes",
17
+ "version": "2.0.0",
18
+ "scope": "required"
19
+ },
20
+ {
21
+ "type": "library",
22
+ "name": "@noble/post-quantum",
23
+ "version": "0.5.4",
24
+ "scope": "required"
25
+ },
26
+ {
27
+ "type": "library",
28
+ "name": "chalk",
29
+ "version": "5.3.0",
30
+ "scope": "required"
31
+ },
32
+ {
33
+ "type": "library",
34
+ "name": "commander",
35
+ "version": "12.0.0",
36
+ "scope": "required"
37
+ },
38
+ {
39
+ "type": "library",
40
+ "name": "express",
41
+ "version": "4.18.2",
42
+ "scope": "required"
43
+ },
44
+ {
45
+ "type": "library",
46
+ "name": "express-rate-limit",
47
+ "version": "8.2.1",
48
+ "scope": "required"
49
+ },
50
+ {
51
+ "type": "library",
52
+ "name": "node-forge",
53
+ "version": "1.3.3",
54
+ "scope": "required"
55
+ },
56
+ {
57
+ "type": "library",
58
+ "name": "onnxruntime-node",
59
+ "version": "1.24.2",
60
+ "scope": "required"
61
+ },
62
+ {
63
+ "type": "library",
64
+ "name": "sql.js",
65
+ "version": "1.10.0",
66
+ "scope": "required"
67
+ },
68
+ {
69
+ "type": "library",
70
+ "name": "ws",
71
+ "version": "8.16.0",
72
+ "scope": "required"
73
+ },
74
+ {
75
+ "type": "library",
76
+ "name": "nodemon",
77
+ "version": "3.0.0",
78
+ "scope": "optional"
79
+ },
80
+ {
81
+ "type": "library",
82
+ "name": "vitest",
83
+ "version": "4.0.17",
84
+ "scope": "optional"
85
+ }
86
+ ]
87
+ }
@@ -0,0 +1,264 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Security Audit Script
4
+ *
5
+ * Runs dependency security checks and generates SBOM.
6
+ * Run before deployment or as part of CI/CD.
7
+ *
8
+ * Usage:
9
+ * node scripts/security-audit.mjs
10
+ * node scripts/security-audit.mjs --fix # Auto-fix where possible
11
+ * node scripts/security-audit.mjs --sbom # Generate SBOM only
12
+ * node scripts/security-audit.mjs --json # JSON output for CI
13
+ *
14
+ * @module scripts/security-audit
15
+ * @version 1.0.0
16
+ */
17
+
18
+ import { spawnSync } from 'child_process';
19
+ import { readFileSync, writeFileSync, existsSync } from 'fs';
20
+ import { join, dirname } from 'path';
21
+ import { fileURLToPath } from 'url';
22
+ import { createHash } from 'crypto';
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ const ROOT_DIR = join(__dirname, '..');
27
+
28
+ const args = process.argv.slice(2);
29
+ const FIX_MODE = args.includes('--fix');
30
+ const SBOM_ONLY = args.includes('--sbom');
31
+ const JSON_OUTPUT = args.includes('--json');
32
+
33
+ const results = {
34
+ timestamp: new Date().toISOString(),
35
+ audit: null,
36
+ lockfileIntegrity: null,
37
+ sbom: null,
38
+ recommendations: [],
39
+ };
40
+
41
+ /**
42
+ * Run npm audit
43
+ */
44
+ function runAudit() {
45
+ console.log('\n📦 Running npm audit...\n');
46
+
47
+ try {
48
+ const cmdArgs = FIX_MODE
49
+ ? ['audit', 'fix', '--audit-level=moderate']
50
+ : ['audit', '--json'];
51
+
52
+ const result = spawnSync('npm', cmdArgs, {
53
+ cwd: ROOT_DIR,
54
+ encoding: 'utf-8',
55
+ shell: true,
56
+ });
57
+
58
+ if (JSON_OUTPUT || !FIX_MODE) {
59
+ try {
60
+ const auditData = JSON.parse(result.stdout);
61
+ results.audit = {
62
+ vulnerabilities: auditData.metadata?.vulnerabilities || {},
63
+ totalDependencies: auditData.metadata?.dependencies?.total || 0,
64
+ advisories: Object.keys(auditData.advisories || {}).length,
65
+ };
66
+
67
+ const vulns = results.audit.vulnerabilities;
68
+ const total = (vulns.critical || 0) + (vulns.high || 0) + (vulns.moderate || 0) + (vulns.low || 0);
69
+
70
+ if (vulns.critical > 0) {
71
+ results.recommendations.push(`🔴 CRITICAL: ${vulns.critical} critical vulnerabilities found!`);
72
+ }
73
+ if (vulns.high > 0) {
74
+ results.recommendations.push(`🟠 HIGH: ${vulns.high} high severity vulnerabilities`);
75
+ }
76
+
77
+ console.log(` Total dependencies: ${results.audit.totalDependencies}`);
78
+ console.log(` Vulnerabilities: ${total} (${vulns.critical || 0} critical, ${vulns.high || 0} high)`);
79
+
80
+ return total === 0;
81
+ } catch (e) {
82
+ // npm audit returns non-zero on vulnerabilities, output may not be valid JSON
83
+ if (result.stderr) {
84
+ console.log(' Audit stderr:', result.stderr.slice(0, 200));
85
+ }
86
+ results.audit = { raw: result.stdout?.slice(0, 500) };
87
+ return false;
88
+ }
89
+ } else {
90
+ console.log(result.stdout);
91
+ return result.status === 0;
92
+ }
93
+ } catch (e) {
94
+ console.error(' Audit failed:', e.message);
95
+ results.audit = { error: e.message };
96
+ return false;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Verify package-lock.json integrity
102
+ */
103
+ function verifyLockfile() {
104
+ console.log('\n🔒 Verifying lockfile integrity...\n');
105
+
106
+ const lockPath = join(ROOT_DIR, 'package-lock.json');
107
+
108
+ if (!existsSync(lockPath)) {
109
+ console.log(' ⚠️ No package-lock.json found');
110
+ results.lockfileIntegrity = { exists: false };
111
+ results.recommendations.push('Generate package-lock.json with npm install');
112
+ return false;
113
+ }
114
+
115
+ try {
116
+ const lockContent = readFileSync(lockPath, 'utf-8');
117
+ const lockData = JSON.parse(lockContent);
118
+
119
+ // Calculate hash of lockfile
120
+ const hash = createHash('sha256').update(lockContent).digest('hex');
121
+
122
+ results.lockfileIntegrity = {
123
+ exists: true,
124
+ hash: hash.slice(0, 16),
125
+ lockfileVersion: lockData.lockfileVersion,
126
+ packageCount: Object.keys(lockData.packages || {}).length,
127
+ };
128
+
129
+ console.log(` Lockfile version: ${lockData.lockfileVersion}`);
130
+ console.log(` Packages locked: ${results.lockfileIntegrity.packageCount}`);
131
+ console.log(` Lockfile hash: ${hash.slice(0, 16)}...`);
132
+
133
+ // Verify with npm ci (dry run)
134
+ const verifyResult = spawnSync('npm', ['ci', '--dry-run'], {
135
+ cwd: ROOT_DIR,
136
+ encoding: 'utf-8',
137
+ shell: true,
138
+ });
139
+
140
+ if (verifyResult.status === 0) {
141
+ console.log(' ✓ Lockfile is valid and consistent');
142
+ return true;
143
+ } else {
144
+ console.log(' ⚠️ Lockfile may be out of sync with package.json');
145
+ results.recommendations.push('Run npm install to regenerate lockfile');
146
+ return false;
147
+ }
148
+ } catch (e) {
149
+ console.error(' Lockfile verification failed:', e.message);
150
+ results.lockfileIntegrity = { error: e.message };
151
+ return false;
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Generate Software Bill of Materials (SBOM)
157
+ */
158
+ function generateSBOM() {
159
+ console.log('\n📋 Generating SBOM...\n');
160
+
161
+ const packagePath = join(ROOT_DIR, 'package.json');
162
+ const lockPath = join(ROOT_DIR, 'package-lock.json');
163
+
164
+ try {
165
+ const pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
166
+ const lock = existsSync(lockPath) ? JSON.parse(readFileSync(lockPath, 'utf-8')) : null;
167
+
168
+ const sbom = {
169
+ bomFormat: 'CycloneDX',
170
+ specVersion: '1.4',
171
+ version: 1,
172
+ metadata: {
173
+ timestamp: new Date().toISOString(),
174
+ component: {
175
+ type: 'application',
176
+ name: pkg.name,
177
+ version: pkg.version,
178
+ },
179
+ },
180
+ components: [],
181
+ };
182
+
183
+ // Add direct dependencies
184
+ for (const [name, version] of Object.entries(pkg.dependencies || {})) {
185
+ sbom.components.push({
186
+ type: 'library',
187
+ name,
188
+ version: version.replace(/^[\^~]/, ''),
189
+ scope: 'required',
190
+ });
191
+ }
192
+
193
+ // Add dev dependencies
194
+ for (const [name, version] of Object.entries(pkg.devDependencies || {})) {
195
+ sbom.components.push({
196
+ type: 'library',
197
+ name,
198
+ version: version.replace(/^[\^~]/, ''),
199
+ scope: 'optional',
200
+ });
201
+ }
202
+
203
+ const sbomPath = join(ROOT_DIR, 'sbom.json');
204
+ writeFileSync(sbomPath, JSON.stringify(sbom, null, 2));
205
+
206
+ results.sbom = {
207
+ generated: true,
208
+ path: 'sbom.json',
209
+ componentCount: sbom.components.length,
210
+ };
211
+
212
+ console.log(` Generated sbom.json with ${sbom.components.length} components`);
213
+ console.log(` Direct deps: ${Object.keys(pkg.dependencies || {}).length}`);
214
+ console.log(` Dev deps: ${Object.keys(pkg.devDependencies || {}).length}`);
215
+
216
+ return true;
217
+ } catch (e) {
218
+ console.error(' SBOM generation failed:', e.message);
219
+ results.sbom = { error: e.message };
220
+ return false;
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Main
226
+ */
227
+ async function main() {
228
+ console.log('╔════════════════════════════════════════════════════════════╗');
229
+ console.log('║ YAKMESH SECURITY AUDIT ║');
230
+ console.log('╚════════════════════════════════════════════════════════════╝');
231
+
232
+ let allPassed = true;
233
+
234
+ if (SBOM_ONLY) {
235
+ generateSBOM();
236
+ } else {
237
+ allPassed = runAudit() && allPassed;
238
+ allPassed = verifyLockfile() && allPassed;
239
+ generateSBOM();
240
+ }
241
+
242
+ console.log('\n═══════════════════════════════════════════════════════════════');
243
+
244
+ if (results.recommendations.length > 0) {
245
+ console.log('\n📝 Recommendations:\n');
246
+ for (const rec of results.recommendations) {
247
+ console.log(` ${rec}`);
248
+ }
249
+ }
250
+
251
+ if (JSON_OUTPUT) {
252
+ console.log('\n📊 JSON Results:\n');
253
+ console.log(JSON.stringify(results, null, 2));
254
+ }
255
+
256
+ console.log('\n' + (allPassed ? '✅ Security audit passed' : '⚠️ Security issues detected'));
257
+
258
+ process.exit(allPassed ? 0 : 1);
259
+ }
260
+
261
+ main().catch(e => {
262
+ console.error('Audit failed:', e);
263
+ process.exit(1);
264
+ });