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,400 @@
1
+ /**
2
+ * Yakmesh - Modern Literal Version Bible Adapter
3
+ *
4
+ * Serves the Modern Literal Version Bible (https://www.modernliteralversion.org)
5
+ * via DARSHAN streaming and provides scripture lookup for KATHA chat.
6
+ *
7
+ * This adapter demonstrates:
8
+ * 1. ContentAdapter for PDF/document serving
9
+ * 2. ChatModAdapter for scripture commands (/bible, /mlv)
10
+ * 3. Secure, verifiable scripture quoting in chat
11
+ *
12
+ * SCRIPTURE SOVEREIGNTY: Users host their own scripture copies.
13
+ * No central server, no censorship, no manipulation.
14
+ *
15
+ * "For where two or three are gathered in my name,
16
+ * there am I among them." - Matthew 18:20
17
+ *
18
+ * @module adapters/adapter-mlv-bible
19
+ * @version 1.0.0
20
+ */
21
+
22
+ import { ContentAdapter, ContentMetadata, CONTENT_CAPABILITIES } from '../content-adapter.js';
23
+ import { ChatModAdapter, ChatModManifest, CHAT_MOD_CAPABILITIES } from '../chat-mod-adapter.js';
24
+ import { createReadStream, promises as fs } from 'fs';
25
+ import { join, dirname } from 'path';
26
+ import { fileURLToPath } from 'url';
27
+
28
+ const __dirname = dirname(fileURLToPath(import.meta.url));
29
+
30
+ /**
31
+ * Bible book metadata
32
+ */
33
+ const BIBLE_BOOKS = {
34
+ // Old Testament
35
+ 'Genesis': { abbrev: ['Gen', 'Ge'], chapters: 50, testament: 'OT' },
36
+ 'Exodus': { abbrev: ['Ex', 'Exod'], chapters: 40, testament: 'OT' },
37
+ 'Leviticus': { abbrev: ['Lev', 'Le'], chapters: 27, testament: 'OT' },
38
+ 'Numbers': { abbrev: ['Num', 'Nu'], chapters: 36, testament: 'OT' },
39
+ 'Deuteronomy': { abbrev: ['Deut', 'De'], chapters: 34, testament: 'OT' },
40
+ 'Joshua': { abbrev: ['Josh', 'Jos'], chapters: 24, testament: 'OT' },
41
+ 'Judges': { abbrev: ['Judg', 'Jdg'], chapters: 21, testament: 'OT' },
42
+ 'Ruth': { abbrev: ['Ruth', 'Ru'], chapters: 4, testament: 'OT' },
43
+ '1 Samuel': { abbrev: ['1Sam', '1Sa'], chapters: 31, testament: 'OT' },
44
+ '2 Samuel': { abbrev: ['2Sam', '2Sa'], chapters: 24, testament: 'OT' },
45
+ '1 Kings': { abbrev: ['1Ki', '1Kgs'], chapters: 22, testament: 'OT' },
46
+ '2 Kings': { abbrev: ['2Ki', '2Kgs'], chapters: 25, testament: 'OT' },
47
+ '1 Chronicles': { abbrev: ['1Chr', '1Ch'], chapters: 29, testament: 'OT' },
48
+ '2 Chronicles': { abbrev: ['2Chr', '2Ch'], chapters: 36, testament: 'OT' },
49
+ 'Ezra': { abbrev: ['Ezra', 'Ezr'], chapters: 10, testament: 'OT' },
50
+ 'Nehemiah': { abbrev: ['Neh', 'Ne'], chapters: 13, testament: 'OT' },
51
+ 'Esther': { abbrev: ['Est', 'Esth'], chapters: 10, testament: 'OT' },
52
+ 'Job': { abbrev: ['Job'], chapters: 42, testament: 'OT' },
53
+ 'Psalms': { abbrev: ['Ps', 'Psa', 'Psalm'], chapters: 150, testament: 'OT' },
54
+ 'Proverbs': { abbrev: ['Prov', 'Pr'], chapters: 31, testament: 'OT' },
55
+ 'Ecclesiastes': { abbrev: ['Ecc', 'Eccl'], chapters: 12, testament: 'OT' },
56
+ 'Song of Solomon': { abbrev: ['Song', 'SoS', 'SS'], chapters: 8, testament: 'OT' },
57
+ 'Isaiah': { abbrev: ['Isa', 'Is'], chapters: 66, testament: 'OT' },
58
+ 'Jeremiah': { abbrev: ['Jer', 'Je'], chapters: 52, testament: 'OT' },
59
+ 'Lamentations': { abbrev: ['Lam', 'La'], chapters: 5, testament: 'OT' },
60
+ 'Ezekiel': { abbrev: ['Ezek', 'Eze'], chapters: 48, testament: 'OT' },
61
+ 'Daniel': { abbrev: ['Dan', 'Da'], chapters: 12, testament: 'OT' },
62
+ 'Hosea': { abbrev: ['Hos', 'Ho'], chapters: 14, testament: 'OT' },
63
+ 'Joel': { abbrev: ['Joel', 'Joe'], chapters: 3, testament: 'OT' },
64
+ 'Amos': { abbrev: ['Amos', 'Am'], chapters: 9, testament: 'OT' },
65
+ 'Obadiah': { abbrev: ['Obad', 'Ob'], chapters: 1, testament: 'OT' },
66
+ 'Jonah': { abbrev: ['Jonah', 'Jon'], chapters: 4, testament: 'OT' },
67
+ 'Micah': { abbrev: ['Mic', 'Mi'], chapters: 7, testament: 'OT' },
68
+ 'Nahum': { abbrev: ['Nah', 'Na'], chapters: 3, testament: 'OT' },
69
+ 'Habakkuk': { abbrev: ['Hab'], chapters: 3, testament: 'OT' },
70
+ 'Zephaniah': { abbrev: ['Zeph', 'Zep'], chapters: 3, testament: 'OT' },
71
+ 'Haggai': { abbrev: ['Hag'], chapters: 2, testament: 'OT' },
72
+ 'Zechariah': { abbrev: ['Zech', 'Zec'], chapters: 14, testament: 'OT' },
73
+ 'Malachi': { abbrev: ['Mal'], chapters: 4, testament: 'OT' },
74
+
75
+ // New Testament
76
+ 'Matthew': { abbrev: ['Matt', 'Mt'], chapters: 28, testament: 'NT' },
77
+ 'Mark': { abbrev: ['Mark', 'Mk'], chapters: 16, testament: 'NT' },
78
+ 'Luke': { abbrev: ['Luke', 'Lk'], chapters: 24, testament: 'NT' },
79
+ 'John': { abbrev: ['John', 'Jn'], chapters: 21, testament: 'NT' },
80
+ 'Acts': { abbrev: ['Acts', 'Ac'], chapters: 28, testament: 'NT' },
81
+ 'Romans': { abbrev: ['Rom', 'Ro'], chapters: 16, testament: 'NT' },
82
+ '1 Corinthians': { abbrev: ['1Cor', '1Co'], chapters: 16, testament: 'NT' },
83
+ '2 Corinthians': { abbrev: ['2Cor', '2Co'], chapters: 13, testament: 'NT' },
84
+ 'Galatians': { abbrev: ['Gal', 'Ga'], chapters: 6, testament: 'NT' },
85
+ 'Ephesians': { abbrev: ['Eph'], chapters: 6, testament: 'NT' },
86
+ 'Philippians': { abbrev: ['Phil', 'Php'], chapters: 4, testament: 'NT' },
87
+ 'Colossians': { abbrev: ['Col'], chapters: 4, testament: 'NT' },
88
+ '1 Thessalonians': { abbrev: ['1Thess', '1Th'], chapters: 5, testament: 'NT' },
89
+ '2 Thessalonians': { abbrev: ['2Thess', '2Th'], chapters: 3, testament: 'NT' },
90
+ '1 Timothy': { abbrev: ['1Tim', '1Ti'], chapters: 6, testament: 'NT' },
91
+ '2 Timothy': { abbrev: ['2Tim', '2Ti'], chapters: 4, testament: 'NT' },
92
+ 'Titus': { abbrev: ['Titus', 'Tit'], chapters: 3, testament: 'NT' },
93
+ 'Philemon': { abbrev: ['Phlm', 'Phm'], chapters: 1, testament: 'NT' },
94
+ 'Hebrews': { abbrev: ['Heb'], chapters: 13, testament: 'NT' },
95
+ 'James': { abbrev: ['Jas', 'Jam'], chapters: 5, testament: 'NT' },
96
+ '1 Peter': { abbrev: ['1Pet', '1Pe'], chapters: 5, testament: 'NT' },
97
+ '2 Peter': { abbrev: ['2Pet', '2Pe'], chapters: 3, testament: 'NT' },
98
+ '1 John': { abbrev: ['1Jn', '1Jo'], chapters: 5, testament: 'NT' },
99
+ '2 John': { abbrev: ['2Jn', '2Jo'], chapters: 1, testament: 'NT' },
100
+ '3 John': { abbrev: ['3Jn', '3Jo'], chapters: 1, testament: 'NT' },
101
+ 'Jude': { abbrev: ['Jude'], chapters: 1, testament: 'NT' },
102
+ 'Revelation': { abbrev: ['Rev', 'Re'], chapters: 22, testament: 'NT' },
103
+ };
104
+
105
+ /**
106
+ * Parse a scripture reference (e.g., \"John 3:16\" or \"Gen 1:1-5\")
107
+ */
108
+ function parseReference(ref) {
109
+ // Pattern: Book Chapter:Verse(-EndVerse)?
110
+ const pattern = /^(\d?\s*[A-Za-z]+)\s*(\d+):(\d+)(?:-(\d+))?$/;
111
+ const match = ref.trim().match(pattern);
112
+
113
+ if (!match) return null;
114
+
115
+ const [, bookPart, chapter, startVerse, endVerse] = match;
116
+ const bookName = bookPart.trim();
117
+
118
+ // Find the book
119
+ let foundBook = null;
120
+ for (const [name, data] of Object.entries(BIBLE_BOOKS)) {
121
+ if (name.toLowerCase() === bookName.toLowerCase() ||
122
+ data.abbrev.some(a => a.toLowerCase() === bookName.toLowerCase())) {
123
+ foundBook = { name, ...data };
124
+ break;
125
+ }
126
+ }
127
+
128
+ if (!foundBook) return null;
129
+
130
+ return {
131
+ book: foundBook.name,
132
+ chapter: parseInt(chapter, 10),
133
+ startVerse: parseInt(startVerse, 10),
134
+ endVerse: endVerse ? parseInt(endVerse, 10) : parseInt(startVerse, 10),
135
+ testament: foundBook.testament,
136
+ };
137
+ }
138
+
139
+ /**
140
+ * MLV Bible Content Adapter
141
+ * Serves PDF files and handles scripture lookup
142
+ */
143
+ export class MLVContentAdapter extends ContentAdapter {
144
+ constructor(config = {}) {
145
+ super({
146
+ name: 'Modern Literal Version Bible',
147
+ id: 'mlv-bible-content',
148
+ capabilities: [
149
+ CONTENT_CAPABILITIES.SERVE_PDF,
150
+ CONTENT_CAPABILITIES.SERVE_TEXT,
151
+ CONTENT_CAPABILITIES.SEARCH_REFERENCE,
152
+ CONTENT_CAPABILITIES.CHAT_QUOTE,
153
+ CONTENT_CAPABILITIES.CHAT_LOOKUP,
154
+ CONTENT_CAPABILITIES.NET_STREAM,
155
+ ],
156
+ ...config,
157
+ });
158
+
159
+ // Path to MLV content files
160
+ this.contentPath = config.contentPath || join(__dirname, 'content');
161
+
162
+ // In-memory verse index (populated on init)
163
+ this.verseIndex = new Map(); // \"John 3:16\" -> verse text
164
+ }
165
+
166
+ async init() {
167
+ // Register PDF files
168
+ try {
169
+ const files = await fs.readdir(this.contentPath);
170
+
171
+ for (const file of files) {
172
+ if (file.endsWith('.pdf')) {
173
+ const filePath = join(this.contentPath, file);
174
+ const stat = await fs.stat(filePath);
175
+
176
+ const id = file.replace('.pdf', '');
177
+ this.catalog.set(id, new ContentMetadata({
178
+ id,
179
+ title: this._formatTitle(id),
180
+ author: 'Modern Literal Version Translation Committee',
181
+ copyright: 'Public Domain / MLV License',
182
+ license: 'Free to distribute - https://www.modernliteralversion.org',
183
+ contentType: 'application/pdf',
184
+ size: stat.size,
185
+ created: stat.birthtime,
186
+ modified: stat.mtime,
187
+ tags: ['bible', 'scripture', 'mlv', 'christianity'],
188
+ }));
189
+ }
190
+
191
+ // Load verse JSON index if present
192
+ if (file === 'verses.json') {
193
+ const data = await fs.readFile(join(this.contentPath, file), 'utf8');
194
+ const verses = JSON.parse(data);
195
+ for (const [ref, text] of Object.entries(verses)) {
196
+ this.verseIndex.set(ref.toLowerCase(), { ref, text });
197
+ }
198
+ }
199
+ }
200
+ } catch (err) {
201
+ // Content directory might not exist yet - that's okay
202
+ console.log('[MLV] No content directory found. Create:', this.contentPath);
203
+ }
204
+
205
+ this.emit('initialized', { catalogSize: this.catalog.size });
206
+ }
207
+
208
+ _formatTitle(id) {
209
+ // Convert \"mlv-nt\" to \"MLV New Testament\", etc.
210
+ return id
211
+ .replace('mlv-', 'MLV ')
212
+ .replace('nt', 'New Testament')
213
+ .replace('ot', 'Old Testament')
214
+ .replace('complete', 'Complete Bible');
215
+ }
216
+
217
+ async search(query, options = {}) {
218
+ this.stats.searchQueries++;
219
+
220
+ const results = [];
221
+ const q = query.toLowerCase();
222
+
223
+ for (const [ref, data] of this.verseIndex) {
224
+ if (ref.includes(q) || data.text.toLowerCase().includes(q)) {
225
+ results.push({
226
+ reference: data.ref,
227
+ text: data.text,
228
+ score: ref.includes(q) ? 1.0 : 0.5,
229
+ });
230
+
231
+ if (results.length >= (options.limit || 20)) break;
232
+ }
233
+ }
234
+
235
+ return results.sort((a, b) => b.score - a.score);
236
+ }
237
+
238
+ async lookupReference(reference) {
239
+ const parsed = parseReference(reference);
240
+ if (!parsed) return null;
241
+
242
+ // Build the lookup key
243
+ const key = \\ \:\\;
244
+
245
+ // Check verse index
246
+ const verse = this.verseIndex.get(key);
247
+ if (verse) {
248
+ return {
249
+ reference: \\ \:\\,
250
+ text: verse.text,
251
+ book: parsed.book,
252
+ chapter: parsed.chapter,
253
+ verse: parsed.startVerse,
254
+ testament: parsed.testament,
255
+ };
256
+ }
257
+
258
+ // If not in index, return a placeholder indicating lookup needed
259
+ return {
260
+ reference: \\ \:\\,
261
+ text: '[Verse text available in PDF - download MLV from modernliteralversion.org]',
262
+ book: parsed.book,
263
+ chapter: parsed.chapter,
264
+ verse: parsed.startVerse,
265
+ testament: parsed.testament,
266
+ needsFullContent: true,
267
+ };
268
+ }
269
+
270
+ async getContentStream(id, options = {}) {
271
+ const meta = this.catalog.get(id);
272
+ if (!meta) {
273
+ throw new Error('Content not found: ' + id);
274
+ }
275
+
276
+ const filePath = join(this.contentPath, id + '.pdf');
277
+ this.stats.contentServed++;
278
+
279
+ return createReadStream(filePath, {
280
+ start: options.start || 0,
281
+ end: options.end,
282
+ });
283
+ }
284
+ }
285
+
286
+ /**
287
+ * MLV Bible Chat Mod Adapter
288
+ * Handles /bible and /mlv commands in KATHA chat
289
+ */
290
+ export class MLVChatAdapter extends ChatModAdapter {
291
+ constructor(contentAdapter, config = {}) {
292
+ super(
293
+ new ChatModManifest({
294
+ id: 'mlv-bible-chat',
295
+ name: 'MLV Bible Chat',
296
+ version: '1.0.0',
297
+ author: 'Yakmesh Community',
298
+ description: 'Scripture lookup and sharing in chat. Commands: /bible, /mlv',
299
+ capabilities: [
300
+ CHAT_MOD_CAPABILITIES.CMD_SLASH,
301
+ CHAT_MOD_CAPABILITIES.MSG_RESPOND,
302
+ CHAT_MOD_CAPABILITIES.GEN_QUOTE,
303
+ CHAT_MOD_CAPABILITIES.GEN_CARD,
304
+ ],
305
+ commands: ['bible', 'mlv', 'scripture', 'verse'],
306
+ triggers: [], // Only respond to explicit commands
307
+ rateLimit: { messages: 30, window: 60000 }, // 30/min for scripture
308
+ }),
309
+ config
310
+ );
311
+
312
+ this.contentAdapter = contentAdapter;
313
+ }
314
+
315
+ async init() {
316
+ await this.contentAdapter.init();
317
+ this.emit('initialized');
318
+ }
319
+
320
+ async onCommand(command, args, context) {
321
+ const reference = args.join(' ');
322
+
323
+ if (!reference) {
324
+ return {
325
+ type: 'text',
326
+ content: \Usage: /\ <reference>\nExample: /\ John 3:16\,
327
+ };
328
+ }
329
+
330
+ const result = await this.contentAdapter.lookupReference(reference);
331
+
332
+ if (!result) {
333
+ return {
334
+ type: 'text',
335
+ content: \Could not find: \\nCheck the format: Book Chapter:Verse (e.g., John 3:16)\,
336
+ };
337
+ }
338
+
339
+ // Return a rich scripture card
340
+ return {
341
+ type: 'scripture-card',
342
+ reference: result.reference,
343
+ text: result.text,
344
+ translation: 'Modern Literal Version',
345
+ source: 'https://www.modernliteralversion.org',
346
+ testament: result.testament,
347
+ metadata: {
348
+ adapterId: this.manifest.id,
349
+ timestamp: Date.now(),
350
+ },
351
+ };
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Combined MLV Bible Adapter
357
+ * Convenience class that bundles content + chat functionality
358
+ */
359
+ export class MLVBibleAdapter {
360
+ constructor(config = {}) {
361
+ this.contentAdapter = new MLVContentAdapter(config);
362
+ this.chatAdapter = new MLVChatAdapter(this.contentAdapter, config);
363
+ }
364
+
365
+ async init() {
366
+ await this.contentAdapter.init();
367
+ // Chat adapter shares the content adapter's data
368
+ }
369
+
370
+ /**
371
+ * Register with a DARSHAN instance for content streaming
372
+ */
373
+ async registerWithDarshan(darshan) {
374
+ this.contentAdapter.darshan = darshan;
375
+
376
+ // Register all PDF content
377
+ for (const [id] of this.contentAdapter.catalog) {
378
+ await this.contentAdapter.registerWithDarshan(id, {
379
+ allowDownload: true, // MLV is freely distributable
380
+ });
381
+ }
382
+ }
383
+
384
+ /**
385
+ * Register with KATHA chat for commands
386
+ */
387
+ registerWithKatha(katha, registry) {
388
+ registry.register(this.chatAdapter);
389
+ this.chatAdapter.katha = katha;
390
+ }
391
+
392
+ getStats() {
393
+ return {
394
+ content: this.contentAdapter.getStats(),
395
+ chat: this.chatAdapter.getStats(),
396
+ };
397
+ }
398
+ }
399
+
400
+ export default MLVBibleAdapter;