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