@hyperfixi/patterns-reference 3.1.1 → 3.2.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/CHANGELOG.md +145 -0
- package/README.md +47 -36
- package/data/engine-verification.json +40 -38
- package/data/patterns.db +0 -0
- package/data/patterns.db.stamp +1 -0
- package/dist/api/index.d.mts +2 -2
- package/dist/api/index.d.ts +2 -2
- package/dist/api/index.js +198 -98
- package/dist/api/index.mjs +197 -100
- package/dist/{index-6GkHj5yJ.d.mts → index-CoDUfq2P.d.mts} +39 -3
- package/dist/{index-6GkHj5yJ.d.ts → index-CoDUfq2P.d.ts} +39 -3
- package/dist/index.d.mts +87 -13
- package/dist/index.d.ts +87 -13
- package/dist/index.js +261 -144
- package/dist/index.mjs +258 -146
- package/dist/{llm-B5nGz8V1.d.mts → llm-CCCSw-yp.d.ts} +21 -10
- package/dist/{llm-rEdJQScF.d.ts → llm-PxnriEZ_.d.mts} +21 -10
- package/dist/sync/index.d.mts +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.js +4 -1
- package/dist/sync/index.mjs +4 -1
- package/package.json +16 -16
- package/src/adapters/llm-adapter.ts +64 -42
- package/src/api/engine-filter.ts +37 -0
- package/src/api/llm.ts +54 -64
- package/src/api/patterns.ts +92 -30
- package/src/api/roles.ts +6 -4
- package/src/api/translations.ts +34 -27
- package/src/database/connection.ts +16 -4
- package/src/html-snippets.ts +39 -10
- package/src/index.ts +12 -2
- package/src/registry/patterns-provider.ts +3 -1
- package/src/sync/db-stamp.ts +7 -4
- package/src/sync/markup-attributes.ts +15 -0
- package/src/sync/verify-parses.ts +42 -0
- package/src/types/better-sqlite3.d.ts +2 -0
- package/src/types/index.ts +44 -2
- package/src/sync/span-mask.ts +0 -166
- package/src/sync/translation-checks.ts +0 -282
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var semantic = require('@lokascript/semantic');
|
|
3
4
|
var Database = require('better-sqlite3');
|
|
4
5
|
var fs = require('fs');
|
|
5
6
|
var url = require('url');
|
|
@@ -10,9 +11,84 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
11
|
|
|
11
12
|
var Database__default = /*#__PURE__*/_interopDefault(Database);
|
|
12
13
|
|
|
14
|
+
var __defProp = Object.defineProperty;
|
|
15
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
16
|
+
var __esm = (fn, res) => function __init() {
|
|
17
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name in all)
|
|
21
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
|
+
};
|
|
23
|
+
|
|
13
24
|
// ../../node_modules/tsup/assets/cjs_shims.js
|
|
14
|
-
var getImportMetaUrl
|
|
15
|
-
var
|
|
25
|
+
var getImportMetaUrl, importMetaUrl;
|
|
26
|
+
var init_cjs_shims = __esm({
|
|
27
|
+
"../../node_modules/tsup/assets/cjs_shims.js"() {
|
|
28
|
+
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;
|
|
29
|
+
importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// src/sync/markup-attributes.ts
|
|
34
|
+
function findHyperscriptAttributes(markup) {
|
|
35
|
+
const spans = [];
|
|
36
|
+
ATTRIBUTE.lastIndex = 0;
|
|
37
|
+
let match;
|
|
38
|
+
while ((match = ATTRIBUTE.exec(markup)) !== null) {
|
|
39
|
+
const body = match[2] ?? match[3];
|
|
40
|
+
const start = match.index + match[0].length - body.length - 1;
|
|
41
|
+
spans.push({ start, end: start + body.length, body });
|
|
42
|
+
}
|
|
43
|
+
return spans;
|
|
44
|
+
}
|
|
45
|
+
function isMarkupRow(code) {
|
|
46
|
+
return /^\s*<[a-zA-Z!]/.test(code);
|
|
47
|
+
}
|
|
48
|
+
function hyperscriptBodies(code) {
|
|
49
|
+
if (!isMarkupRow(code)) return [code];
|
|
50
|
+
const bodies = findHyperscriptAttributes(code).map((span) => span.body);
|
|
51
|
+
for (const match of code.matchAll(HX_LIVE_ATTRIBUTE)) bodies.push(match[2] ?? match[3] ?? "");
|
|
52
|
+
return bodies.filter((body) => body.trim().length > 0);
|
|
53
|
+
}
|
|
54
|
+
var ATTRIBUTE, HX_LIVE_ATTRIBUTE;
|
|
55
|
+
var init_markup_attributes = __esm({
|
|
56
|
+
"src/sync/markup-attributes.ts"() {
|
|
57
|
+
init_cjs_shims();
|
|
58
|
+
ATTRIBUTE = /(^|[\s"'])_\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
59
|
+
HX_LIVE_ATTRIBUTE = /(^|[\s"'])hx-live\s*=\s*(?:"([^"]*)"|'([^']*)')/g;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// src/sync/verify-parses.ts
|
|
64
|
+
var verify_parses_exports = {};
|
|
65
|
+
__export(verify_parses_exports, {
|
|
66
|
+
verifyParses: () => verifyParses
|
|
67
|
+
});
|
|
68
|
+
function verifyParses(code, language, translatable = true) {
|
|
69
|
+
const bodies = hyperscriptBodies(code);
|
|
70
|
+
if (bodies.length === 0) return false;
|
|
71
|
+
const parseLanguage = translatable ? language : "en";
|
|
72
|
+
return bodies.every((body) => {
|
|
73
|
+
try {
|
|
74
|
+
return semantic.canParse(body, parseLanguage);
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
var init_verify_parses = __esm({
|
|
81
|
+
"src/sync/verify-parses.ts"() {
|
|
82
|
+
init_cjs_shims();
|
|
83
|
+
init_markup_attributes();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// src/index.ts
|
|
88
|
+
init_cjs_shims();
|
|
89
|
+
|
|
90
|
+
// src/database/connection.ts
|
|
91
|
+
init_cjs_shims();
|
|
16
92
|
var __filename2 = url.fileURLToPath(importMetaUrl);
|
|
17
93
|
var __dirname$1 = path.dirname(__filename2);
|
|
18
94
|
var DEFAULT_DB_PATH = process.env.LSP_DB_PATH || process.env.HYPERSCRIPT_LSP_DB || path.join(__dirname$1, "../data/patterns.db");
|
|
@@ -20,6 +96,7 @@ var dbInstance = null;
|
|
|
20
96
|
var currentDbPath = null;
|
|
21
97
|
var openFileId = null;
|
|
22
98
|
var lastIdentityCheckAt = 0;
|
|
99
|
+
var openReadonly = false;
|
|
23
100
|
var IDENTITY_TTL_MS = 1e3;
|
|
24
101
|
function fileIdentity(path) {
|
|
25
102
|
try {
|
|
@@ -34,7 +111,9 @@ function getDefaultDbPath() {
|
|
|
34
111
|
}
|
|
35
112
|
function getDatabase(options = {}) {
|
|
36
113
|
const dbPath = options.dbPath ?? DEFAULT_DB_PATH;
|
|
37
|
-
|
|
114
|
+
const readonly = options.readonly ?? false;
|
|
115
|
+
const canServe = !openReadonly || readonly;
|
|
116
|
+
if (dbInstance !== null && currentDbPath === dbPath && canServe) {
|
|
38
117
|
const now = Date.now();
|
|
39
118
|
if (now - lastIdentityCheckAt < IDENTITY_TTL_MS) {
|
|
40
119
|
return dbInstance;
|
|
@@ -50,9 +129,8 @@ function getDatabase(options = {}) {
|
|
|
50
129
|
if (dbInstance !== null) {
|
|
51
130
|
dbInstance.close();
|
|
52
131
|
}
|
|
53
|
-
dbInstance = new Database__default.default(dbPath, {
|
|
54
|
-
|
|
55
|
-
});
|
|
132
|
+
dbInstance = new Database__default.default(dbPath, { readonly });
|
|
133
|
+
openReadonly = readonly;
|
|
56
134
|
dbInstance.pragma("foreign_keys = ON");
|
|
57
135
|
currentDbPath = dbPath;
|
|
58
136
|
openFileId = fileIdentity(dbPath);
|
|
@@ -66,6 +144,7 @@ function closeDatabase() {
|
|
|
66
144
|
currentDbPath = null;
|
|
67
145
|
openFileId = null;
|
|
68
146
|
lastIdentityCheckAt = 0;
|
|
147
|
+
openReadonly = false;
|
|
69
148
|
}
|
|
70
149
|
}
|
|
71
150
|
function resetConnection() {
|
|
@@ -73,6 +152,7 @@ function resetConnection() {
|
|
|
73
152
|
currentDbPath = null;
|
|
74
153
|
openFileId = null;
|
|
75
154
|
lastIdentityCheckAt = 0;
|
|
155
|
+
openReadonly = false;
|
|
76
156
|
}
|
|
77
157
|
function isConnected() {
|
|
78
158
|
return dbInstance !== null;
|
|
@@ -81,12 +161,27 @@ function getCurrentDbPath() {
|
|
|
81
161
|
return currentDbPath;
|
|
82
162
|
}
|
|
83
163
|
|
|
164
|
+
// src/api/patterns.ts
|
|
165
|
+
init_cjs_shims();
|
|
166
|
+
init_markup_attributes();
|
|
167
|
+
|
|
168
|
+
// src/api/engine-filter.ts
|
|
169
|
+
init_cjs_shims();
|
|
170
|
+
function runsOn(column, engine) {
|
|
171
|
+
if (engine === null) return { sql: `${column} IS NULL`, params: [] };
|
|
172
|
+
if (engine === "both") return { sql: `${column} = 'both'`, params: [] };
|
|
173
|
+
return { sql: `${column} IN ('both', ?)`, params: [engine] };
|
|
174
|
+
}
|
|
175
|
+
function exampleCondition(column, engine) {
|
|
176
|
+
return engine === void 0 ? { sql: `${column} IS NOT NULL`, params: [] } : runsOn(column, engine);
|
|
177
|
+
}
|
|
178
|
+
|
|
84
179
|
// src/api/patterns.ts
|
|
85
180
|
async function getPatternById(id, options) {
|
|
86
181
|
const db = getDatabase({ ...options, readonly: true });
|
|
87
182
|
const row = db.prepare(
|
|
88
183
|
`
|
|
89
|
-
SELECT id, title, raw_code, description, feature, engine, created_at
|
|
184
|
+
SELECT id, title, raw_code, description, feature, engine, translatable, created_at
|
|
90
185
|
FROM code_examples
|
|
91
186
|
WHERE id = ?
|
|
92
187
|
`
|
|
@@ -97,7 +192,7 @@ async function getPatternsByCategory(category, options) {
|
|
|
97
192
|
const db = getDatabase({ ...options, readonly: true });
|
|
98
193
|
const rows = db.prepare(
|
|
99
194
|
`
|
|
100
|
-
SELECT id, title, raw_code, description, feature, engine, created_at
|
|
195
|
+
SELECT id, title, raw_code, description, feature, engine, translatable, created_at
|
|
101
196
|
FROM code_examples
|
|
102
197
|
WHERE feature = ?
|
|
103
198
|
ORDER BY title
|
|
@@ -109,7 +204,7 @@ async function getPatternsByCommand(command, options) {
|
|
|
109
204
|
const db = getDatabase({ ...options, readonly: true });
|
|
110
205
|
const rows = db.prepare(
|
|
111
206
|
`
|
|
112
|
-
SELECT id, title, raw_code, description, feature, engine, created_at
|
|
207
|
+
SELECT id, title, raw_code, description, feature, engine, translatable, created_at
|
|
113
208
|
FROM code_examples
|
|
114
209
|
WHERE raw_code LIKE ?
|
|
115
210
|
ORDER BY title
|
|
@@ -117,32 +212,45 @@ async function getPatternsByCommand(command, options) {
|
|
|
117
212
|
).all(`%${command}%`);
|
|
118
213
|
return rows.filter((row) => new RegExp(`\\b${command}\\b`, "i").test(row.raw_code)).map(mapRowToPattern);
|
|
119
214
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
215
|
+
function engineFilter(searchOptions) {
|
|
216
|
+
return searchOptions.engine === void 0 ? { sql: "1 = 1", params: [] } : runsOn("engine", searchOptions.engine);
|
|
217
|
+
}
|
|
218
|
+
function usableIn(db, language) {
|
|
123
219
|
const rows = db.prepare(
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
ORDER BY title
|
|
129
|
-
LIMIT ? OFFSET ?
|
|
130
|
-
`
|
|
131
|
-
).all(`%${query}%`, `%${query}%`, `%${query}%`, limit, offset);
|
|
132
|
-
return rows.map(mapRowToPattern);
|
|
220
|
+
"SELECT code_example_id AS id FROM pattern_translations WHERE language = ? AND verified_parses = 1"
|
|
221
|
+
).all(language);
|
|
222
|
+
const verified = new Set(rows.map((row) => row.id));
|
|
223
|
+
return (pattern) => verified.has(pattern.id) || hyperscriptBodies(pattern.rawCode).length === 0;
|
|
133
224
|
}
|
|
134
|
-
|
|
225
|
+
function queryPatterns(searchOptions, defaultLimit, connOptions, match = { sql: "1 = 1", params: [] }) {
|
|
135
226
|
const db = getDatabase({ ...connOptions, readonly: true });
|
|
136
|
-
const { limit =
|
|
227
|
+
const { limit = defaultLimit, offset = 0, category, difficulty, language } = searchOptions;
|
|
228
|
+
const runs = engineFilter(searchOptions);
|
|
229
|
+
const inCategory = category === void 0 ? { sql: "1 = 1", params: [] } : { sql: "feature = ?", params: [category] };
|
|
137
230
|
const rows = db.prepare(
|
|
138
231
|
`
|
|
139
|
-
SELECT id, title, raw_code, description, feature, engine, created_at
|
|
232
|
+
SELECT id, title, raw_code, description, feature, engine, translatable, created_at
|
|
140
233
|
FROM code_examples
|
|
234
|
+
WHERE (${match.sql}) AND ${runs.sql} AND ${inCategory.sql}
|
|
141
235
|
ORDER BY title
|
|
142
|
-
LIMIT ? OFFSET ?
|
|
143
236
|
`
|
|
144
|
-
).all(
|
|
145
|
-
|
|
237
|
+
).all(...match.params, ...runs.params, ...inCategory.params);
|
|
238
|
+
const inLanguage = language === void 0 ? null : usableIn(db, language);
|
|
239
|
+
return rows.map(mapRowToPattern).filter((pattern) => difficulty === void 0 || pattern.difficulty === difficulty).filter((pattern) => inLanguage === null || inLanguage(pattern)).slice(offset, offset + limit);
|
|
240
|
+
}
|
|
241
|
+
async function searchPatterns(query, searchOptions = {}, connOptions) {
|
|
242
|
+
const like = `%${query}%`;
|
|
243
|
+
const inTranslation = searchOptions.language === void 0 ? { sql: "", params: [] } : {
|
|
244
|
+
sql: " OR id IN (SELECT code_example_id FROM pattern_translations WHERE language = ? AND hyperscript LIKE ?)",
|
|
245
|
+
params: [searchOptions.language, like]
|
|
246
|
+
};
|
|
247
|
+
return queryPatterns(searchOptions, 50, connOptions, {
|
|
248
|
+
sql: `title LIKE ? OR raw_code LIKE ? OR description LIKE ?${inTranslation.sql}`,
|
|
249
|
+
params: [like, like, like, ...inTranslation.params]
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function getAllPatterns(searchOptions = {}, connOptions) {
|
|
253
|
+
return queryPatterns(searchOptions, 1e3, connOptions);
|
|
146
254
|
}
|
|
147
255
|
async function getPatternStats(connOptions) {
|
|
148
256
|
const db = getDatabase({ ...connOptions, readonly: true });
|
|
@@ -201,6 +309,7 @@ function mapRowToPattern(row) {
|
|
|
201
309
|
tags: extractTags(row.raw_code),
|
|
202
310
|
difficulty: inferDifficulty(row.raw_code),
|
|
203
311
|
engine: row.engine || null,
|
|
312
|
+
translatable: row.translatable !== 0,
|
|
204
313
|
createdAt: new Date(row.created_at)
|
|
205
314
|
};
|
|
206
315
|
}
|
|
@@ -225,6 +334,7 @@ function inferDifficulty(code) {
|
|
|
225
334
|
}
|
|
226
335
|
|
|
227
336
|
// src/api/behavior-loader.ts
|
|
337
|
+
init_cjs_shims();
|
|
228
338
|
async function loadBehaviors(runtime, options) {
|
|
229
339
|
const patterns = await getBehaviorPatterns(options?.connectionOptions);
|
|
230
340
|
const filtered = options?.names ? patterns.filter((p) => options.names.some((name) => p.rawCode.includes(`behavior ${name}(`))) : patterns;
|
|
@@ -253,6 +363,7 @@ async function loadBehaviors(runtime, options) {
|
|
|
253
363
|
}
|
|
254
364
|
|
|
255
365
|
// src/api/translations.ts
|
|
366
|
+
init_cjs_shims();
|
|
256
367
|
async function getTranslation(patternId, language, options) {
|
|
257
368
|
const db = getDatabase({ ...options, readonly: true });
|
|
258
369
|
const row = db.prepare(
|
|
@@ -314,32 +425,35 @@ async function verifyTranslation(translation, options) {
|
|
|
314
425
|
let parseSuccess = false;
|
|
315
426
|
let errorMessage = null;
|
|
316
427
|
let confidence = translation.confidence;
|
|
428
|
+
const db = getDatabase(options);
|
|
429
|
+
const example = db.prepare("SELECT translatable FROM code_examples WHERE id = ?").get(translation.codeExampleId);
|
|
317
430
|
try {
|
|
318
|
-
const {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
431
|
+
const { verifyParses: verifyParses2 } = await Promise.resolve().then(() => (init_verify_parses(), verify_parses_exports));
|
|
432
|
+
parseSuccess = verifyParses2(
|
|
433
|
+
translation.hyperscript,
|
|
434
|
+
translation.language,
|
|
435
|
+
example?.translatable !== 0
|
|
436
|
+
);
|
|
437
|
+
if (!parseSuccess) errorMessage = "the semantic parser rejected it (or it has no hyperscript)";
|
|
325
438
|
} catch (e) {
|
|
326
439
|
errorMessage = e.message;
|
|
327
440
|
}
|
|
328
|
-
|
|
329
|
-
|
|
441
|
+
db.transaction(() => {
|
|
442
|
+
db.prepare(
|
|
443
|
+
`
|
|
444
|
+
UPDATE pattern_translations
|
|
445
|
+
SET verified_parses = ?, updated_at = datetime('now')
|
|
446
|
+
WHERE id = ?
|
|
330
447
|
`
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
448
|
+
).run(parseSuccess ? 1 : 0, translation.id);
|
|
449
|
+
db.prepare(
|
|
450
|
+
`
|
|
451
|
+
INSERT INTO pattern_tests
|
|
452
|
+
(code_example_id, language, test_type, success, error_message, test_date)
|
|
453
|
+
VALUES (?, ?, 'parse', ?, ?, datetime('now'))
|
|
337
454
|
`
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
VALUES (?, ?, datetime('now'), ?, ?)
|
|
341
|
-
`
|
|
342
|
-
).run(translation.codeExampleId, translation.language, parseSuccess ? 1 : 0, errorMessage);
|
|
455
|
+
).run(translation.codeExampleId, translation.language, parseSuccess ? 1 : 0, errorMessage);
|
|
456
|
+
})();
|
|
343
457
|
return {
|
|
344
458
|
translation,
|
|
345
459
|
parseSuccess,
|
|
@@ -409,74 +523,70 @@ function getWordOrder(language) {
|
|
|
409
523
|
}
|
|
410
524
|
|
|
411
525
|
// src/api/llm.ts
|
|
526
|
+
init_cjs_shims();
|
|
527
|
+
var EXAMPLES_FROM = `
|
|
528
|
+
SELECT le.*, ce.engine AS engine
|
|
529
|
+
FROM llm_examples le
|
|
530
|
+
JOIN code_examples ce ON ce.id = le.code_example_id`;
|
|
412
531
|
async function getLLMExamples(prompt, language = "en", limit = 5, options) {
|
|
413
532
|
const db = getDatabase({ ...options, readonly: true });
|
|
533
|
+
const runs = exampleCondition("ce.engine", options?.engine);
|
|
414
534
|
const keywords = extractKeywords(prompt);
|
|
415
535
|
if (keywords.length === 0) {
|
|
416
536
|
const rows2 = db.prepare(
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
ORDER BY quality_score DESC, usage_count DESC
|
|
537
|
+
`${EXAMPLES_FROM}
|
|
538
|
+
WHERE le.language = ? AND ${runs.sql}
|
|
539
|
+
ORDER BY le.quality_score DESC, le.usage_count DESC
|
|
421
540
|
LIMIT ?
|
|
422
541
|
`
|
|
423
|
-
).all(language, limit);
|
|
424
|
-
trackUsage(
|
|
425
|
-
db,
|
|
426
|
-
rows2.map((r) => r.id)
|
|
427
|
-
);
|
|
542
|
+
).all(language, ...runs.params, limit);
|
|
428
543
|
return rows2.map(mapRowToLLMExample);
|
|
429
544
|
}
|
|
430
|
-
const likeClauses = keywords.map(() => "(prompt LIKE ? OR completion LIKE ?)").join(" OR ");
|
|
545
|
+
const likeClauses = keywords.map(() => "(le.prompt LIKE ? OR le.completion LIKE ?)").join(" OR ");
|
|
431
546
|
const params = keywords.flatMap((k) => [`%${k}%`, `%${k}%`]);
|
|
432
547
|
const rows = db.prepare(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
ORDER BY quality_score DESC
|
|
548
|
+
`${EXAMPLES_FROM}
|
|
549
|
+
WHERE le.language = ? AND ${runs.sql} AND (${likeClauses})
|
|
550
|
+
ORDER BY le.quality_score DESC
|
|
437
551
|
LIMIT ?
|
|
438
552
|
`
|
|
439
|
-
).all(language, ...params, limit);
|
|
440
|
-
trackUsage(
|
|
441
|
-
db,
|
|
442
|
-
rows.map((r) => r.id)
|
|
443
|
-
);
|
|
553
|
+
).all(language, ...runs.params, ...params, limit);
|
|
444
554
|
return rows.map(mapRowToLLMExample);
|
|
445
555
|
}
|
|
446
556
|
async function getExamplesByCommand(command, language = "en", limit = 5, options) {
|
|
447
557
|
const db = getDatabase({ ...options, readonly: true });
|
|
558
|
+
const runs = exampleCondition("ce.engine", options?.engine);
|
|
448
559
|
const rows = db.prepare(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
ORDER BY quality_score DESC
|
|
560
|
+
`${EXAMPLES_FROM}
|
|
561
|
+
WHERE le.language = ? AND ${runs.sql} AND le.completion LIKE ?
|
|
562
|
+
ORDER BY le.quality_score DESC
|
|
453
563
|
LIMIT ?
|
|
454
564
|
`
|
|
455
|
-
).all(language, `%${command}%`, limit);
|
|
565
|
+
).all(language, ...runs.params, `%${command}%`, limit);
|
|
456
566
|
return rows.map(mapRowToLLMExample);
|
|
457
567
|
}
|
|
458
568
|
async function getHighQualityExamples(language = "en", minQuality = 0.8, limit = 10, options) {
|
|
459
569
|
const db = getDatabase({ ...options, readonly: true });
|
|
570
|
+
const runs = exampleCondition("ce.engine", options?.engine);
|
|
460
571
|
const rows = db.prepare(
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
ORDER BY quality_score DESC, usage_count DESC
|
|
572
|
+
`${EXAMPLES_FROM}
|
|
573
|
+
WHERE le.language = ? AND ${runs.sql} AND le.quality_score >= ?
|
|
574
|
+
ORDER BY le.quality_score DESC, le.usage_count DESC
|
|
465
575
|
LIMIT ?
|
|
466
576
|
`
|
|
467
|
-
).all(language, minQuality, limit);
|
|
577
|
+
).all(language, ...runs.params, minQuality, limit);
|
|
468
578
|
return rows.map(mapRowToLLMExample);
|
|
469
579
|
}
|
|
470
580
|
async function getMostUsedExamples(language = "en", limit = 10, options) {
|
|
471
581
|
const db = getDatabase({ ...options, readonly: true });
|
|
582
|
+
const runs = exampleCondition("ce.engine", options?.engine);
|
|
472
583
|
const rows = db.prepare(
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
ORDER BY usage_count DESC, quality_score DESC
|
|
584
|
+
`${EXAMPLES_FROM}
|
|
585
|
+
WHERE le.language = ? AND ${runs.sql}
|
|
586
|
+
ORDER BY le.usage_count DESC, le.quality_score DESC
|
|
477
587
|
LIMIT ?
|
|
478
588
|
`
|
|
479
|
-
).all(language, limit);
|
|
589
|
+
).all(language, ...runs.params, limit);
|
|
480
590
|
return rows.map(mapRowToLLMExample);
|
|
481
591
|
}
|
|
482
592
|
async function buildFewShotContext(prompt, language = "en", numExamples = 3, options) {
|
|
@@ -574,18 +684,6 @@ function extractKeywords(prompt) {
|
|
|
574
684
|
]);
|
|
575
685
|
return prompt.toLowerCase().split(/\W+/).filter((word) => word.length > 2 && !stopWords.has(word));
|
|
576
686
|
}
|
|
577
|
-
function trackUsage(db, ids) {
|
|
578
|
-
if (ids.length === 0) return;
|
|
579
|
-
try {
|
|
580
|
-
const stmt = db.prepare(`
|
|
581
|
-
UPDATE llm_examples SET usage_count = usage_count + 1 WHERE id = ?
|
|
582
|
-
`);
|
|
583
|
-
for (const id of ids) {
|
|
584
|
-
stmt.run(id);
|
|
585
|
-
}
|
|
586
|
-
} catch {
|
|
587
|
-
}
|
|
588
|
-
}
|
|
589
687
|
function mapRowToLLMExample(row) {
|
|
590
688
|
return {
|
|
591
689
|
id: row.id,
|
|
@@ -595,11 +693,13 @@ function mapRowToLLMExample(row) {
|
|
|
595
693
|
completion: row.completion,
|
|
596
694
|
qualityScore: row.quality_score,
|
|
597
695
|
usageCount: row.usage_count,
|
|
598
|
-
createdAt: new Date(row.created_at)
|
|
696
|
+
createdAt: new Date(row.created_at),
|
|
697
|
+
engine: row.engine ?? null
|
|
599
698
|
};
|
|
600
699
|
}
|
|
601
700
|
|
|
602
701
|
// src/api/language-docs.ts
|
|
702
|
+
init_cjs_shims();
|
|
603
703
|
function mapCommand(row) {
|
|
604
704
|
return {
|
|
605
705
|
id: row.id,
|
|
@@ -845,6 +945,12 @@ async function getLanguageDocsStats(options) {
|
|
|
845
945
|
expressionOperators: getCount("expression_operators")
|
|
846
946
|
};
|
|
847
947
|
}
|
|
948
|
+
|
|
949
|
+
// src/sync/index.ts
|
|
950
|
+
init_cjs_shims();
|
|
951
|
+
|
|
952
|
+
// src/sync/db-stamp.ts
|
|
953
|
+
init_cjs_shims();
|
|
848
954
|
function repoRootFromDbPath(dbPath) {
|
|
849
955
|
return path.resolve(path.dirname(dbPath), "..", "..", "..");
|
|
850
956
|
}
|
|
@@ -870,7 +976,10 @@ function dbInputFiles(dbPath) {
|
|
|
870
976
|
for (const f of [
|
|
871
977
|
path.join(pr, "scripts", "init-db.ts"),
|
|
872
978
|
path.join(pr, "scripts", "sync-translations.ts"),
|
|
873
|
-
|
|
979
|
+
// Decides which markup `_` bodies are translated (and which stay English).
|
|
980
|
+
path.join(pr, "src", "sync", "markup-attributes.ts"),
|
|
981
|
+
// Writes every row's `verified_parses`.
|
|
982
|
+
path.join(pr, "src", "sync", "verify-parses.ts"),
|
|
874
983
|
// Committed engine-verification results are seeded into the engine
|
|
875
984
|
// column by init-db.ts, so they are DB input too.
|
|
876
985
|
path.join(pr, "data", "engine-verification.json")
|
|
@@ -930,6 +1039,12 @@ async function seedLLMExamples(_dryRun = false) {
|
|
|
930
1039
|
}
|
|
931
1040
|
|
|
932
1041
|
// src/adapters/llm-adapter.ts
|
|
1042
|
+
init_cjs_shims();
|
|
1043
|
+
var RECORDS_FROM = `
|
|
1044
|
+
SELECT le.id, le.prompt, le.completion, le.language, le.quality_score as qualityScore,
|
|
1045
|
+
ce.engine AS engine
|
|
1046
|
+
FROM llm_examples le
|
|
1047
|
+
JOIN code_examples ce ON ce.id = le.code_example_id`;
|
|
933
1048
|
var syncDatabaseAvailable = true;
|
|
934
1049
|
function isDatabaseAvailable() {
|
|
935
1050
|
try {
|
|
@@ -940,42 +1055,31 @@ function isDatabaseAvailable() {
|
|
|
940
1055
|
return false;
|
|
941
1056
|
}
|
|
942
1057
|
}
|
|
943
|
-
function findRelevantExamples(prompt, language = "en", limit = 5) {
|
|
1058
|
+
function findRelevantExamples(prompt, language = "en", limit = 5, engine) {
|
|
944
1059
|
if (!syncDatabaseAvailable) return [];
|
|
945
1060
|
try {
|
|
946
1061
|
const db = getDatabase({ readonly: true });
|
|
1062
|
+
const runs = exampleCondition("ce.engine", engine);
|
|
947
1063
|
const keywords = extractKeywords2(prompt);
|
|
948
1064
|
if (keywords.length === 0) {
|
|
949
1065
|
const rows2 = db.prepare(
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
WHERE language = ?
|
|
954
|
-
ORDER BY quality_score DESC, usage_count DESC
|
|
1066
|
+
`${RECORDS_FROM}
|
|
1067
|
+
WHERE le.language = ? AND ${runs.sql}
|
|
1068
|
+
ORDER BY le.quality_score DESC, le.usage_count DESC
|
|
955
1069
|
LIMIT ?
|
|
956
1070
|
`
|
|
957
|
-
).all(language, limit);
|
|
958
|
-
trackUsageSync(
|
|
959
|
-
db,
|
|
960
|
-
rows2.map((r) => r.id)
|
|
961
|
-
);
|
|
1071
|
+
).all(language, ...runs.params, limit);
|
|
962
1072
|
return rows2;
|
|
963
1073
|
}
|
|
964
|
-
const likeClauses = keywords.map(() => "(prompt LIKE ? OR completion LIKE ?)").join(" OR ");
|
|
1074
|
+
const likeClauses = keywords.map(() => "(le.prompt LIKE ? OR le.completion LIKE ?)").join(" OR ");
|
|
965
1075
|
const params = keywords.flatMap((k) => [`%${k}%`, `%${k}%`]);
|
|
966
1076
|
const rows = db.prepare(
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
WHERE language = ? AND (${likeClauses})
|
|
971
|
-
ORDER BY quality_score DESC
|
|
1077
|
+
`${RECORDS_FROM}
|
|
1078
|
+
WHERE le.language = ? AND ${runs.sql} AND (${likeClauses})
|
|
1079
|
+
ORDER BY le.quality_score DESC
|
|
972
1080
|
LIMIT ?
|
|
973
1081
|
`
|
|
974
|
-
).all(language, ...params, limit);
|
|
975
|
-
trackUsageSync(
|
|
976
|
-
db,
|
|
977
|
-
rows.map((r) => r.id)
|
|
978
|
-
);
|
|
1082
|
+
).all(language, ...runs.params, ...params, limit);
|
|
979
1083
|
return rows;
|
|
980
1084
|
} catch (error) {
|
|
981
1085
|
console.warn(
|
|
@@ -986,19 +1090,18 @@ function findRelevantExamples(prompt, language = "en", limit = 5) {
|
|
|
986
1090
|
return [];
|
|
987
1091
|
}
|
|
988
1092
|
}
|
|
989
|
-
function findExamplesByCommand(command, language = "en", limit = 5) {
|
|
1093
|
+
function findExamplesByCommand(command, language = "en", limit = 5, engine) {
|
|
990
1094
|
if (!syncDatabaseAvailable) return [];
|
|
991
1095
|
try {
|
|
992
1096
|
const db = getDatabase({ readonly: true });
|
|
1097
|
+
const runs = exampleCondition("ce.engine", engine);
|
|
993
1098
|
const rows = db.prepare(
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
WHERE language = ? AND completion LIKE ?
|
|
998
|
-
ORDER BY quality_score DESC
|
|
1099
|
+
`${RECORDS_FROM}
|
|
1100
|
+
WHERE le.language = ? AND ${runs.sql} AND le.completion LIKE ?
|
|
1101
|
+
ORDER BY le.quality_score DESC
|
|
999
1102
|
LIMIT ?
|
|
1000
1103
|
`
|
|
1001
|
-
).all(language, `%${command}%`, limit);
|
|
1104
|
+
).all(language, ...runs.params, `%${command}%`, limit);
|
|
1002
1105
|
return rows;
|
|
1003
1106
|
} catch (error) {
|
|
1004
1107
|
console.warn(
|
|
@@ -1008,8 +1111,8 @@ function findExamplesByCommand(command, language = "en", limit = 5) {
|
|
|
1008
1111
|
return [];
|
|
1009
1112
|
}
|
|
1010
1113
|
}
|
|
1011
|
-
function buildFewShotContextSync(prompt, language = "en", numExamples = 3) {
|
|
1012
|
-
const examples = findRelevantExamples(prompt, language, numExamples);
|
|
1114
|
+
function buildFewShotContextSync(prompt, language = "en", numExamples = 3, engine) {
|
|
1115
|
+
const examples = findRelevantExamples(prompt, language, numExamples, engine);
|
|
1013
1116
|
if (examples.length === 0) {
|
|
1014
1117
|
return "";
|
|
1015
1118
|
}
|
|
@@ -1112,11 +1215,12 @@ function createLLMAdapter(options) {
|
|
|
1112
1215
|
getLLMExampleStats,
|
|
1113
1216
|
isDatabaseAvailable,
|
|
1114
1217
|
// Async methods (preferred for new code)
|
|
1115
|
-
getLLMExamples: (prompt, language, limit) => getLLMExamples(prompt, language, limit, options),
|
|
1116
|
-
getExamplesByCommand: (command, language, limit) => getExamplesByCommand(command, language, limit, options),
|
|
1117
|
-
getHighQualityExamples: (language, minQuality, limit) => getHighQualityExamples(language, minQuality, limit, options),
|
|
1118
|
-
|
|
1119
|
-
|
|
1218
|
+
getLLMExamples: (prompt, language, limit, engine) => getLLMExamples(prompt, language, limit, { ...options, engine }),
|
|
1219
|
+
getExamplesByCommand: (command, language, limit, engine) => getExamplesByCommand(command, language, limit, { ...options, engine }),
|
|
1220
|
+
getHighQualityExamples: (language, minQuality, limit, engine) => getHighQualityExamples(language, minQuality, limit, { ...options, engine }),
|
|
1221
|
+
/** @deprecated See getMostUsedExamples. */
|
|
1222
|
+
getMostUsedExamples: (language, limit, engine) => getMostUsedExamples(language, limit, { ...options, engine }),
|
|
1223
|
+
buildFewShotContext: (prompt, language, numExamples, engine) => buildFewShotContext(prompt, language, numExamples, { ...options, engine }),
|
|
1120
1224
|
getLLMStats: () => getLLMStats(options),
|
|
1121
1225
|
// Cleanup
|
|
1122
1226
|
close: closeDatabase
|
|
@@ -1124,6 +1228,7 @@ function createLLMAdapter(options) {
|
|
|
1124
1228
|
}
|
|
1125
1229
|
|
|
1126
1230
|
// src/registry/patterns-provider.ts
|
|
1231
|
+
init_cjs_shims();
|
|
1127
1232
|
var DatabasePatternsProvider = class {
|
|
1128
1233
|
id = "patterns-reference-db";
|
|
1129
1234
|
name = "Patterns Reference Database";
|
|
@@ -1173,7 +1278,9 @@ var DatabasePatternsProvider = class {
|
|
|
1173
1278
|
command: p.primaryCommand,
|
|
1174
1279
|
language: language || "en",
|
|
1175
1280
|
confidence: 1,
|
|
1176
|
-
|
|
1281
|
+
// The English source pattern: "verified" = some engine runs it
|
|
1282
|
+
// (code_examples.engine, mechanically checked) — not a constant.
|
|
1283
|
+
verified: p.engine !== null,
|
|
1177
1284
|
title: p.title,
|
|
1178
1285
|
category: p.category || void 0
|
|
1179
1286
|
}));
|
|
@@ -1275,6 +1382,7 @@ function resetDefaultProvider() {
|
|
|
1275
1382
|
}
|
|
1276
1383
|
|
|
1277
1384
|
// src/semantic-bridge.ts
|
|
1385
|
+
init_cjs_shims();
|
|
1278
1386
|
var bridgeInitialized = false;
|
|
1279
1387
|
var bridgeProvider = null;
|
|
1280
1388
|
async function initializeSemanticIntegration(options) {
|
|
@@ -1334,7 +1442,7 @@ async function uninitializeSemanticIntegration() {
|
|
|
1334
1442
|
bridgeProvider = null;
|
|
1335
1443
|
bridgeInitialized = false;
|
|
1336
1444
|
}
|
|
1337
|
-
async function
|
|
1445
|
+
async function queryPatterns2(language) {
|
|
1338
1446
|
const provider = bridgeProvider || createPatternsProvider();
|
|
1339
1447
|
return provider.getPatternsForLanguage(language);
|
|
1340
1448
|
}
|
|
@@ -1348,15 +1456,17 @@ async function getSupportedLanguages() {
|
|
|
1348
1456
|
}
|
|
1349
1457
|
|
|
1350
1458
|
// src/html-snippets.ts
|
|
1459
|
+
init_cjs_shims();
|
|
1351
1460
|
var HYPERFIXI_ONLY_ATTR_PREFIXES = ["hx-live", "sse-", "ws-"];
|
|
1352
1461
|
function extractHyperscriptFromMarkup(doc, markup) {
|
|
1353
1462
|
const container = doc.createElement("div");
|
|
1354
1463
|
try {
|
|
1355
1464
|
container.innerHTML = markup;
|
|
1356
1465
|
} catch {
|
|
1357
|
-
return { snippets: [], hyperfixiOnly: false };
|
|
1466
|
+
return { snippets: [], hyperfixiOnly: false, componentTags: [] };
|
|
1358
1467
|
}
|
|
1359
1468
|
const snippets = [];
|
|
1469
|
+
const componentTags = [];
|
|
1360
1470
|
let hyperfixiOnly = false;
|
|
1361
1471
|
for (const el of Array.from(container.querySelectorAll("*"))) {
|
|
1362
1472
|
for (const attr of Array.from(el.attributes)) {
|
|
@@ -1370,19 +1480,24 @@ function extractHyperscriptFromMarkup(doc, markup) {
|
|
|
1370
1480
|
hyperfixiOnly = true;
|
|
1371
1481
|
}
|
|
1372
1482
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1483
|
+
const tag = el.getAttribute("component");
|
|
1484
|
+
const isScriptTemplate = el.tagName === "SCRIPT" && el.getAttribute("type") === "text/hyperscript-template";
|
|
1485
|
+
if (tag && (isScriptTemplate || el.tagName === "TEMPLATE")) {
|
|
1486
|
+
componentTags.push(tag);
|
|
1487
|
+
const body = isScriptTemplate ? el.textContent ?? "" : el.innerHTML ?? "";
|
|
1488
|
+
const inner = extractHyperscriptFromMarkup(doc, body);
|
|
1489
|
+
snippets.push(...inner.snippets);
|
|
1490
|
+
componentTags.push(...inner.componentTags);
|
|
1491
|
+
hyperfixiOnly ||= inner.hyperfixiOnly;
|
|
1492
|
+
} else if (el.tagName === "SCRIPT" && el.getAttribute("type") === "text/hyperscript" && el.textContent?.trim()) {
|
|
1493
|
+
snippets.push(el.textContent);
|
|
1380
1494
|
}
|
|
1381
1495
|
}
|
|
1382
|
-
return { snippets, hyperfixiOnly };
|
|
1496
|
+
return { snippets, hyperfixiOnly, componentTags };
|
|
1383
1497
|
}
|
|
1384
1498
|
|
|
1385
1499
|
// src/index.ts
|
|
1500
|
+
init_markup_attributes();
|
|
1386
1501
|
function createPatternsReference(options) {
|
|
1387
1502
|
getDatabase(options);
|
|
1388
1503
|
return {
|
|
@@ -1396,7 +1511,7 @@ function createPatternsReference(options) {
|
|
|
1396
1511
|
getAllTranslations: (patternId) => getAllTranslations(patternId, options),
|
|
1397
1512
|
verifyTranslation: (translation) => verifyTranslation(translation, options),
|
|
1398
1513
|
// LLM
|
|
1399
|
-
getLLMExamples: (prompt, language, limit) => getLLMExamples(prompt, language, limit, options),
|
|
1514
|
+
getLLMExamples: (prompt, language, limit, engine) => getLLMExamples(prompt, language, limit, { ...options, engine }),
|
|
1400
1515
|
// Stats
|
|
1401
1516
|
getStats: () => getPatternStats(options),
|
|
1402
1517
|
// Connection
|
|
@@ -1420,6 +1535,7 @@ exports.dbStampPath = dbStampPath;
|
|
|
1420
1535
|
exports.discoverPatterns = discoverPatterns;
|
|
1421
1536
|
exports.extractHyperscriptFromMarkup = extractHyperscriptFromMarkup;
|
|
1422
1537
|
exports.findExamplesByCommand = findExamplesByCommand;
|
|
1538
|
+
exports.findHyperscriptAttributes = findHyperscriptAttributes;
|
|
1423
1539
|
exports.findRelevantExamples = findRelevantExamples;
|
|
1424
1540
|
exports.getAllCommands = getAllCommands;
|
|
1425
1541
|
exports.getAllExpressions = getAllExpressions;
|
|
@@ -1461,9 +1577,10 @@ exports.getWordOrder = getWordOrder;
|
|
|
1461
1577
|
exports.initializeSemanticIntegration = initializeSemanticIntegration;
|
|
1462
1578
|
exports.isConnected = isConnected;
|
|
1463
1579
|
exports.isDatabaseAvailable = isDatabaseAvailable;
|
|
1580
|
+
exports.isMarkupRow = isMarkupRow;
|
|
1464
1581
|
exports.isSemanticIntegrationInitialized = isSemanticIntegrationInitialized;
|
|
1465
1582
|
exports.loadBehaviors = loadBehaviors;
|
|
1466
|
-
exports.queryPatterns =
|
|
1583
|
+
exports.queryPatterns = queryPatterns2;
|
|
1467
1584
|
exports.queryPatternsForCommand = queryPatternsForCommand;
|
|
1468
1585
|
exports.resetConnection = resetConnection;
|
|
1469
1586
|
exports.resetDefaultProvider = resetDefaultProvider;
|