@nxuss/lemma 0.2.1 → 0.3.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 +50 -5
- package/dist/cjs/api/dashboardRoutes.d.ts +28 -0
- package/dist/cjs/api/dashboardRoutes.d.ts.map +1 -0
- package/dist/cjs/api/dashboardRoutes.js +239 -0
- package/dist/cjs/api/dashboardRoutes.js.map +1 -0
- package/dist/cjs/api/server.d.ts +51 -0
- package/dist/cjs/api/server.d.ts.map +1 -0
- package/dist/cjs/api/server.js +166 -0
- package/dist/cjs/api/server.js.map +1 -0
- package/dist/cjs/core/AgentRegistry.d.ts +4 -0
- package/dist/cjs/core/AgentRegistry.d.ts.map +1 -1
- package/dist/cjs/core/AgentRegistry.js +6 -0
- package/dist/cjs/core/AgentRegistry.js.map +1 -1
- package/dist/cjs/core/DashboardWebSocketServer.d.ts +70 -0
- package/dist/cjs/core/DashboardWebSocketServer.d.ts.map +1 -0
- package/dist/cjs/core/DashboardWebSocketServer.js +211 -0
- package/dist/cjs/core/DashboardWebSocketServer.js.map +1 -0
- package/dist/cjs/core/OrchestrationEngine.d.ts +22 -0
- package/dist/cjs/core/OrchestrationEngine.d.ts.map +1 -1
- package/dist/cjs/core/OrchestrationEngine.js +98 -0
- package/dist/cjs/core/OrchestrationEngine.js.map +1 -1
- package/dist/cjs/core/SubconsciousEngine.d.ts +24 -0
- package/dist/cjs/core/SubconsciousEngine.d.ts.map +1 -1
- package/dist/cjs/core/SubconsciousEngine.js +110 -0
- package/dist/cjs/core/SubconsciousEngine.js.map +1 -1
- package/dist/cjs/core/WebSocketServer.d.ts.map +1 -1
- package/dist/cjs/core/WebSocketServer.js +4 -0
- package/dist/cjs/core/WebSocketServer.js.map +1 -1
- package/dist/cjs/db/database.d.ts +60 -0
- package/dist/cjs/db/database.d.ts.map +1 -0
- package/dist/cjs/db/database.js +297 -0
- package/dist/cjs/db/database.js.map +1 -0
- package/dist/cjs/db/migrations/001-dashboard-schema.d.ts +18 -0
- package/dist/cjs/db/migrations/001-dashboard-schema.d.ts.map +1 -0
- package/dist/cjs/db/migrations/001-dashboard-schema.js +175 -0
- package/dist/cjs/db/migrations/001-dashboard-schema.js.map +1 -0
- package/dist/cjs/embed/index.d.ts +1 -1
- package/dist/cjs/embed/index.d.ts.map +1 -1
- package/dist/cjs/embed/index.js +17 -9
- package/dist/cjs/embed/index.js.map +1 -1
- package/dist/cjs/proxy/Gatekeeper.d.ts +43 -0
- package/dist/cjs/proxy/Gatekeeper.d.ts.map +1 -0
- package/dist/cjs/proxy/Gatekeeper.js +202 -0
- package/dist/cjs/proxy/Gatekeeper.js.map +1 -0
- package/dist/cjs/proxy/KeyManager.d.ts +56 -0
- package/dist/cjs/proxy/KeyManager.d.ts.map +1 -0
- package/dist/cjs/proxy/KeyManager.js +220 -0
- package/dist/cjs/proxy/KeyManager.js.map +1 -0
- package/dist/cjs/proxy/ProjectStore.d.ts +84 -0
- package/dist/cjs/proxy/ProjectStore.d.ts.map +1 -0
- package/dist/cjs/proxy/ProjectStore.js +214 -0
- package/dist/cjs/proxy/ProjectStore.js.map +1 -0
- package/dist/cjs/proxy/SseRelay.d.ts +41 -0
- package/dist/cjs/proxy/SseRelay.d.ts.map +1 -0
- package/dist/cjs/proxy/SseRelay.js +176 -0
- package/dist/cjs/proxy/SseRelay.js.map +1 -0
- package/dist/esm/api/dashboardRoutes.d.ts +28 -0
- package/dist/esm/api/dashboardRoutes.d.ts.map +1 -0
- package/dist/esm/api/dashboardRoutes.js +236 -0
- package/dist/esm/api/dashboardRoutes.js.map +1 -0
- package/dist/esm/api/server.d.ts +51 -0
- package/dist/esm/api/server.d.ts.map +1 -0
- package/dist/esm/api/server.js +159 -0
- package/dist/esm/api/server.js.map +1 -0
- package/dist/esm/core/AgentRegistry.d.ts +4 -0
- package/dist/esm/core/AgentRegistry.d.ts.map +1 -1
- package/dist/esm/core/AgentRegistry.js +6 -0
- package/dist/esm/core/AgentRegistry.js.map +1 -1
- package/dist/esm/core/DashboardWebSocketServer.d.ts +70 -0
- package/dist/esm/core/DashboardWebSocketServer.d.ts.map +1 -0
- package/dist/esm/core/DashboardWebSocketServer.js +207 -0
- package/dist/esm/core/DashboardWebSocketServer.js.map +1 -0
- package/dist/esm/core/OrchestrationEngine.d.ts +22 -0
- package/dist/esm/core/OrchestrationEngine.d.ts.map +1 -1
- package/dist/esm/core/OrchestrationEngine.js +98 -0
- package/dist/esm/core/OrchestrationEngine.js.map +1 -1
- package/dist/esm/core/SubconsciousEngine.d.ts +24 -0
- package/dist/esm/core/SubconsciousEngine.d.ts.map +1 -1
- package/dist/esm/core/SubconsciousEngine.js +110 -0
- package/dist/esm/core/SubconsciousEngine.js.map +1 -1
- package/dist/esm/core/WebSocketServer.d.ts.map +1 -1
- package/dist/esm/core/WebSocketServer.js +4 -0
- package/dist/esm/core/WebSocketServer.js.map +1 -1
- package/dist/esm/db/database.d.ts +60 -0
- package/dist/esm/db/database.d.ts.map +1 -0
- package/dist/esm/db/database.js +293 -0
- package/dist/esm/db/database.js.map +1 -0
- package/dist/esm/db/migrations/001-dashboard-schema.d.ts +18 -0
- package/dist/esm/db/migrations/001-dashboard-schema.d.ts.map +1 -0
- package/dist/esm/db/migrations/001-dashboard-schema.js +172 -0
- package/dist/esm/db/migrations/001-dashboard-schema.js.map +1 -0
- package/dist/esm/embed/index.d.ts +1 -1
- package/dist/esm/embed/index.d.ts.map +1 -1
- package/dist/esm/embed/index.js +17 -9
- package/dist/esm/embed/index.js.map +1 -1
- package/dist/esm/proxy/Gatekeeper.d.ts +43 -0
- package/dist/esm/proxy/Gatekeeper.d.ts.map +1 -0
- package/dist/esm/proxy/Gatekeeper.js +165 -0
- package/dist/esm/proxy/Gatekeeper.js.map +1 -0
- package/dist/esm/proxy/KeyManager.d.ts +56 -0
- package/dist/esm/proxy/KeyManager.d.ts.map +1 -0
- package/dist/esm/proxy/KeyManager.js +213 -0
- package/dist/esm/proxy/KeyManager.js.map +1 -0
- package/dist/esm/proxy/ProjectStore.d.ts +84 -0
- package/dist/esm/proxy/ProjectStore.d.ts.map +1 -0
- package/dist/esm/proxy/ProjectStore.js +207 -0
- package/dist/esm/proxy/ProjectStore.js.map +1 -0
- package/dist/esm/proxy/SseRelay.d.ts +41 -0
- package/dist/esm/proxy/SseRelay.d.ts.map +1 -0
- package/dist/esm/proxy/SseRelay.js +169 -0
- package/dist/esm/proxy/SseRelay.js.map +1 -0
- package/lemma-proxy.js +810 -0
- package/package.json +17 -3
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lemma Gatekeeper
|
|
4
|
+
*
|
|
5
|
+
* Picks the correct cache backend per request based on license tier:
|
|
6
|
+
* Standard (Free) → InMemoryExactBackend (exact-match, no embeddings)
|
|
7
|
+
* Pro (Paid) → SemanticBackendAdapter (vector similarity)
|
|
8
|
+
*
|
|
9
|
+
* Backend is evaluated per-request so activate takes effect immediately.
|
|
10
|
+
* Emits 'mode-changed' when the effective tier switches.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.Gatekeeper = void 0;
|
|
47
|
+
const events_1 = require("events");
|
|
48
|
+
class Gatekeeper extends events_1.EventEmitter {
|
|
49
|
+
constructor(keyManager) {
|
|
50
|
+
super();
|
|
51
|
+
this.lastMode = null;
|
|
52
|
+
this.memBackend = null;
|
|
53
|
+
this.semBackend = null;
|
|
54
|
+
this.semInitialized = false;
|
|
55
|
+
this.keyManager = keyManager;
|
|
56
|
+
}
|
|
57
|
+
async getBackend() {
|
|
58
|
+
const mode = this.getMode();
|
|
59
|
+
if (mode !== this.lastMode) {
|
|
60
|
+
const prev = this.lastMode;
|
|
61
|
+
this.lastMode = mode;
|
|
62
|
+
if (prev !== null) {
|
|
63
|
+
this.emit('mode-changed', { from: prev, to: mode });
|
|
64
|
+
console.log(`[Gatekeeper] Mode: ${prev} → ${mode}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return mode === 'pro' ? this.getSemanticBackend() : this.getMemoryBackend();
|
|
68
|
+
}
|
|
69
|
+
getMode() {
|
|
70
|
+
return this.keyManager.isPro() ? 'pro' : 'standard';
|
|
71
|
+
}
|
|
72
|
+
getStatus() {
|
|
73
|
+
const mode = this.getMode();
|
|
74
|
+
return { mode, semanticEnabled: mode === 'pro', isPro: mode === 'pro', licenseKey: this.keyManager.getLicenseKey() };
|
|
75
|
+
}
|
|
76
|
+
reload() {
|
|
77
|
+
this.keyManager.reload();
|
|
78
|
+
}
|
|
79
|
+
getMemoryBackend() {
|
|
80
|
+
if (!this.memBackend)
|
|
81
|
+
this.memBackend = new InMemoryExactBackend();
|
|
82
|
+
return this.memBackend;
|
|
83
|
+
}
|
|
84
|
+
async getSemanticBackend() {
|
|
85
|
+
if (!this.semBackend)
|
|
86
|
+
this.semBackend = new SemanticBackendAdapter();
|
|
87
|
+
if (!this.semInitialized) {
|
|
88
|
+
try {
|
|
89
|
+
await this.semBackend.initialize();
|
|
90
|
+
this.semInitialized = true;
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.warn(`[Gatekeeper] Semantic backend unavailable: ${err.message}`);
|
|
94
|
+
console.warn(`[Gatekeeper] Install @xenova/transformers for Pro semantic mode.`);
|
|
95
|
+
this.semBackend = this.getMemoryBackend();
|
|
96
|
+
this.semInitialized = true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return this.semBackend;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.Gatekeeper = Gatekeeper;
|
|
103
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
104
|
+
function norm(s) { return s.toLowerCase().replace(/\s+/g, ' ').trim(); }
|
|
105
|
+
class InMemoryExactBackend {
|
|
106
|
+
constructor() {
|
|
107
|
+
this.store = new Map();
|
|
108
|
+
this.maxSize = 10000;
|
|
109
|
+
}
|
|
110
|
+
async set(key, input, data, ttl) {
|
|
111
|
+
if (this.store.size >= this.maxSize) {
|
|
112
|
+
const k = this.store.keys().next().value;
|
|
113
|
+
if (k)
|
|
114
|
+
this.store.delete(k);
|
|
115
|
+
}
|
|
116
|
+
this.store.set(key, { key, input, data, createdAt: Date.now(), ttl });
|
|
117
|
+
}
|
|
118
|
+
async findSimilar(input, _threshold) {
|
|
119
|
+
const n = norm(input);
|
|
120
|
+
for (const e of this.store.values()) {
|
|
121
|
+
if (e.ttl > 0 && Date.now() - e.createdAt > e.ttl) {
|
|
122
|
+
this.store.delete(e.key);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (norm(e.input) === n)
|
|
126
|
+
return { data: e.data, similarity: 1.0 };
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
size() { return this.store.size; }
|
|
131
|
+
clear() { this.store.clear(); }
|
|
132
|
+
}
|
|
133
|
+
class SemanticBackendAdapter {
|
|
134
|
+
constructor() {
|
|
135
|
+
this.store = new Map();
|
|
136
|
+
this.pipeline = null;
|
|
137
|
+
this.embCache = new Map();
|
|
138
|
+
this.maxSize = 10000;
|
|
139
|
+
}
|
|
140
|
+
async initialize() {
|
|
141
|
+
if (this.pipeline)
|
|
142
|
+
return;
|
|
143
|
+
// @ts-ignore optional dependency
|
|
144
|
+
const { pipeline } = await Promise.resolve().then(() => __importStar(require('@xenova/transformers')));
|
|
145
|
+
this.pipeline = await pipeline('feature-extraction', 'Xenova/all-MiniLM-L6-v2');
|
|
146
|
+
}
|
|
147
|
+
async set(key, input, data, ttl) {
|
|
148
|
+
if (this.store.size >= this.maxSize) {
|
|
149
|
+
const k = this.store.keys().next().value;
|
|
150
|
+
if (k)
|
|
151
|
+
this.store.delete(k);
|
|
152
|
+
}
|
|
153
|
+
const embedding = await this.embed(input);
|
|
154
|
+
this.store.set(key, { key, input, embedding, data, createdAt: Date.now(), ttl });
|
|
155
|
+
}
|
|
156
|
+
async findSimilar(input, threshold) {
|
|
157
|
+
if (this.store.size === 0)
|
|
158
|
+
return null;
|
|
159
|
+
const q = await this.embed(input);
|
|
160
|
+
let best = null;
|
|
161
|
+
let bestScore = -1;
|
|
162
|
+
for (const e of this.store.values()) {
|
|
163
|
+
if (e.ttl > 0 && Date.now() - e.createdAt > e.ttl) {
|
|
164
|
+
this.store.delete(e.key);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const sim = cosine(q, e.embedding);
|
|
168
|
+
if (sim > bestScore && sim >= threshold) {
|
|
169
|
+
bestScore = sim;
|
|
170
|
+
best = { data: e.data, similarity: sim };
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return best;
|
|
174
|
+
}
|
|
175
|
+
async embed(text) {
|
|
176
|
+
const k = text.toLowerCase().trim();
|
|
177
|
+
if (this.embCache.has(k))
|
|
178
|
+
return this.embCache.get(k);
|
|
179
|
+
const out = await this.pipeline(text, { pooling: 'mean', normalize: true });
|
|
180
|
+
const vec = Array.from(out.data);
|
|
181
|
+
this.embCache.set(k, vec);
|
|
182
|
+
if (this.embCache.size > this.maxSize) {
|
|
183
|
+
const f = this.embCache.keys().next().value;
|
|
184
|
+
if (f)
|
|
185
|
+
this.embCache.delete(f);
|
|
186
|
+
}
|
|
187
|
+
return vec;
|
|
188
|
+
}
|
|
189
|
+
size() { return this.store.size; }
|
|
190
|
+
clear() { this.store.clear(); this.embCache.clear(); }
|
|
191
|
+
}
|
|
192
|
+
function cosine(a, b) {
|
|
193
|
+
let dot = 0, na = 0, nb = 0;
|
|
194
|
+
for (let i = 0; i < a.length; i++) {
|
|
195
|
+
dot += a[i] * b[i];
|
|
196
|
+
na += a[i] * a[i];
|
|
197
|
+
nb += b[i] * b[i];
|
|
198
|
+
}
|
|
199
|
+
const d = Math.sqrt(na) * Math.sqrt(nb);
|
|
200
|
+
return d === 0 ? 0 : dot / d;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=Gatekeeper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gatekeeper.js","sourceRoot":"","sources":["../../../src/proxy/Gatekeeper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lemma KeyManager
|
|
3
|
+
*
|
|
4
|
+
* Handles Pro license key lifecycle:
|
|
5
|
+
* - Activation via remote validation (https://lemma.nxus.studio/api/v1/validate)
|
|
6
|
+
* - Graceful fallback to local format check when endpoint is unreachable
|
|
7
|
+
* - Persistence to ~/.lemma-cache/license.json
|
|
8
|
+
* - Auto-migration from legacy license.key format
|
|
9
|
+
*
|
|
10
|
+
* TODO(v0.4.0): Replace HTTP validate call with direct PostgreSQL check.
|
|
11
|
+
*/
|
|
12
|
+
export interface LicenseData {
|
|
13
|
+
key: string;
|
|
14
|
+
tier: 'pro' | 'free';
|
|
15
|
+
isPro: boolean;
|
|
16
|
+
activatedAt: string;
|
|
17
|
+
expiresAt?: string;
|
|
18
|
+
validatedRemotely: boolean;
|
|
19
|
+
email?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ActivationResult {
|
|
22
|
+
success: boolean;
|
|
23
|
+
isPro: boolean;
|
|
24
|
+
message: string;
|
|
25
|
+
license?: LicenseData;
|
|
26
|
+
validatedRemotely: boolean;
|
|
27
|
+
}
|
|
28
|
+
export declare class KeyManager {
|
|
29
|
+
private license;
|
|
30
|
+
constructor();
|
|
31
|
+
isPro(): boolean;
|
|
32
|
+
getLicenseKey(): string | null;
|
|
33
|
+
getLicense(): LicenseData | null;
|
|
34
|
+
/**
|
|
35
|
+
* Activate a license key.
|
|
36
|
+
* Attempts remote validation first; falls back to format-check if unreachable.
|
|
37
|
+
*/
|
|
38
|
+
activate(key: string): Promise<ActivationResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Deactivate / remove the current license.
|
|
41
|
+
*/
|
|
42
|
+
deactivate(): void;
|
|
43
|
+
/**
|
|
44
|
+
* Reload license from disk (used after activate from another process).
|
|
45
|
+
*/
|
|
46
|
+
reload(): void;
|
|
47
|
+
private load;
|
|
48
|
+
private save;
|
|
49
|
+
private ensureCacheDir;
|
|
50
|
+
/**
|
|
51
|
+
* POST to https://lemma.nxus.studio/api/v1/validate with a timeout.
|
|
52
|
+
* Returns the JSON response body.
|
|
53
|
+
*/
|
|
54
|
+
private validateRemote;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=KeyManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyManager.d.ts","sourceRoot":"","sources":["../../../src/proxy/KeyManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAID,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAA4B;;IAS3C,KAAK,IAAI,OAAO;IAYhB,aAAa,IAAI,MAAM,GAAG,IAAI;IAI9B,UAAU,IAAI,WAAW,GAAG,IAAI;IAIhC;;;OAGG;IACG,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0DtD;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd,OAAO,CAAC,IAAI;IAoCZ,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACH,OAAO,CAAC,cAAc;CAyCvB"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lemma KeyManager
|
|
4
|
+
*
|
|
5
|
+
* Handles Pro license key lifecycle:
|
|
6
|
+
* - Activation via remote validation (https://lemma.nxus.studio/api/v1/validate)
|
|
7
|
+
* - Graceful fallback to local format check when endpoint is unreachable
|
|
8
|
+
* - Persistence to ~/.lemma-cache/license.json
|
|
9
|
+
* - Auto-migration from legacy license.key format
|
|
10
|
+
*
|
|
11
|
+
* TODO(v0.4.0): Replace HTTP validate call with direct PostgreSQL check.
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.KeyManager = void 0;
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const https_1 = __importDefault(require("https"));
|
|
21
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
22
|
+
const CACHE_DIR = path_1.default.join(process.env.HOME || process.env.USERPROFILE || '~', '.lemma-cache');
|
|
23
|
+
const LICENSE_FILE = path_1.default.join(CACHE_DIR, 'license.json');
|
|
24
|
+
const LEGACY_LICENSE_FILE = path_1.default.join(CACHE_DIR, 'license.key');
|
|
25
|
+
const VALIDATE_URL = 'https://lemma.nxus.studio/api/v1/validate';
|
|
26
|
+
const VALIDATE_TIMEOUT_MS = 5000;
|
|
27
|
+
const KEY_FORMAT_REGEX = /^LEMMA-PRO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/;
|
|
28
|
+
// ─── KeyManager ───────────────────────────────────────────────────────────────
|
|
29
|
+
class KeyManager {
|
|
30
|
+
constructor() {
|
|
31
|
+
this.license = null;
|
|
32
|
+
this.ensureCacheDir();
|
|
33
|
+
this.license = this.load();
|
|
34
|
+
}
|
|
35
|
+
// ── Public API ──────────────────────────────────────────────────────────────
|
|
36
|
+
isPro() {
|
|
37
|
+
if (!this.license)
|
|
38
|
+
return false;
|
|
39
|
+
if (!this.license.isPro)
|
|
40
|
+
return false;
|
|
41
|
+
// Check expiry if set
|
|
42
|
+
if (this.license.expiresAt) {
|
|
43
|
+
if (Date.now() > new Date(this.license.expiresAt).getTime()) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
getLicenseKey() {
|
|
50
|
+
return this.license?.key || null;
|
|
51
|
+
}
|
|
52
|
+
getLicense() {
|
|
53
|
+
return this.license;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Activate a license key.
|
|
57
|
+
* Attempts remote validation first; falls back to format-check if unreachable.
|
|
58
|
+
*/
|
|
59
|
+
async activate(key) {
|
|
60
|
+
// Basic format validation first
|
|
61
|
+
if (!KEY_FORMAT_REGEX.test(key.trim())) {
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
isPro: false,
|
|
65
|
+
validatedRemotely: false,
|
|
66
|
+
message: `Invalid key format. Pro keys look like: LEMMA-PRO-XXXX-XXXX-XXXX`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Attempt remote validation
|
|
70
|
+
let validatedRemotely = false;
|
|
71
|
+
let remoteData = null;
|
|
72
|
+
try {
|
|
73
|
+
remoteData = await this.validateRemote(key.trim());
|
|
74
|
+
validatedRemotely = true;
|
|
75
|
+
if (!remoteData.valid) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
isPro: false,
|
|
79
|
+
validatedRemotely: true,
|
|
80
|
+
message: remoteData.reason || 'License key is not valid.',
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
// Network/endpoint unavailable — fall back to local format check
|
|
86
|
+
console.warn(`[KeyManager] Remote validation unavailable: ${err.message}`);
|
|
87
|
+
console.warn(`[KeyManager] Falling back to local format validation.`);
|
|
88
|
+
}
|
|
89
|
+
// Build and persist license
|
|
90
|
+
const license = {
|
|
91
|
+
key: key.trim(),
|
|
92
|
+
tier: 'pro',
|
|
93
|
+
isPro: true,
|
|
94
|
+
activatedAt: new Date().toISOString(),
|
|
95
|
+
validatedRemotely,
|
|
96
|
+
expiresAt: remoteData?.expiresAt,
|
|
97
|
+
email: remoteData?.email,
|
|
98
|
+
};
|
|
99
|
+
this.license = license;
|
|
100
|
+
this.save(license);
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
isPro: true,
|
|
104
|
+
validatedRemotely,
|
|
105
|
+
message: validatedRemotely
|
|
106
|
+
? `✅ Lemma Pro activated (server-verified). Semantic Mode enabled.`
|
|
107
|
+
: `✅ Lemma Pro activated (format-validated, server offline). Semantic Mode enabled.`,
|
|
108
|
+
license,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Deactivate / remove the current license.
|
|
113
|
+
*/
|
|
114
|
+
deactivate() {
|
|
115
|
+
this.license = null;
|
|
116
|
+
if (fs_1.default.existsSync(LICENSE_FILE)) {
|
|
117
|
+
fs_1.default.unlinkSync(LICENSE_FILE);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Reload license from disk (used after activate from another process).
|
|
122
|
+
*/
|
|
123
|
+
reload() {
|
|
124
|
+
this.license = this.load();
|
|
125
|
+
}
|
|
126
|
+
// ── Private helpers ─────────────────────────────────────────────────────────
|
|
127
|
+
load() {
|
|
128
|
+
// Try new JSON format
|
|
129
|
+
if (fs_1.default.existsSync(LICENSE_FILE)) {
|
|
130
|
+
try {
|
|
131
|
+
const data = JSON.parse(fs_1.default.readFileSync(LICENSE_FILE, 'utf8'));
|
|
132
|
+
if (data.key && data.isPro)
|
|
133
|
+
return data;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Corrupt file — ignore
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// Migrate from legacy format
|
|
140
|
+
if (fs_1.default.existsSync(LEGACY_LICENSE_FILE)) {
|
|
141
|
+
try {
|
|
142
|
+
const legacy = JSON.parse(fs_1.default.readFileSync(LEGACY_LICENSE_FILE, 'utf8'));
|
|
143
|
+
if (legacy.key && (legacy.isPro || legacy.tier === 'pro')) {
|
|
144
|
+
const migrated = {
|
|
145
|
+
key: legacy.key,
|
|
146
|
+
tier: 'pro',
|
|
147
|
+
isPro: true,
|
|
148
|
+
activatedAt: legacy.activatedAt || new Date().toISOString(),
|
|
149
|
+
validatedRemotely: false,
|
|
150
|
+
};
|
|
151
|
+
this.save(migrated);
|
|
152
|
+
fs_1.default.unlinkSync(LEGACY_LICENSE_FILE); // Remove legacy file
|
|
153
|
+
console.log('[KeyManager] Migrated license from legacy format.');
|
|
154
|
+
return migrated;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Ignore
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
save(license) {
|
|
164
|
+
try {
|
|
165
|
+
this.ensureCacheDir();
|
|
166
|
+
fs_1.default.writeFileSync(LICENSE_FILE, JSON.stringify(license, null, 2));
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
console.error(`[KeyManager] Failed to save license: ${err.message}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
ensureCacheDir() {
|
|
173
|
+
if (!fs_1.default.existsSync(CACHE_DIR)) {
|
|
174
|
+
fs_1.default.mkdirSync(CACHE_DIR, { recursive: true });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* POST to https://lemma.nxus.studio/api/v1/validate with a timeout.
|
|
179
|
+
* Returns the JSON response body.
|
|
180
|
+
*/
|
|
181
|
+
validateRemote(key) {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
const body = JSON.stringify({ key });
|
|
184
|
+
const url = new URL(VALIDATE_URL);
|
|
185
|
+
const options = {
|
|
186
|
+
hostname: url.hostname,
|
|
187
|
+
port: url.port || 443,
|
|
188
|
+
path: url.pathname,
|
|
189
|
+
method: 'POST',
|
|
190
|
+
headers: {
|
|
191
|
+
'Content-Type': 'application/json',
|
|
192
|
+
'Content-Length': Buffer.byteLength(body),
|
|
193
|
+
'User-Agent': 'lemma-proxy/0.3.0',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
const req = https_1.default.request(options, (res) => {
|
|
197
|
+
let data = '';
|
|
198
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
199
|
+
res.on('end', () => {
|
|
200
|
+
try {
|
|
201
|
+
resolve(JSON.parse(data));
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
reject(new Error(`Invalid JSON response from validate endpoint`));
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
req.on('error', reject);
|
|
209
|
+
const timer = setTimeout(() => {
|
|
210
|
+
req.destroy();
|
|
211
|
+
reject(new Error(`Validation endpoint timed out after ${VALIDATE_TIMEOUT_MS}ms`));
|
|
212
|
+
}, VALIDATE_TIMEOUT_MS);
|
|
213
|
+
req.on('close', () => clearTimeout(timer));
|
|
214
|
+
req.write(body);
|
|
215
|
+
req.end();
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.KeyManager = KeyManager;
|
|
220
|
+
//# sourceMappingURL=KeyManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyManager.js","sourceRoot":"","sources":["../../../src/proxy/KeyManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lemma ProjectStore
|
|
3
|
+
*
|
|
4
|
+
* Project-aware storage resolver:
|
|
5
|
+
* - Detects project identity from package.json → cwd basename fallback
|
|
6
|
+
* - Hashes project name to a 12-char hex prefix for path safety
|
|
7
|
+
* - Provides Stats and Usage persistence helpers
|
|
8
|
+
*
|
|
9
|
+
* Layout:
|
|
10
|
+
* ~/.lemma-cache/
|
|
11
|
+
* proxy.pid
|
|
12
|
+
* proxy.port
|
|
13
|
+
* stats.json (global, cross-project)
|
|
14
|
+
* usage.json (global free-tier counter)
|
|
15
|
+
* license.json (KeyManager)
|
|
16
|
+
* <12-char hash>/ (per-project)
|
|
17
|
+
* cache.db (future SQLite)
|
|
18
|
+
* project-stats.json
|
|
19
|
+
*/
|
|
20
|
+
export declare const CACHE_DIR: string;
|
|
21
|
+
export declare const PID_FILE: string;
|
|
22
|
+
export declare const PORT_FILE: string;
|
|
23
|
+
export declare const STATS_FILE: string;
|
|
24
|
+
export declare const USAGE_FILE: string;
|
|
25
|
+
export declare const FREE_TIER_LIMIT = 300;
|
|
26
|
+
export declare const WARNING_THRESHOLD = 0.8;
|
|
27
|
+
export interface ProjectInfo {
|
|
28
|
+
name: string;
|
|
29
|
+
hash: string;
|
|
30
|
+
cacheDir: string;
|
|
31
|
+
dbFile: string;
|
|
32
|
+
statsFile: string;
|
|
33
|
+
}
|
|
34
|
+
export interface ProjectStats {
|
|
35
|
+
total: number;
|
|
36
|
+
hits: number;
|
|
37
|
+
misses: number;
|
|
38
|
+
totalLatency: number;
|
|
39
|
+
totalTokensSaved: number;
|
|
40
|
+
providers: Record<string, {
|
|
41
|
+
hits: number;
|
|
42
|
+
misses: number;
|
|
43
|
+
}>;
|
|
44
|
+
}
|
|
45
|
+
export interface UsageRecord {
|
|
46
|
+
count: number;
|
|
47
|
+
lastReset: string;
|
|
48
|
+
history: Array<{
|
|
49
|
+
month: string;
|
|
50
|
+
count: number;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
export declare class ProjectStore {
|
|
54
|
+
private project;
|
|
55
|
+
private stats;
|
|
56
|
+
private usage;
|
|
57
|
+
constructor(overrideName?: string);
|
|
58
|
+
getProject(): ProjectInfo;
|
|
59
|
+
private resolveProject;
|
|
60
|
+
private detectProjectName;
|
|
61
|
+
getStats(): Record<string, ProjectStats>;
|
|
62
|
+
getProjectStats(): ProjectStats;
|
|
63
|
+
recordRequest(opts: {
|
|
64
|
+
fromCache: boolean;
|
|
65
|
+
latencyMs: number;
|
|
66
|
+
provider: string;
|
|
67
|
+
tokensSaved?: number;
|
|
68
|
+
}): void;
|
|
69
|
+
private emptyProjectStats;
|
|
70
|
+
private loadStats;
|
|
71
|
+
saveStats(): void;
|
|
72
|
+
getUsage(): UsageRecord;
|
|
73
|
+
incrementUsage(): void;
|
|
74
|
+
checkUsageLimit(): {
|
|
75
|
+
allowed: boolean;
|
|
76
|
+
warning?: string;
|
|
77
|
+
remaining: number;
|
|
78
|
+
};
|
|
79
|
+
getNextResetDate(): string;
|
|
80
|
+
private loadUsage;
|
|
81
|
+
saveUsage(override?: UsageRecord): void;
|
|
82
|
+
private ensureCacheDir;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=ProjectStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProjectStore.d.ts","sourceRoot":"","sources":["../../../src/proxy/ProjectStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AASH,eAAO,MAAM,SAAS,QAAkC,CAAC;AACzD,eAAO,MAAM,QAAQ,QAAoC,CAAC;AAC1D,eAAO,MAAM,SAAS,QAAqC,CAAC;AAC5D,eAAO,MAAM,UAAU,QAAqC,CAAC;AAC7D,eAAO,MAAM,UAAU,QAAqC,CAAC;AAE7D,eAAO,MAAM,eAAe,MAAM,CAAC;AACnC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAIrC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAID,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,KAAK,CAAc;gBAEf,YAAY,CAAC,EAAE,MAAM;IASjC,UAAU,IAAI,WAAW;IAIzB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,iBAAiB;IAkBzB,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;IAIxC,eAAe,IAAI,YAAY;IAI/B,aAAa,CAAC,IAAI,EAAE;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,IAAI;IA4BR,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,SAAS;IAWjB,SAAS,IAAI,IAAI;IAUjB,QAAQ,IAAI,WAAW;IAIvB,cAAc,IAAI,IAAI;IAUtB,eAAe,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAuB5E,gBAAgB,IAAI,MAAM;IAK1B,OAAO,CAAC,SAAS;IAwBjB,SAAS,CAAC,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI;IAUvC,OAAO,CAAC,cAAc;CAKvB"}
|