@hyperfixi/patterns-reference 2.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.
package/dist/index.mjs ADDED
@@ -0,0 +1,1240 @@
1
+ import Database from 'better-sqlite3';
2
+ import { fileURLToPath } from 'url';
3
+ import { dirname, join } from 'path';
4
+
5
+ // src/database/connection.ts
6
+ var __filename$1 = fileURLToPath(import.meta.url);
7
+ var __dirname$1 = dirname(__filename$1);
8
+ var DEFAULT_DB_PATH = process.env.LSP_DB_PATH || process.env.HYPERSCRIPT_LSP_DB || join(__dirname$1, "../data/patterns.db");
9
+ var dbInstance = null;
10
+ var currentDbPath = null;
11
+ function getDatabase(options = {}) {
12
+ const dbPath = options.dbPath ?? DEFAULT_DB_PATH;
13
+ if (dbInstance !== null && currentDbPath === dbPath) {
14
+ return dbInstance;
15
+ }
16
+ if (dbInstance !== null) {
17
+ dbInstance.close();
18
+ }
19
+ dbInstance = new Database(dbPath, {
20
+ readonly: options.readonly ?? false
21
+ });
22
+ dbInstance.pragma("foreign_keys = ON");
23
+ currentDbPath = dbPath;
24
+ return dbInstance;
25
+ }
26
+ function closeDatabase() {
27
+ if (dbInstance) {
28
+ dbInstance.close();
29
+ dbInstance = null;
30
+ currentDbPath = null;
31
+ }
32
+ }
33
+ function resetConnection() {
34
+ dbInstance = null;
35
+ currentDbPath = null;
36
+ }
37
+ function isConnected() {
38
+ return dbInstance !== null;
39
+ }
40
+ function getCurrentDbPath() {
41
+ return currentDbPath;
42
+ }
43
+
44
+ // src/api/patterns.ts
45
+ async function getPatternById(id, options) {
46
+ const db = getDatabase({ ...options, readonly: true });
47
+ const row = db.prepare(
48
+ `
49
+ SELECT id, title, raw_code, description, feature, engine, created_at
50
+ FROM code_examples
51
+ WHERE id = ?
52
+ `
53
+ ).get(id);
54
+ return row ? mapRowToPattern(row) : null;
55
+ }
56
+ async function getPatternsByCategory(category, options) {
57
+ const db = getDatabase({ ...options, readonly: true });
58
+ const rows = db.prepare(
59
+ `
60
+ SELECT id, title, raw_code, description, feature, engine, created_at
61
+ FROM code_examples
62
+ WHERE feature = ?
63
+ ORDER BY title
64
+ `
65
+ ).all(category);
66
+ return rows.map(mapRowToPattern);
67
+ }
68
+ async function getPatternsByCommand(command, options) {
69
+ const db = getDatabase({ ...options, readonly: true });
70
+ const rows = db.prepare(
71
+ `
72
+ SELECT id, title, raw_code, description, feature, engine, created_at
73
+ FROM code_examples
74
+ WHERE raw_code LIKE ?
75
+ ORDER BY title
76
+ `
77
+ ).all(`%${command}%`);
78
+ return rows.filter((row) => new RegExp(`\\b${command}\\b`, "i").test(row.raw_code)).map(mapRowToPattern);
79
+ }
80
+ async function searchPatterns(query, searchOptions = {}, connOptions) {
81
+ const db = getDatabase({ ...connOptions, readonly: true });
82
+ const { limit = 50, offset = 0 } = searchOptions;
83
+ const rows = db.prepare(
84
+ `
85
+ SELECT id, title, raw_code, description, feature, engine, created_at
86
+ FROM code_examples
87
+ WHERE title LIKE ? OR raw_code LIKE ? OR description LIKE ?
88
+ ORDER BY title
89
+ LIMIT ? OFFSET ?
90
+ `
91
+ ).all(`%${query}%`, `%${query}%`, `%${query}%`, limit, offset);
92
+ return rows.map(mapRowToPattern);
93
+ }
94
+ async function getAllPatterns(searchOptions = {}, connOptions) {
95
+ const db = getDatabase({ ...connOptions, readonly: true });
96
+ const { limit = 1e3, offset = 0 } = searchOptions;
97
+ const rows = db.prepare(
98
+ `
99
+ SELECT id, title, raw_code, description, feature, engine, created_at
100
+ FROM code_examples
101
+ ORDER BY title
102
+ LIMIT ? OFFSET ?
103
+ `
104
+ ).all(limit, offset);
105
+ return rows.map(mapRowToPattern);
106
+ }
107
+ async function getPatternStats(connOptions) {
108
+ const db = getDatabase({ ...connOptions, readonly: true });
109
+ const patternCount = db.prepare("SELECT COUNT(*) as count FROM code_examples").get();
110
+ const translationCount = db.prepare("SELECT COUNT(*) as count FROM pattern_translations").get();
111
+ const byLangRows = db.prepare(
112
+ `
113
+ SELECT
114
+ language,
115
+ COUNT(*) as count,
116
+ SUM(verified_parses) as verified_count
117
+ FROM pattern_translations
118
+ GROUP BY language
119
+ `
120
+ ).all();
121
+ const byLanguage = {};
122
+ for (const row of byLangRows) {
123
+ byLanguage[row.language] = {
124
+ count: row.count,
125
+ verifiedCount: row.verified_count
126
+ };
127
+ }
128
+ const byCatRows = db.prepare(
129
+ `
130
+ SELECT feature, COUNT(*) as count
131
+ FROM code_examples
132
+ WHERE feature IS NOT NULL
133
+ GROUP BY feature
134
+ `
135
+ ).all();
136
+ const byCategory = {};
137
+ for (const row of byCatRows) {
138
+ byCategory[row.feature] = row.count;
139
+ }
140
+ const avgConfResult = db.prepare("SELECT AVG(confidence) as avg FROM pattern_translations WHERE confidence > 0").get();
141
+ return {
142
+ totalPatterns: patternCount.count,
143
+ totalTranslations: translationCount.count,
144
+ byLanguage,
145
+ byCategory,
146
+ avgConfidence: avgConfResult.avg || 0
147
+ };
148
+ }
149
+ function mapRowToPattern(row) {
150
+ return {
151
+ id: row.id,
152
+ title: row.title,
153
+ description: row.description,
154
+ rawCode: row.raw_code,
155
+ category: row.feature,
156
+ primaryCommand: extractPrimaryCommand(row.raw_code),
157
+ tags: extractTags(row.raw_code),
158
+ difficulty: inferDifficulty(row.raw_code),
159
+ engine: row.engine || null,
160
+ createdAt: new Date(row.created_at)
161
+ };
162
+ }
163
+ function extractPrimaryCommand(code) {
164
+ const match = code.match(/^(on|toggle|put|set|add|remove|show|hide|wait|log|send|fetch|call)\b/i);
165
+ return match ? match[1].toLowerCase() : null;
166
+ }
167
+ function extractTags(code) {
168
+ const tags = [];
169
+ if (code.includes(".")) tags.push("class");
170
+ if (code.includes("#")) tags.push("id");
171
+ if (code.includes("on ")) tags.push("event");
172
+ if (code.includes("fetch")) tags.push("async");
173
+ if (code.includes("wait")) tags.push("timing");
174
+ return tags;
175
+ }
176
+ function inferDifficulty(code) {
177
+ const lines = code.split("\n").filter((l) => l.trim()).length;
178
+ if (lines === 1 && !code.includes("then")) return "beginner";
179
+ if (lines <= 3) return "intermediate";
180
+ return "advanced";
181
+ }
182
+
183
+ // src/api/translations.ts
184
+ async function getTranslation(patternId, language, options) {
185
+ const db = getDatabase({ ...options, readonly: true });
186
+ const row = db.prepare(
187
+ `
188
+ SELECT * FROM pattern_translations
189
+ WHERE code_example_id = ? AND language = ?
190
+ `
191
+ ).get(patternId, language);
192
+ return row ? mapRowToTranslation(row) : null;
193
+ }
194
+ async function getAllTranslations(patternId, options) {
195
+ const db = getDatabase({ ...options, readonly: true });
196
+ const rows = db.prepare(
197
+ `
198
+ SELECT * FROM pattern_translations
199
+ WHERE code_example_id = ?
200
+ ORDER BY language
201
+ `
202
+ ).all(patternId);
203
+ return rows.map(mapRowToTranslation);
204
+ }
205
+ async function getTranslationsByLanguage(language, limit = 100, options) {
206
+ const db = getDatabase({ ...options, readonly: true });
207
+ const rows = db.prepare(
208
+ `
209
+ SELECT * FROM pattern_translations
210
+ WHERE language = ?
211
+ ORDER BY confidence DESC
212
+ LIMIT ?
213
+ `
214
+ ).all(language, limit);
215
+ return rows.map(mapRowToTranslation);
216
+ }
217
+ async function getVerifiedTranslations(language, limit = 100, options) {
218
+ const db = getDatabase({ ...options, readonly: true });
219
+ const rows = db.prepare(
220
+ `
221
+ SELECT * FROM pattern_translations
222
+ WHERE language = ? AND verified_parses = 1
223
+ ORDER BY confidence DESC
224
+ LIMIT ?
225
+ `
226
+ ).all(language, limit);
227
+ return rows.map(mapRowToTranslation);
228
+ }
229
+ async function getHighConfidenceTranslations(minConfidence = 0.8, limit = 100, options) {
230
+ const db = getDatabase({ ...options, readonly: true });
231
+ const rows = db.prepare(
232
+ `
233
+ SELECT * FROM pattern_translations
234
+ WHERE confidence >= ? AND verified_parses = 1
235
+ ORDER BY confidence DESC
236
+ LIMIT ?
237
+ `
238
+ ).all(minConfidence, limit);
239
+ return rows.map(mapRowToTranslation);
240
+ }
241
+ async function verifyTranslation(translation, options) {
242
+ let parseSuccess = false;
243
+ let errorMessage = null;
244
+ let confidence = translation.confidence;
245
+ try {
246
+ const { canParse, parse } = await import('@lokascript/semantic');
247
+ if (canParse(translation.hyperscript, translation.language)) {
248
+ parse(translation.hyperscript, translation.language);
249
+ parseSuccess = true;
250
+ } else {
251
+ errorMessage = "canParse returned false";
252
+ }
253
+ } catch (e) {
254
+ errorMessage = e.message;
255
+ }
256
+ const db = getDatabase(options);
257
+ db.prepare(
258
+ `
259
+ UPDATE pattern_translations
260
+ SET verified_parses = ?, updated_at = datetime('now')
261
+ WHERE id = ?
262
+ `
263
+ ).run(parseSuccess ? 1 : 0, translation.id);
264
+ db.prepare(
265
+ `
266
+ INSERT INTO pattern_tests
267
+ (code_example_id, language, test_date, parse_success, error_message)
268
+ VALUES (?, ?, datetime('now'), ?, ?)
269
+ `
270
+ ).run(translation.codeExampleId, translation.language, parseSuccess ? 1 : 0, errorMessage);
271
+ return {
272
+ translation,
273
+ parseSuccess,
274
+ executeSuccess: false,
275
+ // Not implemented yet
276
+ errorMessage,
277
+ confidence,
278
+ testedAt: /* @__PURE__ */ new Date()
279
+ };
280
+ }
281
+ async function getTranslationStats(options) {
282
+ const db = getDatabase({ ...options, readonly: true });
283
+ const rows = db.prepare(
284
+ `
285
+ SELECT
286
+ language,
287
+ COUNT(*) as total,
288
+ SUM(verified_parses) as verified,
289
+ AVG(confidence) as avg_confidence
290
+ FROM pattern_translations
291
+ GROUP BY language
292
+ `
293
+ ).all();
294
+ const stats = {};
295
+ for (const row of rows) {
296
+ stats[row.language] = {
297
+ total: row.total,
298
+ verified: row.verified,
299
+ avgConfidence: row.avg_confidence || 0
300
+ };
301
+ }
302
+ return stats;
303
+ }
304
+ function mapRowToTranslation(row) {
305
+ return {
306
+ id: row.id,
307
+ codeExampleId: row.code_example_id,
308
+ language: row.language,
309
+ hyperscript: row.hyperscript,
310
+ wordOrder: row.word_order,
311
+ translationMethod: row.translation_method,
312
+ confidence: row.confidence,
313
+ verifiedParses: row.verified_parses === 1,
314
+ verifiedExecutes: row.verified_executes === 1,
315
+ roleAlignmentScore: row.role_alignment_score ?? null,
316
+ createdAt: new Date(row.created_at),
317
+ updatedAt: new Date(row.updated_at)
318
+ };
319
+ }
320
+ function getWordOrder(language) {
321
+ const wordOrders = {
322
+ en: "SVO",
323
+ es: "SVO",
324
+ fr: "SVO",
325
+ pt: "SVO",
326
+ id: "SVO",
327
+ sw: "SVO",
328
+ zh: "SVO",
329
+ ja: "SOV",
330
+ ko: "SOV",
331
+ tr: "SOV",
332
+ qu: "SOV",
333
+ ar: "VSO",
334
+ de: "V2"
335
+ };
336
+ return wordOrders[language] || "SVO";
337
+ }
338
+
339
+ // src/api/llm.ts
340
+ async function getLLMExamples(prompt, language = "en", limit = 5, options) {
341
+ const db = getDatabase({ ...options, readonly: true });
342
+ const keywords = extractKeywords(prompt);
343
+ if (keywords.length === 0) {
344
+ const rows2 = db.prepare(
345
+ `
346
+ SELECT * FROM llm_examples
347
+ WHERE language = ?
348
+ ORDER BY quality_score DESC, usage_count DESC
349
+ LIMIT ?
350
+ `
351
+ ).all(language, limit);
352
+ trackUsage(
353
+ db,
354
+ rows2.map((r) => r.id)
355
+ );
356
+ return rows2.map(mapRowToLLMExample);
357
+ }
358
+ const likeClauses = keywords.map(() => "(prompt LIKE ? OR completion LIKE ?)").join(" OR ");
359
+ const params = keywords.flatMap((k) => [`%${k}%`, `%${k}%`]);
360
+ const rows = db.prepare(
361
+ `
362
+ SELECT * FROM llm_examples
363
+ WHERE language = ? AND (${likeClauses})
364
+ ORDER BY quality_score DESC
365
+ LIMIT ?
366
+ `
367
+ ).all(language, ...params, limit);
368
+ trackUsage(
369
+ db,
370
+ rows.map((r) => r.id)
371
+ );
372
+ return rows.map(mapRowToLLMExample);
373
+ }
374
+ async function getExamplesByCommand(command, language = "en", limit = 5, options) {
375
+ const db = getDatabase({ ...options, readonly: true });
376
+ const rows = db.prepare(
377
+ `
378
+ SELECT * FROM llm_examples
379
+ WHERE language = ? AND completion LIKE ?
380
+ ORDER BY quality_score DESC
381
+ LIMIT ?
382
+ `
383
+ ).all(language, `%${command}%`, limit);
384
+ return rows.map(mapRowToLLMExample);
385
+ }
386
+ async function getHighQualityExamples(language = "en", minQuality = 0.8, limit = 10, options) {
387
+ const db = getDatabase({ ...options, readonly: true });
388
+ const rows = db.prepare(
389
+ `
390
+ SELECT * FROM llm_examples
391
+ WHERE language = ? AND quality_score >= ?
392
+ ORDER BY quality_score DESC, usage_count DESC
393
+ LIMIT ?
394
+ `
395
+ ).all(language, minQuality, limit);
396
+ return rows.map(mapRowToLLMExample);
397
+ }
398
+ async function getMostUsedExamples(language = "en", limit = 10, options) {
399
+ const db = getDatabase({ ...options, readonly: true });
400
+ const rows = db.prepare(
401
+ `
402
+ SELECT * FROM llm_examples
403
+ WHERE language = ?
404
+ ORDER BY usage_count DESC, quality_score DESC
405
+ LIMIT ?
406
+ `
407
+ ).all(language, limit);
408
+ return rows.map(mapRowToLLMExample);
409
+ }
410
+ async function buildFewShotContext(prompt, language = "en", numExamples = 3, options) {
411
+ const examples = await getLLMExamples(prompt, language, numExamples, options);
412
+ if (examples.length === 0) {
413
+ return "";
414
+ }
415
+ let context = "Here are some example hyperscript patterns:\n\n";
416
+ for (const ex of examples) {
417
+ context += `Task: ${ex.prompt}
418
+ `;
419
+ context += `Code: ${ex.completion}
420
+
421
+ `;
422
+ }
423
+ context += `Now generate hyperscript for: ${prompt}
424
+ `;
425
+ return context;
426
+ }
427
+ async function addLLMExample(example, options) {
428
+ const db = getDatabase(options);
429
+ const result = db.prepare(
430
+ `
431
+ INSERT INTO llm_examples
432
+ (code_example_id, language, prompt, completion, quality_score, usage_count, created_at)
433
+ VALUES (?, ?, ?, ?, ?, 0, datetime('now'))
434
+ `
435
+ ).run(
436
+ example.patternId,
437
+ example.language,
438
+ example.prompt,
439
+ example.completion,
440
+ example.qualityScore
441
+ );
442
+ return result.lastInsertRowid;
443
+ }
444
+ async function updateQualityScore(id, qualityScore, options) {
445
+ const db = getDatabase(options);
446
+ db.prepare(
447
+ `
448
+ UPDATE llm_examples SET quality_score = ? WHERE id = ?
449
+ `
450
+ ).run(qualityScore, id);
451
+ }
452
+ async function getLLMStats(options) {
453
+ const db = getDatabase({ ...options, readonly: true });
454
+ const totalResult = db.prepare("SELECT COUNT(*) as count FROM llm_examples").get();
455
+ const byLangResult = db.prepare(
456
+ `
457
+ SELECT language, COUNT(*) as count
458
+ FROM llm_examples
459
+ GROUP BY language
460
+ `
461
+ ).all();
462
+ const avgResult = db.prepare("SELECT AVG(quality_score) as avg FROM llm_examples").get();
463
+ const usageResult = db.prepare("SELECT SUM(usage_count) as total FROM llm_examples").get();
464
+ const byLanguage = {};
465
+ for (const { language, count } of byLangResult) {
466
+ byLanguage[language] = count;
467
+ }
468
+ return {
469
+ total: totalResult.count,
470
+ byLanguage,
471
+ avgQuality: avgResult.avg || 0,
472
+ totalUsage: usageResult.total || 0
473
+ };
474
+ }
475
+ function extractKeywords(prompt) {
476
+ const stopWords = /* @__PURE__ */ new Set([
477
+ "a",
478
+ "an",
479
+ "the",
480
+ "to",
481
+ "on",
482
+ "in",
483
+ "for",
484
+ "is",
485
+ "it",
486
+ "when",
487
+ "i",
488
+ "want",
489
+ "need",
490
+ "create",
491
+ "make",
492
+ "please",
493
+ "can",
494
+ "you",
495
+ "would",
496
+ "should",
497
+ "like",
498
+ "that",
499
+ "this",
500
+ "with",
501
+ "from"
502
+ ]);
503
+ return prompt.toLowerCase().split(/\W+/).filter((word) => word.length > 2 && !stopWords.has(word));
504
+ }
505
+ function trackUsage(db, ids) {
506
+ if (ids.length === 0) return;
507
+ try {
508
+ const stmt = db.prepare(`
509
+ UPDATE llm_examples SET usage_count = usage_count + 1 WHERE id = ?
510
+ `);
511
+ for (const id of ids) {
512
+ stmt.run(id);
513
+ }
514
+ } catch {
515
+ }
516
+ }
517
+ function mapRowToLLMExample(row) {
518
+ return {
519
+ id: row.id,
520
+ patternId: row.code_example_id,
521
+ language: row.language,
522
+ prompt: row.prompt,
523
+ completion: row.completion,
524
+ qualityScore: row.quality_score,
525
+ usageCount: row.usage_count,
526
+ createdAt: new Date(row.created_at)
527
+ };
528
+ }
529
+
530
+ // src/api/language-docs.ts
531
+ function mapCommand(row) {
532
+ return {
533
+ id: row.id,
534
+ name: row.name,
535
+ description: row.description,
536
+ syntax: row.syntax,
537
+ purpose: row.purpose,
538
+ implicitTarget: row.implicit_target,
539
+ implicitResultTarget: row.implicit_result_target,
540
+ isBlocking: row.is_blocking === 1,
541
+ hasBody: row.has_body === 1,
542
+ createdAt: new Date(row.created_at),
543
+ updatedAt: new Date(row.updated_at)
544
+ };
545
+ }
546
+ function mapExpression(row, operators = []) {
547
+ return {
548
+ id: row.id,
549
+ name: row.name,
550
+ description: row.description,
551
+ category: row.category,
552
+ evaluatesToType: row.evaluates_to_type,
553
+ precedence: row.precedence,
554
+ associativity: row.associativity,
555
+ operators,
556
+ createdAt: new Date(row.created_at),
557
+ updatedAt: new Date(row.updated_at)
558
+ };
559
+ }
560
+ function mapKeyword(row) {
561
+ return {
562
+ id: row.id,
563
+ name: row.name,
564
+ description: row.description,
565
+ contextOfUse: row.context_of_use,
566
+ isOptional: row.is_optional === 1,
567
+ createdAt: new Date(row.created_at),
568
+ updatedAt: new Date(row.updated_at)
569
+ };
570
+ }
571
+ function mapFeature(row) {
572
+ return {
573
+ id: row.id,
574
+ name: row.name,
575
+ description: row.description,
576
+ syntax: row.syntax,
577
+ trigger: row.trigger,
578
+ structureDescription: row.structure_description,
579
+ scopeImpact: row.scope_impact,
580
+ createdAt: new Date(row.created_at),
581
+ updatedAt: new Date(row.updated_at)
582
+ };
583
+ }
584
+ function mapSpecialSymbol(row) {
585
+ return {
586
+ id: row.id,
587
+ name: row.name,
588
+ symbol: row.symbol,
589
+ symbolType: row.symbol_type,
590
+ description: row.description,
591
+ typicalValue: row.typical_value,
592
+ scopeImplications: row.scope_implications,
593
+ createdAt: new Date(row.created_at),
594
+ updatedAt: new Date(row.updated_at)
595
+ };
596
+ }
597
+ async function getCommandByName(name, options) {
598
+ const db = getDatabase({ ...options, readonly: true });
599
+ const row = db.prepare("SELECT * FROM commands WHERE LOWER(name) = LOWER(?)").get(name);
600
+ return row ? mapCommand(row) : null;
601
+ }
602
+ async function getAllCommands(options) {
603
+ const db = getDatabase({ ...options, readonly: true });
604
+ const rows = db.prepare("SELECT * FROM commands ORDER BY name").all();
605
+ return rows.map(mapCommand);
606
+ }
607
+ async function searchCommands(query, options) {
608
+ const db = getDatabase({ ...options, readonly: true });
609
+ const pattern = `%${query}%`;
610
+ const rows = db.prepare(
611
+ `SELECT * FROM commands
612
+ WHERE LOWER(name) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?)
613
+ ORDER BY name`
614
+ ).all(pattern, pattern);
615
+ return rows.map(mapCommand);
616
+ }
617
+ async function getExpressionByName(name, options) {
618
+ const db = getDatabase({ ...options, readonly: true });
619
+ const row = db.prepare("SELECT * FROM expressions WHERE LOWER(name) = LOWER(?)").get(name);
620
+ if (!row) return null;
621
+ const operators = db.prepare("SELECT operator FROM expression_operators WHERE expression_id = ?").all(row.id);
622
+ return mapExpression(
623
+ row,
624
+ operators.map((o) => o.operator)
625
+ );
626
+ }
627
+ async function getAllExpressions(options) {
628
+ const db = getDatabase({ ...options, readonly: true });
629
+ const rows = db.prepare("SELECT * FROM expressions ORDER BY name").all();
630
+ const allOperators = db.prepare("SELECT expression_id, operator FROM expression_operators").all();
631
+ const operatorMap = /* @__PURE__ */ new Map();
632
+ for (const op of allOperators) {
633
+ const ops = operatorMap.get(op.expression_id) || [];
634
+ ops.push(op.operator);
635
+ operatorMap.set(op.expression_id, ops);
636
+ }
637
+ return rows.map((row) => mapExpression(row, operatorMap.get(row.id) || []));
638
+ }
639
+ async function getExpressionsByCategory(category, options) {
640
+ const db = getDatabase({ ...options, readonly: true });
641
+ const rows = db.prepare("SELECT * FROM expressions WHERE LOWER(category) = LOWER(?) ORDER BY name").all(category);
642
+ const ids = rows.map((r) => r.id);
643
+ if (ids.length === 0) return [];
644
+ const placeholders = ids.map(() => "?").join(",");
645
+ const allOperators = db.prepare(
646
+ `SELECT expression_id, operator FROM expression_operators WHERE expression_id IN (${placeholders})`
647
+ ).all(...ids);
648
+ const operatorMap = /* @__PURE__ */ new Map();
649
+ for (const op of allOperators) {
650
+ const ops = operatorMap.get(op.expression_id) || [];
651
+ ops.push(op.operator);
652
+ operatorMap.set(op.expression_id, ops);
653
+ }
654
+ return rows.map((row) => mapExpression(row, operatorMap.get(row.id) || []));
655
+ }
656
+ async function getKeywordByName(name, options) {
657
+ const db = getDatabase({ ...options, readonly: true });
658
+ const row = db.prepare("SELECT * FROM keywords WHERE LOWER(name) = LOWER(?)").get(name);
659
+ return row ? mapKeyword(row) : null;
660
+ }
661
+ async function getAllKeywords(options) {
662
+ const db = getDatabase({ ...options, readonly: true });
663
+ const rows = db.prepare("SELECT * FROM keywords ORDER BY name").all();
664
+ return rows.map(mapKeyword);
665
+ }
666
+ async function getFeatureByName(name, options) {
667
+ const db = getDatabase({ ...options, readonly: true });
668
+ const row = db.prepare("SELECT * FROM features WHERE LOWER(name) = LOWER(?)").get(name);
669
+ return row ? mapFeature(row) : null;
670
+ }
671
+ async function getAllFeatures(options) {
672
+ const db = getDatabase({ ...options, readonly: true });
673
+ const rows = db.prepare("SELECT * FROM features ORDER BY name").all();
674
+ return rows.map(mapFeature);
675
+ }
676
+ async function getSpecialSymbolByName(name, options) {
677
+ const db = getDatabase({ ...options, readonly: true });
678
+ const row = db.prepare(
679
+ "SELECT * FROM special_symbols WHERE LOWER(name) = LOWER(?) OR LOWER(symbol) = LOWER(?)"
680
+ ).get(name, name);
681
+ return row ? mapSpecialSymbol(row) : null;
682
+ }
683
+ async function getAllSpecialSymbols(options) {
684
+ const db = getDatabase({ ...options, readonly: true });
685
+ const rows = db.prepare("SELECT * FROM special_symbols ORDER BY name").all();
686
+ return rows.map(mapSpecialSymbol);
687
+ }
688
+ async function searchLanguageElements(query, types, options) {
689
+ const results = [];
690
+ const searchTypes = types || ["command", "expression", "keyword", "feature", "special_symbol"];
691
+ if (searchTypes.includes("command")) {
692
+ const commands = await searchCommands(query, options);
693
+ results.push(...commands.map((c) => ({ type: "command", element: c })));
694
+ }
695
+ if (searchTypes.includes("expression")) {
696
+ const db = getDatabase({ ...options, readonly: true });
697
+ const pattern = `%${query}%`;
698
+ const rows = db.prepare(
699
+ `SELECT * FROM expressions
700
+ WHERE LOWER(name) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?) OR LOWER(category) LIKE LOWER(?)
701
+ ORDER BY name`
702
+ ).all(pattern, pattern, pattern);
703
+ const ids = rows.map((r) => r.id);
704
+ const operatorMap = /* @__PURE__ */ new Map();
705
+ if (ids.length > 0) {
706
+ const placeholders = ids.map(() => "?").join(",");
707
+ const ops = db.prepare(
708
+ `SELECT expression_id, operator FROM expression_operators WHERE expression_id IN (${placeholders})`
709
+ ).all(...ids);
710
+ for (const op of ops) {
711
+ const arr = operatorMap.get(op.expression_id) || [];
712
+ arr.push(op.operator);
713
+ operatorMap.set(op.expression_id, arr);
714
+ }
715
+ }
716
+ results.push(
717
+ ...rows.map((row) => ({
718
+ type: "expression",
719
+ element: mapExpression(row, operatorMap.get(row.id) || [])
720
+ }))
721
+ );
722
+ }
723
+ if (searchTypes.includes("keyword")) {
724
+ const db = getDatabase({ ...options, readonly: true });
725
+ const pattern = `%${query}%`;
726
+ const rows = db.prepare(
727
+ `SELECT * FROM keywords
728
+ WHERE LOWER(name) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?)
729
+ ORDER BY name`
730
+ ).all(pattern, pattern);
731
+ results.push(...rows.map((row) => ({ type: "keyword", element: mapKeyword(row) })));
732
+ }
733
+ if (searchTypes.includes("feature")) {
734
+ const db = getDatabase({ ...options, readonly: true });
735
+ const pattern = `%${query}%`;
736
+ const rows = db.prepare(
737
+ `SELECT * FROM features
738
+ WHERE LOWER(name) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?)
739
+ ORDER BY name`
740
+ ).all(pattern, pattern);
741
+ results.push(...rows.map((row) => ({ type: "feature", element: mapFeature(row) })));
742
+ }
743
+ if (searchTypes.includes("special_symbol")) {
744
+ const db = getDatabase({ ...options, readonly: true });
745
+ const pattern = `%${query}%`;
746
+ const rows = db.prepare(
747
+ `SELECT * FROM special_symbols
748
+ WHERE LOWER(name) LIKE LOWER(?) OR LOWER(symbol) LIKE LOWER(?) OR LOWER(description) LIKE LOWER(?)
749
+ ORDER BY name`
750
+ ).all(pattern, pattern, pattern);
751
+ results.push(
752
+ ...rows.map((row) => ({ type: "special_symbol", element: mapSpecialSymbol(row) }))
753
+ );
754
+ }
755
+ return results;
756
+ }
757
+ async function getLanguageDocsStats(options) {
758
+ const db = getDatabase({ ...options, readonly: true });
759
+ const getCount = (table) => {
760
+ try {
761
+ const result = db.prepare(`SELECT COUNT(*) as count FROM ${table}`).get();
762
+ return result.count;
763
+ } catch {
764
+ return 0;
765
+ }
766
+ };
767
+ return {
768
+ commands: getCount("commands"),
769
+ expressions: getCount("expressions"),
770
+ keywords: getCount("keywords"),
771
+ features: getCount("features"),
772
+ specialSymbols: getCount("special_symbols"),
773
+ expressionOperators: getCount("expression_operators")
774
+ };
775
+ }
776
+
777
+ // src/sync/index.ts
778
+ async function syncTranslations(_options = {}) {
779
+ throw new Error(
780
+ "syncTranslations should be run via: bun run packages/semantic/scripts/sync-lsp-translations.ts"
781
+ );
782
+ }
783
+ async function validateAllTranslations(_options = {}) {
784
+ throw new Error(
785
+ "validateAllTranslations should be run via: bun run packages/semantic/scripts/validate-translations.ts"
786
+ );
787
+ }
788
+ async function discoverPatterns(_verbose = false) {
789
+ throw new Error(
790
+ "discoverPatterns should be run via: bun run packages/semantic/scripts/pattern-discovery.ts"
791
+ );
792
+ }
793
+ async function seedLLMExamples(_dryRun = false) {
794
+ throw new Error(
795
+ "seedLLMExamples should be run via: bun run packages/semantic/scripts/seed-llm-examples.ts"
796
+ );
797
+ }
798
+
799
+ // src/adapters/llm-adapter.ts
800
+ var syncDatabaseAvailable = true;
801
+ function isDatabaseAvailable() {
802
+ try {
803
+ getDatabase({ readonly: true });
804
+ return true;
805
+ } catch {
806
+ syncDatabaseAvailable = false;
807
+ return false;
808
+ }
809
+ }
810
+ function findRelevantExamples(prompt, language = "en", limit = 5) {
811
+ if (!syncDatabaseAvailable) return [];
812
+ try {
813
+ const db = getDatabase({ readonly: true });
814
+ const keywords = extractKeywords2(prompt);
815
+ if (keywords.length === 0) {
816
+ const rows2 = db.prepare(
817
+ `
818
+ SELECT id, prompt, completion, language, quality_score as qualityScore
819
+ FROM llm_examples
820
+ WHERE language = ?
821
+ ORDER BY quality_score DESC, usage_count DESC
822
+ LIMIT ?
823
+ `
824
+ ).all(language, limit);
825
+ trackUsageSync(
826
+ db,
827
+ rows2.map((r) => r.id)
828
+ );
829
+ return rows2;
830
+ }
831
+ const likeClauses = keywords.map(() => "(prompt LIKE ? OR completion LIKE ?)").join(" OR ");
832
+ const params = keywords.flatMap((k) => [`%${k}%`, `%${k}%`]);
833
+ const rows = db.prepare(
834
+ `
835
+ SELECT id, prompt, completion, language, quality_score as qualityScore
836
+ FROM llm_examples
837
+ WHERE language = ? AND (${likeClauses})
838
+ ORDER BY quality_score DESC
839
+ LIMIT ?
840
+ `
841
+ ).all(language, ...params, limit);
842
+ trackUsageSync(
843
+ db,
844
+ rows.map((r) => r.id)
845
+ );
846
+ return rows;
847
+ } catch (error) {
848
+ console.warn(
849
+ "[LLM Adapter] Query failed:",
850
+ error instanceof Error ? error.message : String(error)
851
+ );
852
+ syncDatabaseAvailable = false;
853
+ return [];
854
+ }
855
+ }
856
+ function findExamplesByCommand(command, language = "en", limit = 5) {
857
+ if (!syncDatabaseAvailable) return [];
858
+ try {
859
+ const db = getDatabase({ readonly: true });
860
+ const rows = db.prepare(
861
+ `
862
+ SELECT id, prompt, completion, language, quality_score as qualityScore
863
+ FROM llm_examples
864
+ WHERE language = ? AND completion LIKE ?
865
+ ORDER BY quality_score DESC
866
+ LIMIT ?
867
+ `
868
+ ).all(language, `%${command}%`, limit);
869
+ return rows;
870
+ } catch (error) {
871
+ console.warn(
872
+ "[LLM Adapter] Query failed:",
873
+ error instanceof Error ? error.message : String(error)
874
+ );
875
+ return [];
876
+ }
877
+ }
878
+ function buildFewShotContextSync(prompt, language = "en", numExamples = 3) {
879
+ const examples = findRelevantExamples(prompt, language, numExamples);
880
+ if (examples.length === 0) {
881
+ return "";
882
+ }
883
+ let context = "Here are some example hyperscript patterns:\n\n";
884
+ for (const ex of examples) {
885
+ context += `Task: ${ex.prompt}
886
+ `;
887
+ context += `Code: ${ex.completion}
888
+
889
+ `;
890
+ }
891
+ context += `Now generate hyperscript for: ${prompt}
892
+ `;
893
+ return context;
894
+ }
895
+ function trackExampleUsage(ids) {
896
+ if (!syncDatabaseAvailable || ids.length === 0) return;
897
+ try {
898
+ const db = getDatabase();
899
+ trackUsageSync(db, ids);
900
+ } catch {
901
+ }
902
+ }
903
+ function getLLMExampleStats() {
904
+ if (!syncDatabaseAvailable) return null;
905
+ try {
906
+ const db = getDatabase({ readonly: true });
907
+ const totalResult = db.prepare("SELECT COUNT(*) as count FROM llm_examples").get();
908
+ const byLangResult = db.prepare(
909
+ `
910
+ SELECT language, COUNT(*) as count
911
+ FROM llm_examples
912
+ GROUP BY language
913
+ `
914
+ ).all();
915
+ const avgResult = db.prepare("SELECT AVG(quality_score) as avg FROM llm_examples").get();
916
+ const byLanguage = {};
917
+ for (const { language, count } of byLangResult) {
918
+ byLanguage[language] = count;
919
+ }
920
+ return {
921
+ total: totalResult.count,
922
+ byLanguage,
923
+ avgQuality: avgResult.avg || 0
924
+ };
925
+ } catch {
926
+ return null;
927
+ }
928
+ }
929
+ function extractKeywords2(prompt) {
930
+ const stopWords = /* @__PURE__ */ new Set([
931
+ "a",
932
+ "an",
933
+ "the",
934
+ "to",
935
+ "on",
936
+ "in",
937
+ "for",
938
+ "is",
939
+ "it",
940
+ "when",
941
+ "i",
942
+ "want",
943
+ "need",
944
+ "create",
945
+ "make",
946
+ "please",
947
+ "can",
948
+ "you",
949
+ "would",
950
+ "should",
951
+ "like",
952
+ "that",
953
+ "this",
954
+ "with",
955
+ "from"
956
+ ]);
957
+ return prompt.toLowerCase().split(/\W+/).filter((word) => word.length > 2 && !stopWords.has(word));
958
+ }
959
+ function trackUsageSync(db, ids) {
960
+ if (ids.length === 0) return;
961
+ try {
962
+ const stmt = db.prepare(`
963
+ UPDATE llm_examples SET usage_count = usage_count + 1 WHERE id = ?
964
+ `);
965
+ for (const id of ids) {
966
+ stmt.run(id);
967
+ }
968
+ } catch {
969
+ }
970
+ }
971
+ function createLLMAdapter(options) {
972
+ getDatabase(options);
973
+ return {
974
+ // Sync methods (backward compatibility with llm-examples-query.ts)
975
+ findRelevantExamples,
976
+ findExamplesByCommand,
977
+ buildFewShotContextSync,
978
+ trackExampleUsage,
979
+ getLLMExampleStats,
980
+ isDatabaseAvailable,
981
+ // Async methods (preferred for new code)
982
+ getLLMExamples: (prompt, language, limit) => getLLMExamples(prompt, language, limit, options),
983
+ getExamplesByCommand: (command, language, limit) => getExamplesByCommand(command, language, limit, options),
984
+ getHighQualityExamples: (language, minQuality, limit) => getHighQualityExamples(language, minQuality, limit, options),
985
+ getMostUsedExamples: (language, limit) => getMostUsedExamples(language, limit, options),
986
+ buildFewShotContext: (prompt, language, numExamples) => buildFewShotContext(prompt, language, numExamples, options),
987
+ getLLMStats: () => getLLMStats(options),
988
+ // Cleanup
989
+ close: closeDatabase
990
+ };
991
+ }
992
+
993
+ // src/registry/patterns-provider.ts
994
+ var DatabasePatternsProvider = class {
995
+ id = "patterns-reference-db";
996
+ name = "Patterns Reference Database";
997
+ options;
998
+ languageCache = /* @__PURE__ */ new Map();
999
+ supportedLanguagesCache = null;
1000
+ constructor(options) {
1001
+ this.options = options || {};
1002
+ }
1003
+ /**
1004
+ * Get patterns for a specific language.
1005
+ */
1006
+ async getPatternsForLanguage(language) {
1007
+ const cached = this.languageCache.get(language);
1008
+ if (cached) {
1009
+ return cached;
1010
+ }
1011
+ try {
1012
+ const translations = await getVerifiedTranslations(language, 1e3, this.options);
1013
+ const patterns = translations.map((t) => ({
1014
+ id: t.codeExampleId,
1015
+ code: t.hyperscript,
1016
+ command: this.extractCommand(t.hyperscript),
1017
+ language: t.language,
1018
+ confidence: t.confidence,
1019
+ verified: t.verifiedParses
1020
+ }));
1021
+ this.languageCache.set(language, patterns);
1022
+ return patterns;
1023
+ } catch (error) {
1024
+ console.warn(
1025
+ `[PatternsProvider] Failed to get patterns for ${language}:`,
1026
+ error instanceof Error ? error.message : String(error)
1027
+ );
1028
+ return [];
1029
+ }
1030
+ }
1031
+ /**
1032
+ * Get patterns for a specific command.
1033
+ */
1034
+ async getPatternsForCommand(command, language) {
1035
+ try {
1036
+ const patterns = await getPatternsByCommand(command, this.options);
1037
+ const entries = patterns.map((p) => ({
1038
+ id: p.id,
1039
+ code: p.rawCode,
1040
+ command: p.primaryCommand,
1041
+ language: language || "en",
1042
+ confidence: 1,
1043
+ verified: true,
1044
+ title: p.title,
1045
+ category: p.category || void 0
1046
+ }));
1047
+ return entries;
1048
+ } catch (error) {
1049
+ console.warn(
1050
+ `[PatternsProvider] Failed to get patterns for command ${command}:`,
1051
+ error instanceof Error ? error.message : String(error)
1052
+ );
1053
+ return [];
1054
+ }
1055
+ }
1056
+ /**
1057
+ * Check if source has patterns for a language.
1058
+ */
1059
+ async hasPatterns(language) {
1060
+ const patterns = await this.getPatternsForLanguage(language);
1061
+ return patterns.length > 0;
1062
+ }
1063
+ /**
1064
+ * Get all supported languages.
1065
+ */
1066
+ async getSupportedLanguages() {
1067
+ if (this.supportedLanguagesCache) {
1068
+ return this.supportedLanguagesCache;
1069
+ }
1070
+ try {
1071
+ const db = getDatabase({ ...this.options, readonly: true });
1072
+ const result = db.prepare(
1073
+ `
1074
+ SELECT DISTINCT language FROM pattern_translations
1075
+ WHERE verified_parses = 1
1076
+ `
1077
+ ).all();
1078
+ this.supportedLanguagesCache = result.map((r) => r.language);
1079
+ return this.supportedLanguagesCache;
1080
+ } catch (error) {
1081
+ console.warn(
1082
+ "[PatternsProvider] Failed to get supported languages:",
1083
+ error instanceof Error ? error.message : String(error)
1084
+ );
1085
+ return [];
1086
+ }
1087
+ }
1088
+ /**
1089
+ * Clear the pattern cache.
1090
+ */
1091
+ clearCache() {
1092
+ this.languageCache.clear();
1093
+ this.supportedLanguagesCache = null;
1094
+ }
1095
+ /**
1096
+ * Extract primary command from hyperscript code.
1097
+ */
1098
+ extractCommand(code) {
1099
+ const match = code.match(/^(?:on\s+\w+\s+)?(\w+)/i);
1100
+ if (match) {
1101
+ const keyword = match[1].toLowerCase();
1102
+ const commands = [
1103
+ "toggle",
1104
+ "add",
1105
+ "remove",
1106
+ "put",
1107
+ "set",
1108
+ "show",
1109
+ "hide",
1110
+ "wait",
1111
+ "log",
1112
+ "send",
1113
+ "fetch",
1114
+ "call",
1115
+ "trigger",
1116
+ "transition",
1117
+ "increment",
1118
+ "decrement"
1119
+ ];
1120
+ if (commands.includes(keyword)) {
1121
+ return keyword;
1122
+ }
1123
+ }
1124
+ return null;
1125
+ }
1126
+ };
1127
+ var defaultProvider = null;
1128
+ function getDefaultProvider(options) {
1129
+ if (!defaultProvider) {
1130
+ defaultProvider = new DatabasePatternsProvider(options);
1131
+ }
1132
+ return defaultProvider;
1133
+ }
1134
+ function createPatternsProvider(options) {
1135
+ return new DatabasePatternsProvider(options);
1136
+ }
1137
+ function resetDefaultProvider() {
1138
+ if (defaultProvider) {
1139
+ defaultProvider.clearCache();
1140
+ defaultProvider = null;
1141
+ }
1142
+ }
1143
+
1144
+ // src/semantic-bridge.ts
1145
+ var bridgeInitialized = false;
1146
+ var bridgeProvider = null;
1147
+ async function initializeSemanticIntegration(options) {
1148
+ const provider = options?.provider || createPatternsProvider(options);
1149
+ bridgeProvider = provider;
1150
+ try {
1151
+ const semantic = await import('@lokascript/semantic');
1152
+ if (typeof semantic.registerPatternsSource === "function") {
1153
+ semantic.registerPatternsSource(provider);
1154
+ bridgeInitialized = true;
1155
+ return {
1156
+ success: true,
1157
+ provider,
1158
+ registeredWith: "semantic"
1159
+ };
1160
+ } else {
1161
+ console.warn(
1162
+ "[SemanticBridge] @lokascript/semantic does not export registerPatternsSource. Running in standalone mode."
1163
+ );
1164
+ return {
1165
+ success: true,
1166
+ provider,
1167
+ registeredWith: "standalone"
1168
+ };
1169
+ }
1170
+ } catch (error) {
1171
+ console.warn(
1172
+ "[SemanticBridge] @lokascript/semantic not available:",
1173
+ error instanceof Error ? error.message : String(error)
1174
+ );
1175
+ return {
1176
+ success: true,
1177
+ provider,
1178
+ registeredWith: "standalone",
1179
+ error: "@lokascript/semantic not available"
1180
+ };
1181
+ }
1182
+ }
1183
+ function isSemanticIntegrationInitialized() {
1184
+ return bridgeInitialized;
1185
+ }
1186
+ function getBridgeProvider() {
1187
+ return bridgeProvider;
1188
+ }
1189
+ async function uninitializeSemanticIntegration() {
1190
+ if (!bridgeProvider) {
1191
+ return;
1192
+ }
1193
+ try {
1194
+ const semantic = await import('@lokascript/semantic');
1195
+ if (typeof semantic.unregisterPatternsSource === "function") {
1196
+ semantic.unregisterPatternsSource(bridgeProvider.id);
1197
+ }
1198
+ } catch {
1199
+ }
1200
+ bridgeProvider.clearCache();
1201
+ bridgeProvider = null;
1202
+ bridgeInitialized = false;
1203
+ }
1204
+ async function queryPatterns(language) {
1205
+ const provider = bridgeProvider || createPatternsProvider();
1206
+ return provider.getPatternsForLanguage(language);
1207
+ }
1208
+ async function queryPatternsForCommand(command, language) {
1209
+ const provider = bridgeProvider || createPatternsProvider();
1210
+ return provider.getPatternsForCommand(command, language);
1211
+ }
1212
+ async function getSupportedLanguages() {
1213
+ const provider = bridgeProvider || createPatternsProvider();
1214
+ return provider.getSupportedLanguages();
1215
+ }
1216
+
1217
+ // src/index.ts
1218
+ function createPatternsReference(options) {
1219
+ getDatabase(options);
1220
+ return {
1221
+ // Patterns
1222
+ getPatternById: (id) => getPatternById(id, options),
1223
+ getPatternsByCategory: (category) => getPatternsByCategory(category, options),
1224
+ getPatternsByCommand: (command) => getPatternsByCommand(command, options),
1225
+ searchPatterns: (query, searchOptions) => searchPatterns(query, searchOptions, options),
1226
+ // Translations
1227
+ getTranslation: (patternId, language) => getTranslation(patternId, language, options),
1228
+ getAllTranslations: (patternId) => getAllTranslations(patternId, options),
1229
+ verifyTranslation: (translation) => verifyTranslation(translation, options),
1230
+ // LLM
1231
+ getLLMExamples: (prompt, language, limit) => getLLMExamples(prompt, language, limit, options),
1232
+ // Stats
1233
+ getStats: () => getPatternStats(options),
1234
+ // Connection
1235
+ close: closeDatabase
1236
+ };
1237
+ }
1238
+ var VERSION = "0.1.0";
1239
+
1240
+ export { DatabasePatternsProvider, VERSION, addLLMExample, buildFewShotContext, buildFewShotContextSync, closeDatabase, createLLMAdapter, createPatternsProvider, createPatternsReference, discoverPatterns, findExamplesByCommand, findRelevantExamples, getAllCommands, getAllExpressions, getAllFeatures, getAllKeywords, getAllPatterns, getAllSpecialSymbols, getAllTranslations, getBridgeProvider, getCommandByName, getCurrentDbPath, getDatabase, getDefaultProvider, getExamplesByCommand, getExpressionByName, getExpressionsByCategory, getFeatureByName, getHighConfidenceTranslations, getHighQualityExamples, getKeywordByName, getLLMExampleStats, getLLMExamples, getLLMStats, getLanguageDocsStats, getMostUsedExamples, getPatternById, getPatternStats, getPatternsByCategory, getPatternsByCommand, getSpecialSymbolByName, getSupportedLanguages, getTranslation, getTranslationStats, getTranslationsByLanguage, getVerifiedTranslations, getWordOrder, initializeSemanticIntegration, isConnected, isDatabaseAvailable, isSemanticIntegrationInitialized, queryPatterns, queryPatternsForCommand, resetConnection, resetDefaultProvider, searchCommands, searchLanguageElements, searchPatterns, seedLLMExamples, syncTranslations, trackExampleUsage, uninitializeSemanticIntegration, updateQualityScore, validateAllTranslations, verifyTranslation };