@eeshans/howiprompt 2.1.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/LICENSE +21 -0
- package/README.md +148 -0
- package/bin/bootstrap-db.mjs +166 -0
- package/bin/cli-helpers.mjs +86 -0
- package/bin/cli.mjs +205 -0
- package/config/ml.json +47 -0
- package/data/claude_code/.gitkeep +3 -0
- package/data/codex/.gitkeep +0 -0
- package/data/reference_clusters.json +314 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +194 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline/backends.d.ts +39 -0
- package/dist/pipeline/backends.js +411 -0
- package/dist/pipeline/backends.js.map +1 -0
- package/dist/pipeline/classifiers.d.ts +17 -0
- package/dist/pipeline/classifiers.js +181 -0
- package/dist/pipeline/classifiers.js.map +1 -0
- package/dist/pipeline/config.d.ts +21 -0
- package/dist/pipeline/config.js +79 -0
- package/dist/pipeline/config.js.map +1 -0
- package/dist/pipeline/db.d.ts +41 -0
- package/dist/pipeline/db.js +130 -0
- package/dist/pipeline/db.js.map +1 -0
- package/dist/pipeline/embeddings.d.ts +15 -0
- package/dist/pipeline/embeddings.js +82 -0
- package/dist/pipeline/embeddings.js.map +1 -0
- package/dist/pipeline/exclusions.d.ts +86 -0
- package/dist/pipeline/exclusions.js +320 -0
- package/dist/pipeline/exclusions.js.map +1 -0
- package/dist/pipeline/metrics.d.ts +12 -0
- package/dist/pipeline/metrics.js +278 -0
- package/dist/pipeline/metrics.js.map +1 -0
- package/dist/pipeline/ml-config.d.ts +23 -0
- package/dist/pipeline/ml-config.js +54 -0
- package/dist/pipeline/ml-config.js.map +1 -0
- package/dist/pipeline/models.d.ts +23 -0
- package/dist/pipeline/models.js +21 -0
- package/dist/pipeline/models.js.map +1 -0
- package/dist/pipeline/nlp.d.ts +20 -0
- package/dist/pipeline/nlp.js +200 -0
- package/dist/pipeline/nlp.js.map +1 -0
- package/dist/pipeline/parsers.d.ts +11 -0
- package/dist/pipeline/parsers.js +492 -0
- package/dist/pipeline/parsers.js.map +1 -0
- package/dist/pipeline/registry.d.ts +21 -0
- package/dist/pipeline/registry.js +45 -0
- package/dist/pipeline/registry.js.map +1 -0
- package/dist/pipeline/style.d.ts +37 -0
- package/dist/pipeline/style.js +204 -0
- package/dist/pipeline/style.js.map +1 -0
- package/dist/pipeline/sync.d.ts +8 -0
- package/dist/pipeline/sync.js +52 -0
- package/dist/pipeline/sync.js.map +1 -0
- package/dist/pipeline/trends.d.ts +8 -0
- package/dist/pipeline/trends.js +226 -0
- package/dist/pipeline/trends.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.js +216 -0
- package/dist/server.js.map +1 -0
- package/frontend/dist/_astro/MethodologyModal.astro_astro_type_script_index_0_lang.jiHwSrn-.js +34 -0
- package/frontend/dist/_astro/index.Ck1ZXjve.css +1 -0
- package/frontend/dist/_astro/index.astro_astro_type_script_index_0_lang.PuBlxVje.js +37 -0
- package/frontend/dist/_astro/index.astro_astro_type_script_index_1_lang.DmQY6kFx.js +1 -0
- package/frontend/dist/_astro/theme.CbYAaQI4.js +1 -0
- package/frontend/dist/_astro/wrapped.CpzRcLjf.css +1 -0
- package/frontend/dist/_astro/wrapped.astro_astro_type_script_index_0_lang.D4GeWu2-.js +11 -0
- package/frontend/dist/_astro/wrapped.astro_astro_type_script_index_1_lang.CPAAJDh5.js +1 -0
- package/frontend/dist/favicon.svg +4 -0
- package/frontend/dist/images/card_architect.png +0 -0
- package/frontend/dist/images/card_commander.png +0 -0
- package/frontend/dist/images/card_delegator.png +0 -0
- package/frontend/dist/images/card_explorer.png +0 -0
- package/frontend/dist/images/card_partner.png +0 -0
- package/frontend/dist/images/char_architect.png +0 -0
- package/frontend/dist/images/char_commander.png +0 -0
- package/frontend/dist/images/char_delegator.png +0 -0
- package/frontend/dist/images/char_explorer.png +0 -0
- package/frontend/dist/images/char_partner.png +0 -0
- package/frontend/dist/index.html +9 -0
- package/frontend/dist/wrapped/index.html +9 -0
- package/package.json +66 -0
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { syncClaudeCode, syncCodex, syncLmStudioConversations, syncVsCodeChatSessions, } from "./sync.js";
|
|
5
|
+
import { parseClaudeCode, parseCodexHistory, parseCodexSessionMetadata, parseLmStudioConversations, parseVsCodeChatSessions, } from "./parsers.js";
|
|
6
|
+
import { Platform } from "./models.js";
|
|
7
|
+
const DETECTION_CACHE_TTL_MS = 10_000;
|
|
8
|
+
let detectionCache = null;
|
|
9
|
+
// ── Scan helpers ───────────────────────────────────────
|
|
10
|
+
function findJsonlFilesRecursive(dir) {
|
|
11
|
+
const results = [];
|
|
12
|
+
try {
|
|
13
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
14
|
+
const full = path.join(dir, entry.name);
|
|
15
|
+
if (entry.isDirectory()) {
|
|
16
|
+
results.push(...findJsonlFilesRecursive(full));
|
|
17
|
+
}
|
|
18
|
+
else if (entry.name.endsWith(".jsonl")) {
|
|
19
|
+
results.push(full);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch { /* permission errors, etc */ }
|
|
24
|
+
return results;
|
|
25
|
+
}
|
|
26
|
+
function findFilesRecursive(dir, matcher) {
|
|
27
|
+
const results = [];
|
|
28
|
+
try {
|
|
29
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
30
|
+
const full = path.join(dir, entry.name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
results.push(...findFilesRecursive(full, matcher));
|
|
33
|
+
}
|
|
34
|
+
else if (matcher(full, entry.name)) {
|
|
35
|
+
results.push(full);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch { /* permission errors, etc */ }
|
|
40
|
+
return results;
|
|
41
|
+
}
|
|
42
|
+
function parseIso(ms) {
|
|
43
|
+
if (!ms)
|
|
44
|
+
return undefined;
|
|
45
|
+
const dt = new Date(ms);
|
|
46
|
+
return Number.isNaN(dt.getTime()) ? undefined : dt.toISOString();
|
|
47
|
+
}
|
|
48
|
+
/** Count lines and extract first/last timestamps from JSONL files. */
|
|
49
|
+
function scanClaudeCodeSource(sourceDir) {
|
|
50
|
+
const files = findJsonlFilesRecursive(sourceDir);
|
|
51
|
+
if (files.length === 0)
|
|
52
|
+
return { messageCount: 0 };
|
|
53
|
+
let totalLines = 0;
|
|
54
|
+
let earliest = null;
|
|
55
|
+
let latest = null;
|
|
56
|
+
for (const file of files) {
|
|
57
|
+
try {
|
|
58
|
+
const content = fs.readFileSync(file, "utf-8");
|
|
59
|
+
const lines = content.split("\n").filter(Boolean);
|
|
60
|
+
totalLines += lines.length;
|
|
61
|
+
// Check first and last lines for timestamps
|
|
62
|
+
for (const line of [lines[0], lines[lines.length - 1]]) {
|
|
63
|
+
if (!line)
|
|
64
|
+
continue;
|
|
65
|
+
try {
|
|
66
|
+
const obj = JSON.parse(line);
|
|
67
|
+
const ts = obj.timestamp ?? obj.snapshot?.timestamp;
|
|
68
|
+
if (ts) {
|
|
69
|
+
const d = new Date(ts);
|
|
70
|
+
if (!earliest || d < earliest)
|
|
71
|
+
earliest = d;
|
|
72
|
+
if (!latest || d > latest)
|
|
73
|
+
latest = d;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch { /* skip malformed lines */ }
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch { /* skip unreadable files */ }
|
|
80
|
+
}
|
|
81
|
+
// Each JSONL line is a message (human + assistant + meta), rough /2 for human-only
|
|
82
|
+
const messageCount = Math.round(totalLines / 2);
|
|
83
|
+
const dateRange = earliest && latest
|
|
84
|
+
? { first: earliest.toISOString(), last: latest.toISOString() }
|
|
85
|
+
: undefined;
|
|
86
|
+
return { messageCount, dateRange };
|
|
87
|
+
}
|
|
88
|
+
function scanCodexSource(sourcePath) {
|
|
89
|
+
try {
|
|
90
|
+
const content = fs.readFileSync(sourcePath, "utf-8");
|
|
91
|
+
const lines = content.split("\n").filter(Boolean);
|
|
92
|
+
if (lines.length === 0)
|
|
93
|
+
return { messageCount: 0 };
|
|
94
|
+
let earliest = null;
|
|
95
|
+
let latest = null;
|
|
96
|
+
// Read first and last lines for ts
|
|
97
|
+
for (const line of [lines[0], lines[lines.length - 1]]) {
|
|
98
|
+
try {
|
|
99
|
+
const obj = JSON.parse(line);
|
|
100
|
+
if (obj.ts) {
|
|
101
|
+
if (!earliest || obj.ts < earliest)
|
|
102
|
+
earliest = obj.ts;
|
|
103
|
+
if (!latest || obj.ts > latest)
|
|
104
|
+
latest = obj.ts;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch { /* skip */ }
|
|
108
|
+
}
|
|
109
|
+
const dateRange = earliest && latest
|
|
110
|
+
? { first: new Date(earliest * 1000).toISOString(), last: new Date(latest * 1000).toISOString() }
|
|
111
|
+
: undefined;
|
|
112
|
+
return { messageCount: lines.length, dateRange };
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return { messageCount: 0 };
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function scanVsCodeChatSource(sourceDir) {
|
|
119
|
+
const files = findFilesRecursive(sourceDir, (filePath, entryName) => entryName.endsWith(".json") && filePath.includes(`${path.sep}chatSessions${path.sep}`));
|
|
120
|
+
if (files.length === 0)
|
|
121
|
+
return { messageCount: 0 };
|
|
122
|
+
let messageCount = 0;
|
|
123
|
+
let earliestMs = null;
|
|
124
|
+
let latestMs = null;
|
|
125
|
+
for (const file of files) {
|
|
126
|
+
try {
|
|
127
|
+
const session = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
128
|
+
const requests = Array.isArray(session.requests) ? session.requests : [];
|
|
129
|
+
messageCount += requests.length;
|
|
130
|
+
const timestamps = [
|
|
131
|
+
typeof session.creationDate === "number" ? session.creationDate : null,
|
|
132
|
+
typeof session.lastMessageDate === "number" ? session.lastMessageDate : null,
|
|
133
|
+
].filter((value) => typeof value === "number");
|
|
134
|
+
for (const request of requests) {
|
|
135
|
+
if (typeof request?.timestamp === "number")
|
|
136
|
+
timestamps.push(request.timestamp);
|
|
137
|
+
}
|
|
138
|
+
for (const ts of timestamps) {
|
|
139
|
+
if (earliestMs === null || ts < earliestMs)
|
|
140
|
+
earliestMs = ts;
|
|
141
|
+
if (latestMs === null || ts > latestMs)
|
|
142
|
+
latestMs = ts;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch { /* skip unreadable files */ }
|
|
146
|
+
}
|
|
147
|
+
const first = parseIso(earliestMs);
|
|
148
|
+
const last = parseIso(latestMs);
|
|
149
|
+
return {
|
|
150
|
+
messageCount,
|
|
151
|
+
dateRange: first && last ? { first, last } : undefined,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function scanLmStudioSource(sourceDir) {
|
|
155
|
+
const files = findFilesRecursive(sourceDir, (_filePath, entryName) => entryName.endsWith(".conversation.json"));
|
|
156
|
+
if (files.length === 0)
|
|
157
|
+
return { messageCount: 0 };
|
|
158
|
+
let messageCount = 0;
|
|
159
|
+
let earliestMs = null;
|
|
160
|
+
let latestMs = null;
|
|
161
|
+
for (const file of files) {
|
|
162
|
+
try {
|
|
163
|
+
const conversation = JSON.parse(fs.readFileSync(file, "utf-8"));
|
|
164
|
+
const messages = Array.isArray(conversation.messages) ? conversation.messages : [];
|
|
165
|
+
for (const message of messages) {
|
|
166
|
+
const selectedIndex = Number.isInteger(message?.currentlySelected) ? message.currentlySelected : 0;
|
|
167
|
+
const version = Array.isArray(message?.versions) ? message.versions[selectedIndex] ?? message.versions[0] : null;
|
|
168
|
+
if (version?.role === "user")
|
|
169
|
+
messageCount++;
|
|
170
|
+
}
|
|
171
|
+
const timestamps = [
|
|
172
|
+
typeof conversation.createdAt === "number" ? conversation.createdAt : null,
|
|
173
|
+
typeof conversation.userLastMessagedAt === "number" ? conversation.userLastMessagedAt : null,
|
|
174
|
+
typeof conversation.assistantLastMessagedAt === "number" ? conversation.assistantLastMessagedAt : null,
|
|
175
|
+
].filter((value) => typeof value === "number");
|
|
176
|
+
for (const ts of timestamps) {
|
|
177
|
+
if (earliestMs === null || ts < earliestMs)
|
|
178
|
+
earliestMs = ts;
|
|
179
|
+
if (latestMs === null || ts > latestMs)
|
|
180
|
+
latestMs = ts;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch { /* skip unreadable files */ }
|
|
184
|
+
}
|
|
185
|
+
const first = parseIso(earliestMs);
|
|
186
|
+
const last = parseIso(latestMs);
|
|
187
|
+
return {
|
|
188
|
+
messageCount,
|
|
189
|
+
dateRange: first && last ? { first, last } : undefined,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
// ── Skill discovery helpers ───────────────────────────────
|
|
193
|
+
function readSkillTemplate(skillDir) {
|
|
194
|
+
// Try common skill definition filenames
|
|
195
|
+
for (const name of ["SKILL.md", "skill.md", "README.md", "prompt.md", "index.md"]) {
|
|
196
|
+
const p = path.join(skillDir, name);
|
|
197
|
+
try {
|
|
198
|
+
return fs.readFileSync(p, "utf-8");
|
|
199
|
+
}
|
|
200
|
+
catch { /* not found, try next */ }
|
|
201
|
+
}
|
|
202
|
+
return "";
|
|
203
|
+
}
|
|
204
|
+
function scanSkillDirs(searchPaths, buildPattern) {
|
|
205
|
+
const skills = [];
|
|
206
|
+
for (const base of searchPaths) {
|
|
207
|
+
try {
|
|
208
|
+
if (!fs.existsSync(base))
|
|
209
|
+
continue;
|
|
210
|
+
for (const entry of fs.readdirSync(base, { withFileTypes: true })) {
|
|
211
|
+
if (!entry.isDirectory() || entry.name.startsWith("."))
|
|
212
|
+
continue;
|
|
213
|
+
const skillPath = path.join(base, entry.name);
|
|
214
|
+
skills.push({
|
|
215
|
+
skillName: entry.name,
|
|
216
|
+
skillPath,
|
|
217
|
+
invocationPattern: buildPattern(entry.name),
|
|
218
|
+
templateContent: readSkillTemplate(skillPath),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch { /* permission errors, etc */ }
|
|
223
|
+
}
|
|
224
|
+
return skills;
|
|
225
|
+
}
|
|
226
|
+
// ── Claude Code ────────────────────────────────────────
|
|
227
|
+
class ClaudeCodeBackend {
|
|
228
|
+
id = "claude_code";
|
|
229
|
+
name = "Claude Code";
|
|
230
|
+
detect() {
|
|
231
|
+
const sourcePath = path.join(os.homedir(), ".claude", "projects");
|
|
232
|
+
const detected = fs.existsSync(sourcePath);
|
|
233
|
+
return {
|
|
234
|
+
id: this.id,
|
|
235
|
+
name: this.name,
|
|
236
|
+
supported: true,
|
|
237
|
+
detected,
|
|
238
|
+
sourcePath,
|
|
239
|
+
status: detected ? "available" : "not_found",
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
sync(config) {
|
|
243
|
+
return syncClaudeCode(config.claudeCodeSource);
|
|
244
|
+
}
|
|
245
|
+
async parse(config) {
|
|
246
|
+
const exclusions = config.backends?.[this.id]?.exclusions ?? [];
|
|
247
|
+
return parseClaudeCode(config.claudeCodeSource, exclusions);
|
|
248
|
+
}
|
|
249
|
+
discoverSkills() {
|
|
250
|
+
const home = os.homedir();
|
|
251
|
+
return scanSkillDirs([path.join(home, ".claude", "skills")],
|
|
252
|
+
// Only match explicit /slash invocation at start of message
|
|
253
|
+
(name) => `^\\/${name}\\b`);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// ── Codex ──────────────────────────────────────────────
|
|
257
|
+
class CodexBackend {
|
|
258
|
+
id = "codex";
|
|
259
|
+
name = "Codex";
|
|
260
|
+
detect() {
|
|
261
|
+
const sourcePath = path.join(os.homedir(), ".codex", "history.jsonl");
|
|
262
|
+
const detected = fs.existsSync(sourcePath);
|
|
263
|
+
return {
|
|
264
|
+
id: this.id,
|
|
265
|
+
name: this.name,
|
|
266
|
+
supported: true,
|
|
267
|
+
detected,
|
|
268
|
+
sourcePath,
|
|
269
|
+
status: detected ? "available" : "not_found",
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
sync(config) {
|
|
273
|
+
return syncCodex(config.codexHistorySource);
|
|
274
|
+
}
|
|
275
|
+
async parse(config) {
|
|
276
|
+
const sessionModels = await parseCodexSessionMetadata(config.codexSessionsSource);
|
|
277
|
+
return parseCodexHistory(config.codexHistorySource, sessionModels);
|
|
278
|
+
}
|
|
279
|
+
discoverSkills() {
|
|
280
|
+
const home = os.homedir();
|
|
281
|
+
return scanSkillDirs([path.join(home, ".codex", "skills")],
|
|
282
|
+
// Match [$skill-name](...) or $skill-name at start of message
|
|
283
|
+
(name) => `^(?:\\[\\$${name}\\]\\(|\\$${name}\\b)`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// ── Copilot Chat ───────────────────────────────────────
|
|
287
|
+
class CopilotChatBackend {
|
|
288
|
+
id = "copilot_chat";
|
|
289
|
+
name = "Copilot Chat";
|
|
290
|
+
detect() {
|
|
291
|
+
const sourcePath = path.join(os.homedir(), "Library", "Application Support", "Code", "User", "workspaceStorage");
|
|
292
|
+
const detected = fs.existsSync(sourcePath);
|
|
293
|
+
return {
|
|
294
|
+
id: this.id,
|
|
295
|
+
name: this.name,
|
|
296
|
+
supported: true,
|
|
297
|
+
detected,
|
|
298
|
+
sourcePath,
|
|
299
|
+
status: detected ? "available" : "not_found",
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
sync(config) {
|
|
303
|
+
return syncVsCodeChatSessions(path.join(os.homedir(), "Library", "Application Support", "Code", "User", "workspaceStorage"), config.copilotChatSource);
|
|
304
|
+
}
|
|
305
|
+
async parse(config) {
|
|
306
|
+
return parseVsCodeChatSessions(config.copilotChatSource, Platform.COPILOT_CHAT);
|
|
307
|
+
}
|
|
308
|
+
discoverSkills() {
|
|
309
|
+
return [
|
|
310
|
+
{
|
|
311
|
+
skillName: "agent-command",
|
|
312
|
+
skillPath: "",
|
|
313
|
+
invocationPattern: "^@agent\\b",
|
|
314
|
+
templateContent: "",
|
|
315
|
+
source: "config",
|
|
316
|
+
},
|
|
317
|
+
];
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// ── Cursor ─────────────────────────────────────────────
|
|
321
|
+
class CursorBackend {
|
|
322
|
+
id = "cursor";
|
|
323
|
+
name = "Cursor";
|
|
324
|
+
detect() {
|
|
325
|
+
const sourcePath = path.join(os.homedir(), "Library", "Application Support", "Cursor", "User", "workspaceStorage");
|
|
326
|
+
const detected = fs.existsSync(sourcePath);
|
|
327
|
+
return {
|
|
328
|
+
id: this.id,
|
|
329
|
+
name: this.name,
|
|
330
|
+
supported: true,
|
|
331
|
+
detected,
|
|
332
|
+
sourcePath,
|
|
333
|
+
status: detected ? "available" : "not_found",
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
sync(config) {
|
|
337
|
+
return syncVsCodeChatSessions(path.join(os.homedir(), "Library", "Application Support", "Cursor", "User", "workspaceStorage"), config.cursorSource);
|
|
338
|
+
}
|
|
339
|
+
async parse(config) {
|
|
340
|
+
return parseVsCodeChatSessions(config.cursorSource, Platform.CURSOR);
|
|
341
|
+
}
|
|
342
|
+
discoverSkills() {
|
|
343
|
+
const home = os.homedir();
|
|
344
|
+
return scanSkillDirs([path.join(home, ".cursor", "skills-cursor")],
|
|
345
|
+
// Only match explicit /slash invocation at start of message
|
|
346
|
+
(name) => `^\\/${name}\\b`);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
// ── LM Studio ──────────────────────────────────────────
|
|
350
|
+
class LmStudioBackend {
|
|
351
|
+
id = "lmstudio";
|
|
352
|
+
name = "LM Studio";
|
|
353
|
+
detect() {
|
|
354
|
+
const sourcePath = path.join(os.homedir(), ".lmstudio", "conversations");
|
|
355
|
+
const detected = fs.existsSync(sourcePath);
|
|
356
|
+
return {
|
|
357
|
+
id: this.id,
|
|
358
|
+
name: this.name,
|
|
359
|
+
supported: true,
|
|
360
|
+
detected,
|
|
361
|
+
sourcePath,
|
|
362
|
+
status: detected ? "available" : "not_found",
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
sync(config) {
|
|
366
|
+
return syncLmStudioConversations(config.lmStudioSource);
|
|
367
|
+
}
|
|
368
|
+
async parse(config) {
|
|
369
|
+
return parseLmStudioConversations(config.lmStudioSource);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
// ── Registry ───────────────────────────────────────────
|
|
373
|
+
const ALL_BACKENDS = [
|
|
374
|
+
new ClaudeCodeBackend(),
|
|
375
|
+
new CodexBackend(),
|
|
376
|
+
new CopilotChatBackend(),
|
|
377
|
+
new CursorBackend(),
|
|
378
|
+
new LmStudioBackend(),
|
|
379
|
+
];
|
|
380
|
+
export function getAllBackends() {
|
|
381
|
+
return ALL_BACKENDS;
|
|
382
|
+
}
|
|
383
|
+
export function getBackend(id) {
|
|
384
|
+
return ALL_BACKENDS.find((b) => b.id === id);
|
|
385
|
+
}
|
|
386
|
+
export function detectAll() {
|
|
387
|
+
const now = Date.now();
|
|
388
|
+
if (detectionCache && detectionCache.expiresAt > now) {
|
|
389
|
+
return detectionCache.infos;
|
|
390
|
+
}
|
|
391
|
+
const infos = ALL_BACKENDS.map((b) => b.detect());
|
|
392
|
+
detectionCache = {
|
|
393
|
+
expiresAt: now + DETECTION_CACHE_TTL_MS,
|
|
394
|
+
infos,
|
|
395
|
+
};
|
|
396
|
+
return infos;
|
|
397
|
+
}
|
|
398
|
+
export function resetBackendDetectionCacheForTests() {
|
|
399
|
+
detectionCache = null;
|
|
400
|
+
}
|
|
401
|
+
/** Get backends that are enabled and have working parsers */
|
|
402
|
+
export function getEnabledBackends(config) {
|
|
403
|
+
const available = new Map(detectAll().map((info) => [info.id, info]));
|
|
404
|
+
return ALL_BACKENDS.filter((b) => {
|
|
405
|
+
const info = available.get(b.id);
|
|
406
|
+
if (!info || info.status !== "available")
|
|
407
|
+
return false;
|
|
408
|
+
return config.backends?.[b.id]?.enabled !== false;
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
//# sourceMappingURL=backends.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backends.js","sourceRoot":"","sources":["../../src/pipeline/backends.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Client } from "@libsql/client";
|
|
2
|
+
import type { MlConfig } from "./ml-config.js";
|
|
3
|
+
interface ClassifierResult {
|
|
4
|
+
score: number;
|
|
5
|
+
confidence: number;
|
|
6
|
+
topSignals: Array<{
|
|
7
|
+
signal: string;
|
|
8
|
+
similarity: number;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare function resetClassifiersForTests(): void;
|
|
12
|
+
export declare function initClassifiers(client: Client, mlConfig: MlConfig, dataDir: string): Promise<void>;
|
|
13
|
+
export declare function computeHitlScore(embedding: Float32Array, mlConfig: MlConfig): ClassifierResult;
|
|
14
|
+
export declare function computeVibeIndex(embedding: Float32Array, mlConfig: MlConfig): ClassifierResult;
|
|
15
|
+
export declare function computePoliteness(embedding: Float32Array, mlConfig: MlConfig): ClassifierResult;
|
|
16
|
+
export declare function enrichClassifiers(client: Client, mlConfig: MlConfig, dataDir: string, onBatchProgress?: (classified: number, total: number) => void): Promise<number>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { initEmbedder, embedTexts, cosineSimilarity } from "./embeddings.js";
|
|
5
|
+
let hitlCentroids = null;
|
|
6
|
+
let vibeCentroids = null;
|
|
7
|
+
let politenessCentroids = null;
|
|
8
|
+
export function resetClassifiersForTests() {
|
|
9
|
+
hitlCentroids = null;
|
|
10
|
+
vibeCentroids = null;
|
|
11
|
+
politenessCentroids = null;
|
|
12
|
+
}
|
|
13
|
+
function loadReferenceClusters() {
|
|
14
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const candidates = [
|
|
16
|
+
path.join(__dirname, "..", "..", "data", "reference_clusters.json"),
|
|
17
|
+
path.join(__dirname, "..", "data", "reference_clusters.json"),
|
|
18
|
+
];
|
|
19
|
+
for (const p of candidates) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(fs.readFileSync(p, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
catch { /* try next */ }
|
|
24
|
+
}
|
|
25
|
+
throw new Error("reference_clusters.json not found");
|
|
26
|
+
}
|
|
27
|
+
async function buildCentroids(client, classifier, clusters, weights, mlConfig, dataDir) {
|
|
28
|
+
// Check if centroids are cached in DB
|
|
29
|
+
const cached = await client.execute({
|
|
30
|
+
sql: "SELECT cluster, embedding FROM reference_embeddings WHERE classifier = ?",
|
|
31
|
+
args: [classifier],
|
|
32
|
+
});
|
|
33
|
+
if (cached.rows.length > 0) {
|
|
34
|
+
return cached.rows.map((r) => {
|
|
35
|
+
const cluster = String(r.cluster);
|
|
36
|
+
// Embedding stored as F32_BLOB — comes back as ArrayBuffer
|
|
37
|
+
const buf = r.embedding;
|
|
38
|
+
const centroid = new Float32Array(buf);
|
|
39
|
+
return { cluster, centroid, weight: weights[cluster] ?? 0 };
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// Compute centroids: embed all examples per cluster, average them
|
|
43
|
+
const modelCacheDir = path.join(dataDir, "models");
|
|
44
|
+
await initEmbedder(mlConfig, modelCacheDir);
|
|
45
|
+
const centroids = [];
|
|
46
|
+
for (const [cluster, examples] of Object.entries(clusters)) {
|
|
47
|
+
const vectors = await embedTexts(examples, mlConfig);
|
|
48
|
+
// Average to get centroid
|
|
49
|
+
const dims = mlConfig.embedding.dimensions;
|
|
50
|
+
const centroid = new Float32Array(dims);
|
|
51
|
+
for (const vec of vectors) {
|
|
52
|
+
for (let i = 0; i < dims; i++)
|
|
53
|
+
centroid[i] += vec[i];
|
|
54
|
+
}
|
|
55
|
+
for (let i = 0; i < dims; i++)
|
|
56
|
+
centroid[i] /= vectors.length;
|
|
57
|
+
// Normalize centroid
|
|
58
|
+
let norm = 0;
|
|
59
|
+
for (let i = 0; i < dims; i++)
|
|
60
|
+
norm += centroid[i] * centroid[i];
|
|
61
|
+
norm = Math.sqrt(norm);
|
|
62
|
+
if (norm > 0)
|
|
63
|
+
for (let i = 0; i < dims; i++)
|
|
64
|
+
centroid[i] /= norm;
|
|
65
|
+
centroids.push({ cluster, centroid, weight: weights[cluster] ?? 0 });
|
|
66
|
+
// Cache in DB
|
|
67
|
+
await client.execute({
|
|
68
|
+
sql: "INSERT INTO reference_embeddings (classifier, cluster, prompt, embedding) VALUES (?, ?, ?, vector32(?))",
|
|
69
|
+
args: [classifier, cluster, examples.join("\n---\n"), JSON.stringify(Array.from(centroid))],
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return centroids;
|
|
73
|
+
}
|
|
74
|
+
function scoreFromCentroids(embedding, centroids, config) {
|
|
75
|
+
const similarities = [];
|
|
76
|
+
for (const c of centroids) {
|
|
77
|
+
const sim = cosineSimilarity(embedding, c.centroid);
|
|
78
|
+
similarities.push({ cluster: c.cluster, similarity: sim, weight: c.weight });
|
|
79
|
+
}
|
|
80
|
+
// Sort by absolute similarity descending
|
|
81
|
+
similarities.sort((a, b) => b.similarity - a.similarity);
|
|
82
|
+
// Signal strength = how much above baseline a match is.
|
|
83
|
+
// Random text-to-text cosine similarity is typically 0.3-0.5 for normalized embeddings.
|
|
84
|
+
// Only count matches meaningfully above this baseline.
|
|
85
|
+
const baseline = config.similarityThreshold;
|
|
86
|
+
let rawScore = 0;
|
|
87
|
+
let maxPossibleScore = 0;
|
|
88
|
+
for (const s of similarities) {
|
|
89
|
+
const strength = Math.max(0, s.similarity - baseline);
|
|
90
|
+
rawScore += strength * s.weight;
|
|
91
|
+
maxPossibleScore += Math.max(0, 1 - baseline) * Math.abs(s.weight);
|
|
92
|
+
}
|
|
93
|
+
// Normalize to 0-100 range
|
|
94
|
+
const center = config.centerPoint ?? 0;
|
|
95
|
+
let score;
|
|
96
|
+
if (maxPossibleScore > 0) {
|
|
97
|
+
// Scale raw score to [-1, 1] range relative to max possible, then map to 0-100
|
|
98
|
+
const normalized = rawScore / maxPossibleScore; // -1 to 1
|
|
99
|
+
score = center + normalized * config.normalizationScale * 10;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
score = center;
|
|
103
|
+
}
|
|
104
|
+
score = Math.max(0, Math.min(100, score));
|
|
105
|
+
// Confidence: based on how strongly the prompt matches its best cluster above baseline
|
|
106
|
+
const topStrength = Math.max(0, (similarities[0]?.similarity ?? 0) - baseline);
|
|
107
|
+
const confidence = Math.min(0.95, Math.max(config.confidenceFloor ?? 0.5, 0.5 + topStrength * 1.5));
|
|
108
|
+
const topSignals = similarities
|
|
109
|
+
.filter((s) => s.similarity > baseline)
|
|
110
|
+
.slice(0, 3)
|
|
111
|
+
.map((s) => ({ signal: s.cluster, similarity: round(s.similarity, 3) }));
|
|
112
|
+
return { score: round(score, 1), confidence: round(confidence, 2), topSignals };
|
|
113
|
+
}
|
|
114
|
+
export async function initClassifiers(client, mlConfig, dataDir) {
|
|
115
|
+
const clusters = loadReferenceClusters();
|
|
116
|
+
hitlCentroids = await buildCentroids(client, "hitl", clusters.hitl, mlConfig.hitl.weights, mlConfig, dataDir);
|
|
117
|
+
vibeCentroids = await buildCentroids(client, "vibe", clusters.vibe, mlConfig.vibe.weights, mlConfig, dataDir);
|
|
118
|
+
politenessCentroids = await buildCentroids(client, "politeness", clusters.politeness, mlConfig.politeness.weights, mlConfig, dataDir);
|
|
119
|
+
}
|
|
120
|
+
export function computeHitlScore(embedding, mlConfig) {
|
|
121
|
+
if (!hitlCentroids)
|
|
122
|
+
throw new Error("Classifiers not initialized");
|
|
123
|
+
return scoreFromCentroids(embedding, hitlCentroids, {
|
|
124
|
+
...mlConfig.hitl,
|
|
125
|
+
centerPoint: 0,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
export function computeVibeIndex(embedding, mlConfig) {
|
|
129
|
+
if (!vibeCentroids)
|
|
130
|
+
throw new Error("Classifiers not initialized");
|
|
131
|
+
return scoreFromCentroids(embedding, vibeCentroids, mlConfig.vibe);
|
|
132
|
+
}
|
|
133
|
+
export function computePoliteness(embedding, mlConfig) {
|
|
134
|
+
if (!politenessCentroids)
|
|
135
|
+
throw new Error("Classifiers not initialized");
|
|
136
|
+
return scoreFromCentroids(embedding, politenessCentroids, mlConfig.politeness);
|
|
137
|
+
}
|
|
138
|
+
export async function enrichClassifiers(client, mlConfig, dataDir, onBatchProgress) {
|
|
139
|
+
// Find messages with embeddings but without hero classifier scores
|
|
140
|
+
const result = await client.execute(`SELECT m.id, m.embedding FROM messages m
|
|
141
|
+
JOIN nlp_enrichments e ON m.id = e.message_id
|
|
142
|
+
WHERE m.role = 'human' AND m.embedding IS NOT NULL
|
|
143
|
+
AND (e.hitl_score IS NULL OR e.vibe_score IS NULL OR e.politeness_score IS NULL)`);
|
|
144
|
+
if (result.rows.length === 0)
|
|
145
|
+
return 0;
|
|
146
|
+
// Init classifiers if needed
|
|
147
|
+
await initClassifiers(client, mlConfig, dataDir);
|
|
148
|
+
const batchSize = 200;
|
|
149
|
+
let classified = 0;
|
|
150
|
+
for (let i = 0; i < result.rows.length; i += batchSize) {
|
|
151
|
+
const batch = result.rows.slice(i, i + batchSize);
|
|
152
|
+
const stmts = batch.map((row) => {
|
|
153
|
+
const embedding = new Float32Array(row.embedding);
|
|
154
|
+
const hitl = computeHitlScore(embedding, mlConfig);
|
|
155
|
+
const vibe = computeVibeIndex(embedding, mlConfig);
|
|
156
|
+
const pol = computePoliteness(embedding, mlConfig);
|
|
157
|
+
return {
|
|
158
|
+
sql: `UPDATE nlp_enrichments SET
|
|
159
|
+
hitl_score = ?, hitl_confidence = ?,
|
|
160
|
+
vibe_score = ?, vibe_confidence = ?,
|
|
161
|
+
politeness_score = ?, politeness_confidence = ?
|
|
162
|
+
WHERE message_id = ?`,
|
|
163
|
+
args: [
|
|
164
|
+
hitl.score, hitl.confidence,
|
|
165
|
+
vibe.score, vibe.confidence,
|
|
166
|
+
pol.score, pol.confidence,
|
|
167
|
+
Number(row.id),
|
|
168
|
+
],
|
|
169
|
+
};
|
|
170
|
+
});
|
|
171
|
+
await client.batch(stmts, "write");
|
|
172
|
+
classified += batch.length;
|
|
173
|
+
onBatchProgress?.(classified, result.rows.length);
|
|
174
|
+
}
|
|
175
|
+
return classified;
|
|
176
|
+
}
|
|
177
|
+
function round(n, decimals) {
|
|
178
|
+
const f = 10 ** decimals;
|
|
179
|
+
return Math.round(n * f) / f;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=classifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifiers.js","sourceRoot":"","sources":["../../src/pipeline/classifiers.ts"],"names":[],"mappings":"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"}
|