yakmesh 2.5.0 → 2.6.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.
package/README.md CHANGED
@@ -134,19 +134,24 @@ yakmesh/
134
134
 
135
135
  ## Network Identity
136
136
 
137
- Each YAKMESH network has a unique identity derived from configurable salts:
137
+ Each YAKMESH network has a unique identity derived from the **oracle's code hash** — a deterministic fingerprint of the codebase itself. This means the code IS the identity.
138
138
 
139
139
  ```javascript
140
- import { setIdentityConfig } from 'yakmesh/oracle/network-identity.js';
140
+ // Network identity is AUTOMATIC - derived from code hash
141
+ // When you run a node, it computes:
142
+ // 1. Code hash → cryptographic identity of the codebase
143
+ // 2. Network name → human-readable name (e.g., "factor-primitive-bose")
144
+ // 3. Verification phrase → speakable phrase for verbal verification
141
145
 
142
- setIdentityConfig({
143
- networkPrefix: 'my', // Network ID prefix
144
- identitySalt: 'my-app-v1', // Unique network salt
145
- });
146
+ // The identity functions are available for inspection:
147
+ import { deriveNetworkName, deriveVerificationPhrase } from 'yakmesh/oracle/network-identity.js';
146
148
 
147
- // Different salt = different network (cannot interoperate)
149
+ // Same code = same network. Different code = different network.
150
+ // No configuration needed - the math handles network separation.
148
151
  ```
149
152
 
153
+ **Key Principle:** Two nodes running the same YAKMESH version will automatically be on the same network. Fork the code or modify the oracle, and you're on a different network entirely.
154
+
150
155
  ## Time Source Trust Levels
151
156
 
152
157
  | Level | Source | Tolerance | Oracle Capable |
@@ -42,6 +42,11 @@ Get-ChildItem -Recurse -Filter "*.js" | Select-String -Pattern "ml_dsa65\.(sign|
42
42
  - [ ] **API documentation matches implementation** - Check function signatures
43
43
  - [ ] **CHANGELOG.md updated** - Version, date, and all changes documented
44
44
  - [ ] **Migration guide** (if breaking changes) - Clear upgrade path for users
45
+ - [ ] **Docs bundle regenerated** - Run `npm run build:docs` before release
46
+ ```powershell
47
+ npm run build:docs
48
+ # Verify output shows correct file count and bundle hash
49
+ ```
45
50
 
46
51
  ### 5. Version Management
47
52
 
@@ -86,6 +91,7 @@ node -e "const yk = require('yakmesh-node'); console.log('Import successful')"
86
91
  | `oracle/module-sealer.js` | Module attestation | HIGH |
87
92
  | `mesh/nakpak-routing.js` | Packet signing | HIGH |
88
93
  | `identity/node-key.js` | Node authentication | HIGH |
94
+ | `embedded-docs/bundle.js` | Documentation hashes | MEDIUM |
89
95
 
90
96
  ## Known Pitfalls
91
97
 
package/cli/index.js CHANGED
@@ -823,6 +823,182 @@ geoCmd
823
823
  console.log('');
824
824
  });
825
825
 
