yakmesh 2.8.2 → 2.9.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/CONTRIBUTING.md CHANGED
@@ -47,6 +47,48 @@ Changes to the timing/oracle layer must:
47
47
 
48
48
  ---
49
49
 
50
+ ## 📚 Documentation Guidelines
51
+
52
+ ### Adding New Documentation Pages
53
+
54
+ When adding new pages to the `docs/` directory:
55
+
56
+ 1. **Update the navigation manifest** in `docs/nav-order.json`:
57
+ - Add your new page at the appropriate position in the `pages` array
58
+ - Include: `file`, `icon`, `title`, and `description`
59
+
60
+ 2. **Run the navigation update script**:
61
+ ```bash
62
+ node scripts/update-docs-nav.cjs
63
+ ```
64
+ This automatically updates prev/next links in all affected pages.
65
+
66
+ 3. **Update the sidebar** in all doc pages:
67
+ - Add the new page to the sidebar nav list in every `.html` file
68
+ - Use consistent icon and title
69
+
70
+ ### Navigation Order
71
+
72
+ The canonical page order is defined in `docs/nav-order.json`. This ensures:
73
+ - Consistent prev/next links across all pages
74
+ - Single source of truth for navigation
75
+ - Easy insertion of new pages without manual link updates
76
+
77
+ **Example: Adding a new page "DHARMA" between KATHA and VANI**
78
+
79
+ 1. Edit `docs/nav-order.json`:
80
+ ```json
81
+ { "file": "katha.html", "icon": "💬", "title": "KATHA", "description": "Rich chat" },
82
+ { "file": "dharma.html", "icon": "☸️", "title": "DHARMA", "description": "New protocol" },
83
+ { "file": "vani.html", "icon": "🎙️", "title": "VANI", "description": "Voice calls" },
84
+ ```
85
+
86
+ 2. Run: `node scripts/update-docs-nav.cjs`
87
+
88
+ 3. This updates KATHA (next→DHARMA), creates correct links in DHARMA, and updates VANI (prev→DHARMA).
89
+
90
+ ---
91
+
50
92
  ## 🏷️ Branding & Trademark
51
93
 
52
94
  **YAKMESH** is a trademark of the YAKMESH Project (PeerQuanta).
@@ -0,0 +1,124 @@
1
+ # MLV Bible Adapter for Yakmesh
2
+
3
+ Serve the Modern Literal Version Bible via DARSHAN streaming and enable scripture lookup in KATHA chat.
4
+
5
+ ## Overview
6
+
7
+ This adapter demonstrates Yakmesh's **anti-censorship ethos** by enabling peer-to-peer scripture distribution without central servers or gatekeepers.
8
+
9
+ **\\For where two or three are gathered in my name, there am I among them.\\ - Matthew 18:20**
10
+
11
+ ## Features
12
+
13
+ - **📖 PDF Streaming** - Serve MLV Bible PDFs via DARSHAN (view-not-copy paradigm)
14
+ - **🔍 Scripture Lookup** - Reference parser for all 66 books (e.g., \\John 3:16\\)
15
+ - **💬 Chat Commands** - \\/bible\\, \\/mlv\\, \\/verse\\, \\/scripture\\
16
+ - **🔐 Signed Quotes** - Verifiable scripture cards in chat
17
+ - **🌐 Decentralized** - Each user hosts their own copy
18
+
19
+ ## Installation
20
+
21
+ \\\javascript
22
+ import { MLVBibleAdapter } from '@yakmesh/adapters/adapter-mlv-bible';
23
+
24
+ // Create adapter
25
+ const mlv = new MLVBibleAdapter({
26
+ contentPath: './mlv-content', // Path to your MLV PDFs
27
+ });
28
+
29
+ // Initialize
30
+ await mlv.init();
31
+
32
+ // Register with DARSHAN for streaming
33
+ await mlv.registerWithDarshan(darshan);
34
+
35
+ // Register with KATHA for chat commands
36
+ mlv.registerWithKatha(katha, chatModRegistry);
37
+ \\\
38
+
39
+ ## Content Setup
40
+
41
+ 1. Download MLV Bible from [modernliteralversion.org](https://www.modernliteralversion.org)
42
+ 2. Place PDF files in your content directory
43
+ 3. Optionally create a \\ erses.json\\ for instant lookup:
44
+
45
+ \\\json
46
+ {
47
+ \"John 3:16\": \"For God so loved the world...\",
48
+ \"Genesis 1:1\": \"In the beginning God created...\"
49
+ }
50
+ \\\
51
+
52
+ ## Chat Commands
53
+
54
+ | Command | Example | Description |
55
+ |---------|---------|-------------|
56
+ | \\/bible\\ | \\/bible John 3:16\\ | Look up a verse |
57
+ | \\/mlv\\ | \\/mlv Gen 1:1-5\\ | Look up a passage |
58
+ | \\/verse\\ | \\/verse Ps 23:1\\ | Look up a verse |
59
+ | \\/scripture\\ | \\/scripture Rom 8:28\\ | Look up a verse |
60
+
61
+ ## Creating Your Own Scripture Adapter
62
+
63
+ This adapter serves as a template for other religious texts:
64
+
65
+ \\\javascript
66
+ import { ContentAdapter, CONTENT_CAPABILITIES } from '../content-adapter.js';
67
+ import { ChatModAdapter, ChatModManifest, CHAT_MOD_CAPABILITIES } from '../chat-mod-adapter.js';
68
+
69
+ class MyScriptureAdapter extends ContentAdapter {
70
+ constructor(config) {
71
+ super({
72
+ name: 'My Scripture Name',
73
+ id: 'my-scripture-id',
74
+ capabilities: [
75
+ CONTENT_CAPABILITIES.SERVE_PDF,
76
+ CONTENT_CAPABILITIES.SEARCH_REFERENCE,
77
+ CONTENT_CAPABILITIES.CHAT_QUOTE,
78
+ ],
79
+ ...config,
80
+ });
81
+ }
82
+
83
+ async lookupReference(reference) {
84
+ // Parse your reference format
85
+ // Return { reference, text, ... }
86
+ }
87
+ }
88
+ \\\
89
+
90
+ ## Security Model
91
+
92
+ ### Capability Declaration
93
+ Adapters MUST declare what they can do upfront:
94
+ - \\SERVE_PDF\\ - Can serve PDF content
95
+ - \\CHAT_QUOTE\\ - Can generate chat quotes
96
+ - \\CMD_SLASH\\ - Can handle slash commands
97
+
98
+ ### Rate Limiting
99
+ Default: 30 messages per minute to prevent spam.
100
+
101
+ ### Signed Responses
102
+ All adapter-generated content includes:
103
+ - Adapter ID and version
104
+ - Manifest hash for verification
105
+ - Timestamp
106
+
107
+ ### No Raw Message Access
108
+ Chat adapters only receive sanitized context based on declared capabilities.
109
+
110
+ ## Philosophy
111
+
112
+ Yakmesh rejects centralised gatekeeping of religious texts. This adapter embodies:
113
+
114
+ 1. **Host Sovereignty** - You control your content
115
+ 2. **No Central Server** - Peer-to-peer distribution
116
+ 3. **Anti-Censorship** - No authority can block scripture
117
+ 4. **Verification** - Mathematical proof replaces human trust
118
+
119
+ *\"Let the one who is thirsty come; and let the one who wishes take the free gift of the water of life.\"* - Revelation 22:17
120
+
121
+ ## License
122
+
123
+ This adapter code is MIT licensed.
124
+ The Modern Literal Version Bible is in the public domain per [modernliteralversion.org](https://www.modernliteralversion.org).
@@ -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;