vektor-slipstream 1.0.0 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vektor-slipstream",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Hardware-accelerated persistent memory for AI agents. Local-first, zero cloud dependency, $0 embedding cost.",
5
5
  "main": "slipstream-core.js",
6
6
  "exports": {
@@ -9,9 +9,21 @@
9
9
  "./embedder": "./slipstream-embedder.js"
10
10
  },
11
11
  "keywords": [
12
- "ai", "memory", "agent", "vector", "sqlite", "embeddings",
13
- "langchain", "openai", "anthropic", "claude", "mcp",
14
- "rag", "persistent-memory", "local-ai", "onnx"
12
+ "ai",
13
+ "memory",
14
+ "agent",
15
+ "vector",
16
+ "sqlite",
17
+ "embeddings",
18
+ "langchain",
19
+ "openai",
20
+ "anthropic",
21
+ "claude",
22
+ "mcp",
23
+ "rag",
24
+ "persistent-memory",
25
+ "local-ai",
26
+ "onnx"
15
27
  ],
16
28
  "author": "VEKTOR Memory <hello@vektormemory.com>",
17
29
  "license": "SEE LICENSE IN LICENSE",
@@ -28,15 +40,16 @@
28
40
  "onnxruntime-node": "^1.17.3"
29
41
  },
30
42
  "optionalDependencies": {
31
- "sqlite-vec-windows-x64": "^0.1.6",
32
43
  "sqlite-vec-darwin-arm64": "^0.1.6",
33
- "sqlite-vec-linux-x64": "^0.1.6"
44
+ "sqlite-vec-linux-x64": "^0.1.6",
45
+ "sqlite-vec-windows-x64": "^0.1.6"
34
46
  },