826
+ // ===== DOCS COMMAND GROUP =====
827
+ const docsCmd = program
828
+ .command('docs')
829
+ .description('Embedded documentation management');
830
+
831
+ // docs info - Show bundle information
832
+ docsCmd
833
+ .command('info')
834
+ .description('Show documentation bundle information')
835
+ .action(async () => {
836
+ try {
837
+ const { getBundleInfo, BUNDLE_HASH, BUNDLE_VERSION } = await import('../embedded-docs/index.js');
838
+ const info = getBundleInfo();
839
+
840
+ console.log(chalk.cyan('\n📦 YAKMESH Embedded Documentation Bundle\n'));
841
+ console.log(chalk.white(' Bundle Hash:'), chalk.yellow(BUNDLE_HASH));
842
+ console.log(chalk.white(' Version: '), chalk.green(BUNDLE_VERSION));
843
+ console.log(chalk.white(' Files: '), info.fileCount);
844
+ console.log(chalk.white(' Total Size: '), Math.round(info.totalSize / 1024) + ' KB');
845
+ console.log('');
846
+ console.log(chalk.gray(' Run "yakmesh docs verify" to verify bundle integrity.'));
847
+ console.log(chalk.gray(' Run "yakmesh docs list" to see all files.'));
848
+ console.log('');
849
+ } catch (err) {
850
+ console.error(chalk.red('✗ Error loading docs bundle:'), err.message);
851
+ process.exit(1);
852
+ }
853
+ });
854
+
855
+ // docs verify - Verify bundle integrity
856
+ docsCmd
857
+ .command('verify')
858
+ .description('Verify documentation bundle integrity using SHA3-256')
859
+ .option('-v, --verbose', 'Show individual file verification results')
860
+ .action(async (options) => {
861
+ try {
862
+ const { getBundleInfo, getDocsFile, verifyFile, BUNDLE_HASH } = await import('../embedded-docs/index.js');
863
+ const info = getBundleInfo();
864
+
865
+ console.log(chalk.cyan('\n🔐 Verifying Documentation Bundle...\n'));
866
+
867
+ let verified = 0;
868
+ let failed = 0;
869
+
870
+ for (const filePath of info.files) {
871
+ const file = getDocsFile(filePath);
872
+ if (!file) {
873
+ if (options.verbose) {
874
+ console.log(chalk.red(' ✗'), filePath, chalk.gray('- FILE MISSING'));
875
+ }
876
+ failed++;
877
+ continue;
878
+ }
879
+
880
+ const result = verifyFile(filePath, file.content);
881
+ if (result.valid) {
882
+ verified++;
883
+ if (options.verbose) {
884
+ console.log(chalk.green(' ✓'), filePath, chalk.gray(`(${file.content.length} bytes)`));
885
+ }
886
+ } else {
887
+ failed++;
888
+ if (options.verbose) {
889
+ console.log(chalk.red(' ✗'), filePath, chalk.gray('- HASH MISMATCH'));
890
+ }
891
+ }
892
+ }
893
+
894
+ console.log('');
895
+ if (failed === 0) {
896
+ console.log(chalk.green('✓ Bundle verification PASSED'));
897
+ console.log(chalk.gray(` ${verified} files verified`));
898
+ console.log(chalk.gray(` Bundle: ${BUNDLE_HASH.substring(0, 32)}...`));
899
+ } else {
900
+ console.log(chalk.red('✗ Bundle verification FAILED'));
901
+ console.log(chalk.gray(` ${verified} passed, ${failed} failed`));
902
+ process.exit(1);
903
+ }
904
+ console.log('');
905
+ } catch (err) {
906
+ console.error(chalk.red('✗ Error:'), err.message);
907
+ process.exit(1);
908
+ }
909
+ });
910
+
911
+ // docs list - List all files in bundle
912
+ docsCmd
913
+ .command('list')
914
+ .description('List all files in the documentation bundle')
915
+ .option('--html', 'Show only HTML files')
916
+ .option('--json', 'Output as JSON')
917
+ .action(async (options) => {
918
+ try {
919
+ const { getBundleInfo, FILE_INDEX } = await import('../embedded-docs/index.js');
920
+ const info = getBundleInfo();
921
+
922
+ let files = info.files;
923
+ if (options.html) {
924
+ files = files.filter(f => f.endsWith('.html'));
925
+ }
926
+
927
+ if (options.json) {
928
+ console.log(JSON.stringify({ files, count: files.length }, null, 2));
929
+ return;
930
+ }
931
+
932
+ console.log(chalk.cyan(`\n📄 Documentation Files (${files.length})\n`));
933
+ for (const file of files.sort()) {
934
+ const meta = FILE_INDEX[file];
935
+ const size = meta ? Math.round(meta.size / 1024) + ' KB' : '?';
936
+ console.log(chalk.gray(' -'), file, chalk.gray(`(${size})`));
937
+ }
938
+ console.log('');
939
+ } catch (err) {
940
+ console.error(chalk.red('✗ Error:'), err.message);
941
+ process.exit(1);
942
+ }
943
+ });
944
+
945
+ // docs serve - Start documentation server
946
+ docsCmd
947
+ .command('serve')
948
+ .description('Start a local documentation server')
949
+ .option('-p, --port <port>', 'Port to serve on', '8080')
950
+ .action(async (options) => {
951
+ try {
952
+ const express = (await import('express')).default;
953
+ const { serveDocsFile, getBundleInfo, BUNDLE_HASH } = await import('../embedded-docs/index.js');
954
+
955
+ const app = express();
956
+ const port = parseInt(options.port);
957
+
958
+ // Order matters! Specific routes first to avoid redirect loops
959
+ app.get('/docs/_bundle', (req, res) => res.json(getBundleInfo()));
960
+ app.get('/docs/index.html', (req, res) => serveDocsFile('index.html', res));
961
+ app.get('/docs/', (req, res) => serveDocsFile('index.html', res));
962
+ app.get('/docs', (req, res) => res.redirect('/docs/'));
963
+ app.get('/docs/:file', (req, res) => {
964
+ const file = req.params.file || 'index.html';
965
+ serveDocsFile(file, res);
966
+ });
967
+
968
+ // Serve assets (silhouettes, etc.) - CSS references ../assets/ from /docs/
969
+ app.get('/assets/*', (req, res) => {
970
+ const assetPath = req.path.substring(1); // Remove leading /
971
+ serveDocsFile(assetPath, res);
972
+ });
973
+
974
+ app.get('/', (req, res) => res.redirect('/docs/'));
975
+
976
+ app.listen(port, '0.0.0.0', () => {
977
+ console.log(chalk.cyan('\n📦 YAKMESH Documentation Server\n'));
978
+ console.log(chalk.white(' URL: '), chalk.green(`http://localhost:${port}/docs/`));
979
+ console.log(chalk.white(' Bundle: '), chalk.gray(BUNDLE_HASH.substring(0, 24) + '...'));
980
+ console.log(chalk.white(' Files: '), getBundleInfo().fileCount);
981
+ console.log('');
982
+ console.log(chalk.gray(' Press Ctrl+C to stop.'));
983
+ console.log('');
984
+ });
985
+ } catch (err) {
986
+ console.error(chalk.red('✗ Error:'), err.message);
987
+ process.exit(1);
988
+ }
989
+ });
990
+
991
+ // docs rebuild - Rebuild the bundle (for developers)
992
+ docsCmd
993
+ .command('rebuild')
994
+ .description('Rebuild documentation bundle (development only)')
995
+ .action(async () => {
996
+ console.log(chalk.cyan('\n📦 Rebuilding Documentation Bundle...\n'));
997
+ console.log(chalk.gray(' Run this command from the yakmesh-node directory:'));
998
+ console.log(chalk.white(' npm run build:docs'));
999
+ console.log('');
1000
+ });
1001
+
826
1002
  // ===== VERSION =====
827
1003
  program
828
1004
  .version(VERSION)
@@ -0,0 +1,339 @@
1
+ /**
2
+ * YAKMESH Embedded Documentation Bundle
3
+ *
4
+ * AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
5
+ *
6
+ * Regenerate with: npm run build:docs
7
+ * Source: website/docs/
8
+ *
9
+ * @generated 2026-02-01T03:15:20.104Z
10
+ * @module embedded-docs/bundle
11
+ */
12
+
13
+ /**
14
+ * Master hash of the entire documentation bundle.
15
+ * Computed as: SHA3-256(sorted individual file hashes joined)
16
+ */
17
+ export const BUNDLE_HASH = 'd431166e8bf0458df547a93d6d388b9599e8219ea76a322654a0f8342da4dae4';
18
+
19
+ /**
20
+ * Version of the documentation bundle.
21
+ * Matches the npm package version at build time.
22
+ */
23
+ export const BUNDLE_VERSION = '2.6.0';
24
+
25
+ /**
26
+ * Build timestamp (ISO 8601)
27
+ */
28
+ export const BUNDLE_BUILT_AT = '2026-02-01T03:15:20.104Z';
29
+
30
+ /**
31
+ * Index of all files in the documentation bundle.
32
+ *
33
+ * Each entry contains:
34
+ * - hash: SHA3-256 hash of the file content
35
+ * - size: File size in bytes
36
+ * - contentType: MIME type for HTTP serving
37
+ *
38
+ * @type {Record<string, {hash: string, size: number, contentType: string}>}
39
+ */
40
+ export const FILE_INDEX = {
41
+ "adapters.html": {
42
+ "hash": "a4725f50254405c2707ad6ba97727c03ae18746724a1f7425df4abd196a68de8",
43
+ "size": 11778,
44
+ "contentType": "text/html; charset=utf-8"
45
+ },
46
+ "advanced-systems.html": {
47
+ "hash": "cd95be42f7a41f924a9595017fa9b3de6aa33e7da3a5003faf86db470852a3bd",
48
+ "size": 22922,
49
+ "contentType": "text/html; charset=utf-8"
50
+ },
51
+ "annex.html": {
52
+ "hash": "49ac93e2e79a786760b006bb03d046f4968c6d7ed101fa893b3791f2301cd7c1",
53
+ "size": 28147,
54
+ "contentType": "text/html; charset=utf-8"
55
+ },
56
+ "api.html": {
57
+ "hash": "38e59308cb3c16fddd71705651ada0846d0b26b50ddffee31302d685c257dfdb",
58
+ "size": 18875,
59
+ "contentType": "text/html; charset=utf-8"
60
+ },
61
+ "cli.html": {
62
+ "hash": "236c17ee7e57d7b733e87f5dc1f1f4aee3754fd638e84db9539858cb2e7bb6e1",
63
+ "size": 38666,
64
+ "contentType": "text/html; charset=utf-8"
65
+ },
66
+ "configuration.html": {
67
+ "hash": "c0fb9aca6c21f856db7d60721877ea9a100c3e71eef3e2661ae19f5151e9d292",
68
+ "size": 33144,
69
+ "contentType": "text/html; charset=utf-8"
70
+ },
71
+ "docs-bundle.html": {
72
+ "hash": "f8c5b1d11bf509bef66e2469fc3aa30aea8154089c1c7a6bd36b27653aa048f5",
73
+ "size": 18787,
74
+ "contentType": "text/html; charset=utf-8"
75
+ },
76
+ "docs.css": {
77
+ "hash": "a5cc0ed95d5405e0e3824055abf215e8bdb45a89eb8f714a19b22ffdda2d597d",
78
+ "size": 36002,
79
+ "contentType": "text/css; charset=utf-8"
80
+ },
81
+ "docs.js": {
82
+ "hash": "c29823d705194d455ec85f408de3ca2e81052414814f54711ba6a3b33e4f8e3d",
83
+ "size": 4434,
84
+ "contentType": "application/javascript; charset=utf-8"
85
+ },
86
+ "doko.html": {
87
+ "hash": "7d7eb43e93196612a5c85bb61d97922750f4214ff63ec06bb9e1d6fd775932ce",
88
+ "size": 20893,
89
+ "contentType": "text/html; charset=utf-8"
90
+ },
91
+ "geo-proof.html": {
92
+ "hash": "33e0ec948fa10c85a2d8806bee6823708a75e8d4d1d363c25a954c470bb5ee5e",
93
+ "size": 15543,
94
+ "contentType": "text/html; charset=utf-8"
95
+ },
96
+ "getting-started.html": {
97
+ "hash": "5dc03a8f417d306af232c1f20a35d6e5832640eee2e6af0737bcbabc38e238ea",
98
+ "size": 13401,
99
+ "contentType": "text/html; charset=utf-8"
100
+ },
101
+ "index.html": {
102
+ "hash": "56a4148a1c594976e52bb3e17a175a3e8586aa92fa9bbac40c0ed096ef36c54a",
103
+ "size": 12944,
104
+ "contentType": "text/html; charset=utf-8"
105
+ },
106
+ "karma.html": {
107
+ "hash": "a86ef77a6873b8f404df22f364ce017872b0d6039388cd3d42ae043a07f18860",
108
+ "size": 18123,
109
+ "contentType": "text/html; charset=utf-8"
110
+ },
111
+ "lama.html": {
112
+ "hash": "20fc0c463049659771212eacc12a7d5def640ba75afecb3eb79565d7f917be7d",
113
+ "size": 16483,
114
+ "contentType": "text/html; charset=utf-8"
115
+ },
116
+ "mandala.html": {
117
+ "hash": "50a667cc5d75450e67012b2ff7b81bc1c7012a312cd988b912d6d27ae26e4060",
118
+ "size": 19988,
119
+ "contentType": "text/html; charset=utf-8"
120
+ },
121
+ "mani.html": {
122
+ "hash": "f0c4f8f6f65c68dc70d38d9790a3d62d7b048a0bb6b190d5e10a4e9a71f6653a",
123
+ "size": 15992,
124
+ "contentType": "text/html; charset=utf-8"
125
+ },
126
+ "mantra.html": {
127
+ "hash": "76c3bff0a66c2d8d923dd3ddcb4f88c93ef9e390cd36de6f828c8da0da404302",
128
+ "size": 21140,
129
+ "contentType": "text/html; charset=utf-8"
130
+ },
131
+ "mesh.html": {
132
+ "hash": "db779eaf76998f53cf29209b89613dc2571b1a4b19c8b8ae7d6ba0e7f57bf6a4",
133
+ "size": 46268,
134
+ "contentType": "text/html; charset=utf-8"
135
+ },
136
+ "nakpak.html": {
137
+ "hash": "521bfd22b47a3876f25f1747ef46d30b155f7672e1f31546a9516c8d5e06f2f7",
138
+ "size": 16535,
139
+ "contentType": "text/html; charset=utf-8"
140
+ },
141
+ "namche.html": {
142
+ "hash": "bb5070ab9f016ba2050c33743a1b8bee495852c3f743c0cb42fa60dadb52c7e0",
143
+ "size": 17615,
144
+ "contentType": "text/html; charset=utf-8"
145
+ },
146
+ "privacy.html": {
147
+ "hash": "e274c5afe9c2188f7840bf78edbc0b45e03e537430cf237a5b7382567a1a623c",
148
+ "size": 8047,
149
+ "contentType": "text/html; charset=utf-8"
150
+ },
151
+ "sherpa.html": {
152
+ "hash": "e5b97f5d68e8a89df4fa3358d50ea7340ff9fafe16b1e272d171320a0a2af202",
153
+ "size": 14989,
154
+ "contentType": "text/html; charset=utf-8"
155
+ },
156
+ "stupa.html": {
157
+ "hash": "9c79a8984aab8b6e8d5b80170945030538b7ca6c4a41f9ed0ca6098f50551496",
158
+ "size": 16908,
159
+ "contentType": "text/html; charset=utf-8"
160
+ },
161
+ "tattva.html": {
162
+ "hash": "e4dd2105547b6f1b93fcca0f2ac34e9bf6e561c4f0956db06680b96b40786a01",
163
+ "size": 40704,
164
+ "contentType": "text/html; charset=utf-8"
165
+ },
166
+ "terms.html": {
167
+ "hash": "80e8639dd57ce83e3b9419c3eff222c2cd4fa08c2e8521ad5430f065a2d52e12",
168
+ "size": 7100,
169
+ "contentType": "text/html; charset=utf-8"
170
+ },
171
+ "time-sources.html": {
172
+ "hash": "90e9c5cd635d1b71010e87e0ea246bbacf188aad56351670b5004c691d4ad5f6",
173
+ "size": 43621,
174
+ "contentType": "text/html; charset=utf-8"
175
+ },
176
+ "trademark-policy.html": {
177
+ "hash": "e76cd517163e1c39e88efcf79c333d0efaf0a8460c70adeb7f5ebbe4ecca316b",
178
+ "size": 6728,
179
+ "contentType": "text/html; charset=utf-8"
180
+ },
181
+ "trust-security.html": {
182
+ "hash": "504f324d0197e2edf41da03cb2f2ef738f9e3d023b2ebfae9bee7292d6fedf62",
183
+ "size": 22932,
184
+ "contentType": "text/html; charset=utf-8"
185
+ },
186
+ "webserver.html": {
187
+ "hash": "6639bf4f609ab1d8f08e05fbfccd15421c702d09e3476217253e2a0eeed95a5e",
188
+ "size": 12349,
189
+ "contentType": "text/html; charset=utf-8"
190
+ },
191
+ "yak-protocol.html": {
192
+ "hash": "016cae60a3657c5f18843a634b83720e9b42efaaa6da2e599929c7813f7d5e3b",
193
+ "size": 18748,
194
+ "contentType": "text/html; charset=utf-8"
195
+ },
196
+ "assets/silhouettes/adapters.svg": {
197
+ "hash": "32866be4a0383dd4b0fa894d6fb167ea2af5858c591c3c654bb6a3070994d793",
198
+ "size": 6708,
199
+ "contentType": "image/svg+xml"
200
+ },
201
+ "assets/silhouettes/api-endpoints.svg": {
202
+ "hash": "012ed02645e2fdb9895c118b3f1f718e61e27ff8749b7a16554ee6e8b24d7c10",
203
+ "size": 8124,
204
+ "contentType": "image/svg+xml"
205
+ },
206
+ "assets/silhouettes/atomic-clock.svg": {
207
+ "hash": "d7607ae676c88d4e9cdefad4270ca502304dab6252ee90e955852f30ffdf628f",
208
+ "size": 4664,
209
+ "contentType": "image/svg+xml"
210
+ },
211
+ "assets/silhouettes/base-camp.svg": {
212
+ "hash": "36acb01a56f0cf26556e8453c64efb084ec0a9a150fded380355aec7a7f953d0",
213
+ "size": 4560,
214
+ "contentType": "image/svg+xml"
215
+ },
216
+ "assets/silhouettes/bridge.svg": {
217
+ "hash": "f0e10869c1dc5d7ac40b23fb0a76d3b2575eb03f618a308fdd5ec5414bfc6da7",
218
+ "size": 4171,
219
+ "contentType": "image/svg+xml"
220
+ },
221
+ "assets/silhouettes/docs-bundle.svg": {
222
+ "hash": "686a9f08e44de90a4727302f0e285e08eb46ce0934f4b39f6f2ebb191b75178b",
223
+ "size": 5325,
224
+ "contentType": "image/svg+xml"
225
+ },
226
+ "assets/silhouettes/doko-basket.svg": {
227
+ "hash": "695a0e8a4f16a65aad2b5457e5e95237ecc6b1f893ad1e37c3f6496322ff42a6",
228
+ "size": 3780,
229
+ "contentType": "image/svg+xml"
230
+ },
231
+ "assets/silhouettes/fortress.svg": {
232
+ "hash": "3708addbb09b31e256e3f83a64cc37531bd12ce46dac3236cce5054d07c82cac",
233
+ "size": 5127,
234
+ "contentType": "image/svg+xml"
235
+ },
236
+ "assets/silhouettes/gateway.svg": {
237
+ "hash": "bb6d361cc2a4a61b239d17685ac71697c4c1c8375ac9c42aac2cf718ebb2b525",
238
+ "size": 3134,
239
+ "contentType": "image/svg+xml"
240
+ },
241
+ "assets/silhouettes/gears.svg": {
242
+ "hash": "d7f5cc8a0026f8d89cccc161602e220626c731ad8c9c3b61f48ebbbe6a673978",
243
+ "size": 5644,
244
+ "contentType": "image/svg+xml"
245
+ },
246
+ "assets/silhouettes/globe-satellite.svg": {
247
+ "hash": "a7b34b82e475dec67a8ea716581b204b0353a579665673d796accc375546ba64",
248
+ "size": 3996,
249
+ "contentType": "image/svg+xml"
250
+ },
251
+ "assets/silhouettes/karma-wheel.svg": {
252
+ "hash": "7f19d8646e21aefa249c41837734d90b1e61d8d93b329568b0cfa17890ab39f0",
253
+ "size": 8840,
254
+ "contentType": "image/svg+xml"
255
+ },
256
+ "assets/silhouettes/lama-council.svg": {
257
+ "hash": "f53805c635fdf3c8a398eab7a35899a9b66bba81ff79742ef1ba9c0699793ced",
258
+ "size": 8840,
259
+ "contentType": "image/svg+xml"
260
+ },
261
+ "assets/silhouettes/mandala-network.svg": {
262
+ "hash": "c87d81102804ef014fa34a1e640cc0b9e02c5c612c42125b459241b877b9f273",
263
+ "size": 9991,
264
+ "contentType": "image/svg+xml"
265
+ },
266
+ "assets/silhouettes/mani-stones.svg": {
267
+ "hash": "af42b53aca0ba0f65b80280110243880fc6ee3732743b5d15ce5f76927dd828e",
268
+ "size": 9129,
269
+ "contentType": "image/svg+xml"
270
+ },
271
+ "assets/silhouettes/mantra-wheel.svg": {
272
+ "hash": "3c965a1eb96442b6aaea8afc86d8cc3041a706a5748f5683bc0b61285c777719",
273
+ "size": 7215,
274
+ "contentType": "image/svg+xml"
275
+ },
276
+ "assets/silhouettes/mesh-nodes.svg": {
277
+ "hash": "c9f04677bc1a4f9829d901f53dbafc1aba335d90c18ddba67a028c241d20d4a4",
278
+ "size": 6767,
279
+ "contentType": "image/svg+xml"
280
+ },
281
+ "assets/silhouettes/nakpak.svg": {
282
+ "hash": "25c7ac4dff1434586a3919180dab3b99d6dfa54a435585c310cbc52930fb224e",
283
+ "size": 3245,
284
+ "contentType": "image/svg+xml"
285
+ },
286
+ "assets/silhouettes/peak-lightning.svg": {
287
+ "hash": "2019232dfec6a0a9ea8037010885eb41ffb4e2982c3877e131c5888dd1b1da54",
288
+ "size": 3862,
289
+ "contentType": "image/svg+xml"
290
+ },
291
+ "assets/silhouettes/sherpa.svg": {
292
+ "hash": "f529f52b0e71ee59f2668cbb75b099a094ee8de78780aaa45fdbf39f8052260a",
293
+ "size": 3360,
294
+ "contentType": "image/svg+xml"
295
+ },
296
+ "assets/silhouettes/stupa-tower.svg": {
297
+ "hash": "6a47f026b7cd936cf0da977d13e0586c19227dac0b3563c80fb1b02067e4a19c",
298
+ "size": 7242,
299
+ "contentType": "image/svg+xml"
300
+ },
301
+ "assets/silhouettes/tattva-eye.svg": {
302
+ "hash": "afabc2644033018a2711771ad353eba41d69bd9a8213567696ffb66edb95cc05",
303
+ "size": 4738,
304
+ "contentType": "image/svg+xml"
305
+ },
306
+ "assets/silhouettes/terminal.svg": {
307
+ "hash": "52a9cecb6bd1ce79f2b4b793538a6080c81716cc5d46e83403cb32304c4952e2",
308
+ "size": 4428,
309
+ "contentType": "image/svg+xml"
310
+ },
311
+ "assets/silhouettes/webserver.svg": {
312
+ "hash": "1cea58597a31a9fd7ed9374f024348b2eb1dd5e44d710582aa3b09a932319056",
313
+ "size": 9166,
314
+ "contentType": "image/svg+xml"
315
+ },
316
+ "assets/silhouettes/yak.svg": {
317
+ "hash": "3b548d18156638b3fcdf3f5567b4c8542c78a4c7c4a83dc2152ef894125641e3",
318
+ "size": 4005,
319
+ "contentType": "image/svg+xml"
320
+ }
321
+ };
322
+
323
+ /**
324
+ * Check if a file exists in the bundle
325
+ * @param {string} path - File path relative to docs root
326
+ * @returns {boolean}
327
+ */
328
+ export function hasFile(path) {
329
+ return path in FILE_INDEX;
330
+ }
331
+
332
+ /**
333
+ * Get file metadata from the bundle
334
+ * @param {string} path - File path relative to docs root
335
+ * @returns {{hash: string, size: number, contentType: string} | null}
336
+ */
337
+ export function getFileMeta(path) {
338
+ return FILE_INDEX[path] || null;
339
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * YAKMESH Embedded Documentation Module
3
+ *
4
+ * Self-contained, mathematically verified documentation that ships
5
+ * with every YAKMESH node. No network required - docs are local.
6
+ *
7
+ * @module embedded-docs
8
+ * @author YAKMESH Team
9
+ * @license MIT
10
+ */
11
+
12
+ // Core exports
13
+ export { BUNDLE_HASH, BUNDLE_VERSION, FILE_INDEX } from './bundle.js';
14
+ export { verifyFile, verifyBundle, getBundleInfo } from './verify.js';
15
+ export { createDocsRouter, serveDocsFile, getDocsFile } from './serve.js';
16
+
17
+ // Re-export content types for convenience
18
+ export const DOCS_CONTENT_TYPES = {
19
+ '.html': 'text/html; charset=utf-8',
20
+ '.css': 'text/css; charset=utf-8',
21
+ '.js': 'application/javascript; charset=utf-8',
22
+ '.svg': 'image/svg+xml',
23
+ '.png': 'image/png',
24
+ '.jpg': 'image/jpeg',
25
+ '.ico': 'image/x-icon',
26
+ '.woff': 'font/woff',
27
+ '.woff2': 'font/woff2',
28
+ '.json': 'application/json',
29
+ };
30
+
31
+ /**
32
+ * Get content type for a file path
33
+ * @param {string} path - File path
34
+ * @returns {string} Content type
35
+ */
36
+ export function getContentType(path) {
37
+ const ext = path.substring(path.lastIndexOf('.'));
38
+ return DOCS_CONTENT_TYPES[ext] || 'application/octet-stream';
39
+ }