35
47
  "files": [
36
48
  "slipstream-core.js",
37
49
  "slipstream-db.js",
38
50
  "slipstream-embedder.js",
39
51
  "detect-hardware.js",
52
+ "vektor-licence.js",
40
53
  "models/model_quantized.onnx",
41
54
  "examples/",
42
55
  "README.md",
@@ -18,6 +18,7 @@
18
18
  const { initSlipstreamDB, getDBStats } = require('./slipstream-db');
19
19
  const { SlipstreamEmbedder } = require('./slipstream-embedder');
20
20
  const { getEPLabel } = require('./detect-hardware');
21
+ const { validateLicence } = require('./vektor-licence');
21
22
 
22
23
  // ─── Boot Banner ──────────────────────────────────────────────────────────────
23
24
 
@@ -305,11 +306,15 @@ async function createMemory(options = {}) {
305
306
  const bootStart = Date.now();
306
307
 
307
308
  const {
308
- agentId = 'default',
309
- dbPath = './slipstream-memory.db',
310
- silent = false,
309
+ agentId = 'default',
310
+ dbPath = './slipstream-memory.db',
311
+ silent = false,
312
+ licenceKey = process.env.VEKTOR_LICENCE_KEY || '',
311
313
  } = options;
312
314
 
315
+ // 0. Validate Polar licence key
316
+ await validateLicence(licenceKey);
317
+
313
318
  // 1. Init embedder (hardware probe + ONNX load + pre-warmer)
314
319
  const embedder = new SlipstreamEmbedder();
315
320
  await embedder.init();
@@ -0,0 +1,191 @@
1
+ 'use strict';
2
+ /**
3
+ * vektor-licence.js — Polar Licence Enforcement
4
+ * ─────────────────────────────────────────────────────────────────────────────
5
+ * Validates a Polar licence key before allowing createMemory() to proceed.
6
+ *
7
+ * Flow:
8
+ * 1. Customer calls createMemory({ licenceKey: 'VEKTOR-XXXX-...' })
9
+ * 2. We check ~/.vektor/licence.json for a cached validation (30-day TTL)
10
+ * 3. If cache miss or expired → call Polar validate API
11
+ * 4. Valid → cache result, proceed
12
+ * 5. Invalid/missing → throw with purchase link
13
+ *
14
+ * Polar validate endpoint requires no auth token — safe for client-side use.
15
+ * ─────────────────────────────────────────────────────────────────────────────
16
+ */
17
+
18
+ const fs = require('fs');
19
+ const path = require('path');
20
+ const os = require('os');
21
+ const crypto = require('crypto');
22
+
23
+ // ── Config ────────────────────────────────────────────────────────────────────
24
+ // Replace POLAR_ORG_ID with your actual Polar organisation ID from
25
+ // polar.sh → Settings → Organisation ID
26
+
27
+ const POLAR_ORG_ID = 'a922049c-3049-41e8-9b20-b18890576b6f';
28
+ const POLAR_API = 'https://api.polar.sh/v1/customer-portal/license-keys/validate';
29
+ const CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
30
+ const CACHE_DIR = path.join(os.homedir(), '.vektor');
31
+ const CACHE_FILE = path.join(CACHE_DIR, 'licence.json');
32
+ const PURCHASE_URL = 'https://vektormemory.com/#pricing';
33
+
34
+ // ── Cache helpers ─────────────────────────────────────────────────────────────
35
+
36
+ function _cacheKey(licenceKey) {
37
+ // Hash the key so we don't store it in plaintext
38
+ return crypto.createHash('sha256').update(licenceKey).digest('hex').slice(0, 16);
39
+ }
40
+
41
+ function _readCache() {
42
+ try {
43
+ if (!fs.existsSync(CACHE_FILE)) return {};
44
+ return JSON.parse(fs.readFileSync(CACHE_FILE, 'utf8'));
45
+ } catch(_) { return {}; }
46
+ }
47
+
48
+ function _writeCache(licenceKey, data) {
49
+ try {
50
+ if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true });
51
+ const cache = _readCache();
52
+ cache[_cacheKey(licenceKey)] = { ...data, cached_at: Date.now() };
53
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2));
54
+ } catch(_) {}
55
+ }
56
+
57
+ function _getCached(licenceKey) {
58
+ const cache = _readCache();
59
+ const entry = cache[_cacheKey(licenceKey)];
60
+ if (!entry) return null;
61
+ if (Date.now() - entry.cached_at > CACHE_TTL_MS) return null; // expired
62
+ return entry;
63
+ }
64
+
65
+ // ── Polar validation ──────────────────────────────────────────────────────────
66
+
67
+ async function _validateWithPolar(licenceKey) {
68
+ const body = JSON.stringify({
69
+ key: licenceKey,
70
+ organization_id: POLAR_ORG_ID,
71
+ });
72
+
73
+ const res = await fetch(POLAR_API, {
74
+ method: 'POST',
75
+ headers: { 'Content-Type': 'application/json' },
76
+ body,
77
+ signal: AbortSignal.timeout(10000),
78
+ });
79
+
80
+ if (res.status === 404) {
81
+ return { valid: false, reason: 'Key not found' };
82
+ }
83
+ if (res.status === 422) {
84
+ return { valid: false, reason: 'Invalid key format' };
85
+ }
86
+ if (!res.ok) {
87
+ // Network/server error — allow offline grace period
88
+ return { valid: null, reason: `Polar API error: ${res.status}` };
89
+ }
90
+
91
+ const data = await res.json();
92
+
93
+ // Polar returns status: 'granted' | 'revoked' | 'disabled'
94
+ if (data.status !== 'granted') {
95
+ return { valid: false, reason: `Licence ${data.status}` };
96
+ }
97
+
98
+ return {
99
+ valid: true,
100
+ status: data.status,
101
+ expires_at: data.expires_at || null,
102
+ key_id: data.id,
103
+ };
104
+ }
105
+
106
+ // ── Main export ───────────────────────────────────────────────────────────────
107
+
108
+ /**
109
+ * validateLicence(licenceKey)
110
+ *
111
+ * Call before createMemory(). Throws if the key is invalid.
112
+ * Caches valid keys for 30 days so it doesn't call Polar on every run.
113
+ *
114
+ * @param {string} licenceKey — the customer's Polar licence key
115
+ * @returns {Promise<void>}
116
+ * @throws {Error} if key is invalid, revoked, or missing
117
+ */
118
+ async function validateLicence(licenceKey) {
119
+ if (!licenceKey || typeof licenceKey !== 'string' || licenceKey.trim().length < 8) {
120
+ throw new Error(
121
+ '\n' +
122
+ ' ╔══════════════════════════════════════════════════════╗\n' +
123
+ ' ║ VEKTOR SLIPSTREAM — LICENCE REQUIRED ║\n' +
124
+ ' ╚══════════════════════════════════════════════════════╝\n' +
125
+ '\n' +
126
+ ' A valid licence key is required to use Vektor Slipstream.\n' +
127
+ '\n' +
128
+ ' Purchase at: ' + PURCHASE_URL + '\n' +
129
+ '\n' +
130
+ ' Usage:\n' +
131
+ ' const memory = await createMemory({\n' +
132
+ ' agentId: \'my-agent\',\n' +
133
+ ' licenceKey: \'VEKTOR-XXXX-XXXX-XXXX\',\n' +
134
+ ' });\n'
135
+ );
136
+ }
137
+
138
+ // Check cache first
139
+ const cached = _getCached(licenceKey);
140
+ if (cached?.valid === true) {
141
+ // Cache hit — valid, proceed silently
142
+ return;
143
+ }
144
+
145
+ // Cache miss or expired — validate with Polar
146
+ let result;
147
+ try {
148
+ result = await _validateWithPolar(licenceKey.trim());
149
+ } catch(e) {
150
+ // Network failure — check if we have any cached entry (even expired) as grace period
151
+ const staleCache = _readCache()[_cacheKey(licenceKey)];
152
+ if (staleCache?.valid === true) {
153
+ console.warn('[SLIPSTREAM] Could not reach licence server — using cached validation (grace period).');
154
+ return;
155
+ }
156
+ throw new Error(
157
+ '[SLIPSTREAM] Licence validation failed — could not reach Polar.\n' +
158
+ 'Check your internet connection and try again.\n' +
159
+ 'Error: ' + e.message
160
+ );
161
+ }
162
+
163
+ if (result.valid === null) {
164
+ // Polar API error — use stale cache as grace period
165
+ const staleCache = _readCache()[_cacheKey(licenceKey)];
166
+ if (staleCache?.valid === true) {
167
+ console.warn('[SLIPSTREAM] Licence server error — using cached validation (grace period).');
168
+ return;
169
+ }
170
+ throw new Error('[SLIPSTREAM] Licence server temporarily unavailable. Try again in a moment.');
171
+ }
172
+
173
+ if (!result.valid) {
174
+ throw new Error(
175
+ '\n' +
176
+ ' ╔══════════════════════════════════════════════════════╗\n' +
177
+ ' ║ VEKTOR SLIPSTREAM — LICENCE INVALID ║\n' +
178
+ ' ╚══════════════════════════════════════════════════════╝\n' +
179
+ '\n' +
180
+ ' Reason: ' + result.reason + '\n' +
181
+ '\n' +
182
+ ' Purchase a valid licence at: ' + PURCHASE_URL + '\n' +
183
+ ' Already purchased? Check your email for the key.\n'
184
+ );
185
+ }
186
+
187
+ // Valid — cache it
188
+ _writeCache(licenceKey, result);
189
+ }
190
+
191
+ module.exports = { validateLicence };