vektor-slipstream 1.4.4 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -306
- package/package.json +14 -146
- package/CHANGELOG.md +0 -139
- package/LICENSE +0 -33
- package/TENETS.md +0 -189
- package/audn-log.js +0 -143
- package/axon.js +0 -389
- package/boot-patch.js +0 -33
- package/boot-screen.html +0 -210
- package/briefing.js +0 -150
- package/cerebellum.js +0 -439
- package/cloak-behaviour.js +0 -596
- package/cloak-captcha.js +0 -541
- package/cloak-core.js +0 -499
- package/cloak-identity.js +0 -484
- package/cloak-index.js +0 -261
- package/cloak-llms.js +0 -163
- package/cloak-pattern-store.js +0 -471
- package/cloak-recorder-auto.js +0 -297
- package/cloak-recorder-snippet.js +0 -119
- package/cloak-turbo-quant.js +0 -357
- package/cloak-warmup.js +0 -240
- package/cortex.js +0 -221
- package/detect-hardware.js +0 -181
- package/entity-resolver.js +0 -298
- package/errors.js +0 -66
- package/examples/example-claude-mcp.js +0 -220
- package/examples/example-langchain-researcher.js +0 -82
- package/examples/example-openai-assistant.js +0 -84
- package/examples/examples-README.md +0 -161
- package/export-import.js +0 -221
- package/forget.js +0 -148
- package/inspect.js +0 -199
- package/mistral/README-mistral.md +0 -123
- package/mistral/mistral-bridge.js +0 -218
- package/mistral/mistral-setup.js +0 -220
- package/mistral/vektor-tool-manifest.json +0 -41
- package/models/model_quantized.onnx +0 -0
- package/models/vocab.json +0 -1
- package/namespace.js +0 -186
- package/pin.js +0 -91
- package/slipstream-core-extended.js +0 -134
- package/slipstream-core.js +0 -1
- package/slipstream-db.js +0 -140
- package/slipstream-embedder.js +0 -338
- package/sovereign.js +0 -142
- package/token.js +0 -322
- package/types/index.d.ts +0 -269
- package/vektor-banner-loader.js +0 -109
- package/vektor-cli.js +0 -259
- package/vektor-licence-prompt.js +0 -128
- package/vektor-licence.js +0 -192
- package/vektor-setup.js +0 -270
- package/vektor-slipstream.dxt +0 -0
- package/vektor-tui.js +0 -373
- package/visualize.js +0 -235
package/cloak-core.js
DELETED
|
@@ -1,499 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
/**
|
|
3
|
-
* cloak.js — VEKTOR Cloak Module
|
|
4
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
-
* Sovereign identity and stealth browser layer for AI agents.
|
|
6
|
-
*
|
|
7
|
-
* Functions:
|
|
8
|
-
* cloak_fetch(url) — AOM stealth fetch, compressed text output
|
|
9
|
-
* cloak_render(url, selectors) — headless CSS/DOM sensor (requires Playwright)
|
|
10
|
-
* cloak_diff(url) — semantic diff since last fetch
|
|
11
|
-
* cloak_passport(key, value?) — AES-256 credential vault read/write
|
|
12
|
-
* cloak_diff_text(a, b) — structural diff between two text blobs
|
|
13
|
-
* tokens_saved(session) — ROI audit per session
|
|
14
|
-
*
|
|
15
|
-
* Playwright (cloak_fetch, cloak_render) is an optional dependency.
|
|
16
|
-
* Install with: npx playwright install chromium
|
|
17
|
-
* ─────────────────────────────────────────────────────────────────────────────
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const fs = require('fs');
|
|
21
|
-
const path = require('path');
|
|
22
|
-
const os = require('os');
|
|
23
|
-
const crypto = require('crypto');
|
|
24
|
-
|
|
25
|
-
const VAULT_DIR = path.join(os.homedir(), '.vektor');
|
|
26
|
-
const VAULT_FILE = path.join(VAULT_DIR, 'vault.enc');
|
|
27
|
-
const CACHE_DIR = path.join(VAULT_DIR, 'cloak-cache');
|
|
28
|
-
|
|
29
|
-
// ── Injection sanitiser ───────────────────────────────────────────────────────
|
|
30
|
-
|
|
31
|
-
const INJECTION_PATTERNS = [
|
|
32
|
-
/ignore previous/gi,
|
|
33
|
-
/system:/gi,
|
|
34
|
-
/admin:/gi,
|
|
35
|
-
/\[INST\]/gi,
|
|
36
|
-
/\[\[/g,
|
|
37
|
-
/\s{10,}/g,
|
|
38
|
-
/eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+/g,
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
function _sanitise(text) {
|
|
42
|
-
let clean = text;
|
|
43
|
-
for (const p of INJECTION_PATTERNS) clean = clean.replace(p, '[STRIPPED]');
|
|
44
|
-
return clean;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// ── URL fingerprint ───────────────────────────────────────────────────────────
|
|
48
|
-
|
|
49
|
-
function _fingerprintUrl(url) {
|
|
50
|
-
try {
|
|
51
|
-
const u = new URL(url);
|
|
52
|
-
['utm_source','utm_medium','utm_campaign','ref','token','sid','session'].forEach(p => u.searchParams.delete(p));
|
|
53
|
-
return u.hostname + u.pathname;
|
|
54
|
-
} catch { return url; }
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// ── Vault (AES-256-GCM, machine-bound) ───────────────────────────────────────
|
|
58
|
-
|
|
59
|
-
function _getMachineKey() {
|
|
60
|
-
return crypto.createHash('sha256')
|
|
61
|
-
.update(`${os.hostname()}:${os.platform()}:${os.homedir()}`)
|
|
62
|
-
.digest();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function _vaultEncrypt(data) {
|
|
66
|
-
const key = _getMachineKey();
|
|
67
|
-
const iv = crypto.randomBytes(16);
|
|
68
|
-
const c = crypto.createCipheriv('aes-256-gcm', key, iv);
|
|
69
|
-
const enc = Buffer.concat([c.update(JSON.stringify(data), 'utf8'), c.final()]);
|
|
70
|
-
return { iv: iv.toString('hex'), tag: c.getAuthTag().toString('hex'), data: enc.toString('hex') };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function _vaultDecrypt(s) {
|
|
74
|
-
const key = _getMachineKey();
|
|
75
|
-
const d = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(s.iv, 'hex'));
|
|
76
|
-
d.setAuthTag(Buffer.from(s.tag, 'hex'));
|
|
77
|
-
return JSON.parse(Buffer.concat([d.update(Buffer.from(s.data, 'hex')), d.final()]).toString('utf8'));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function _loadVault() {
|
|
81
|
-
if (!fs.existsSync(VAULT_FILE)) return {};
|
|
82
|
-
try { return _vaultDecrypt(JSON.parse(fs.readFileSync(VAULT_FILE, 'utf8'))); }
|
|
83
|
-
catch { return {}; }
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function _saveVault(v) {
|
|
87
|
-
if (!fs.existsSync(VAULT_DIR)) fs.mkdirSync(VAULT_DIR, { recursive: true });
|
|
88
|
-
fs.writeFileSync(VAULT_FILE, JSON.stringify(_vaultEncrypt(v)), { mode: 0o600 });
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// ── Cache helpers ─────────────────────────────────────────────────────────────
|
|
92
|
-
|
|
93
|
-
function _getCached(fingerprint) {
|
|
94
|
-
const file = path.join(CACHE_DIR, crypto.createHash('md5').update(fingerprint).digest('hex') + '.json');
|
|
95
|
-
if (!fs.existsSync(file)) return null;
|
|
96
|
-
try { return JSON.parse(fs.readFileSync(file, 'utf8')); }
|
|
97
|
-
catch { return null; }
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function _setCached(fingerprint, data) {
|
|
101
|
-
if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
102
|
-
const file = path.join(CACHE_DIR, crypto.createHash('md5').update(fingerprint).digest('hex') + '.json');
|
|
103
|
-
fs.writeFileSync(file, JSON.stringify({ ...data, fetched_at: Date.now() }));
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// ── Playwright loader (optional) ──────────────────────────────────────────────
|
|
107
|
-
|
|
108
|
-
async function _getChromium() {
|
|
109
|
-
try {
|
|
110
|
-
const { chromium } = require('playwright');
|
|
111
|
-
return chromium;
|
|
112
|
-
} catch (e) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
'Playwright not installed. Run: npx playwright install chromium\n' +
|
|
115
|
-
'Or install manually: npm install playwright && npx playwright install chromium'
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// ── cloak_fetch ───────────────────────────────────────────────────────────────
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Fetch a URL using a headless browser and return clean compressed text.
|
|
124
|
-
* Caches results locally in ~/.vektor/cloak-cache/
|
|
125
|
-
*
|
|
126
|
-
* @param {string} url
|
|
127
|
-
* @param {object} opts
|
|
128
|
-
* @param {boolean} opts.force — bypass cache
|
|
129
|
-
* @param {number} opts.limit — max chars returned (default 8000)
|
|
130
|
-
* @returns {Promise<{text: string, tokensSaved: number, fromCache: boolean}>}
|
|
131
|
-
*/
|
|
132
|
-
async function cloak_fetch(url, opts = {}) {
|
|
133
|
-
const fingerprint = _fingerprintUrl(url);
|
|
134
|
-
const limit = opts.limit || 8000;
|
|
135
|
-
|
|
136
|
-
// Cache hit (1 hour TTL)
|
|
137
|
-
if (!opts.force) {
|
|
138
|
-
const cached = _getCached(fingerprint);
|
|
139
|
-
if (cached && Date.now() - cached.fetched_at < 3600000) {
|
|
140
|
-
return { text: cached.text, tokensSaved: cached.tokensSaved, fromCache: true };
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const chromium = await _getChromium();
|
|
145
|
-
let browser;
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
browser = await chromium.launch({ headless: true });
|
|
149
|
-
const page = await browser.newPage();
|
|
150
|
-
|
|
151
|
-
await page.setExtraHTTPHeaders({
|
|
152
|
-
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 });
|
|
156
|
-
|
|
157
|
-
const rawSize = (await page.content()).length;
|
|
158
|
-
const text = await page.evaluate(() => {
|
|
159
|
-
document.querySelectorAll('script,style,nav,footer,header,aside').forEach(el => el.remove());
|
|
160
|
-
return document.body?.innerText || document.body?.textContent || '';
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
await browser.close();
|
|
164
|
-
|
|
165
|
-
const clean = _sanitise(text.replace(/\s+/g, ' ').trim());
|
|
166
|
-
const tokensSaved = Math.floor((rawSize - clean.length) / 4);
|
|
167
|
-
const result = { text: clean.substring(0, limit), tokensSaved, fromCache: false };
|
|
168
|
-
|
|
169
|
-
_setCached(fingerprint, { text: clean.substring(0, limit * 2), tokensSaved });
|
|
170
|
-
return result;
|
|
171
|
-
|
|
172
|
-
} catch (err) {
|
|
173
|
-
if (browser) await browser.close().catch(() => {});
|
|
174
|
-
throw err;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// ── cloak_render ──────────────────────────────────────────────────────────────
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* High-fidelity layout sensor. Renders a page in a headless browser and
|
|
182
|
-
* returns computed CSS, post-JS DOM state, font audit, gap analysis, asset errors.
|
|
183
|
-
*
|
|
184
|
-
* @param {string} url
|
|
185
|
-
* @param {string[]} selectors — CSS selectors to audit
|
|
186
|
-
* @param {object} opts
|
|
187
|
-
* @returns {Promise<object>}
|
|
188
|
-
*/
|
|
189
|
-
async function cloak_render(url, selectors = [], opts = {}) {
|
|
190
|
-
const chromium = await _getChromium();
|
|
191
|
-
const waitFor = opts.wait_for || 'networkidle';
|
|
192
|
-
const mobile = opts.mobile || false;
|
|
193
|
-
const failedAssets = [], consoleErrors = [];
|
|
194
|
-
let browser;
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
browser = await chromium.launch({ headless: true });
|
|
198
|
-
const viewport = mobile
|
|
199
|
-
? { width: 390, height: 844, isMobile: true, hasTouch: true, deviceScaleFactor: 3 }
|
|
200
|
-
: { width: 1440, height: 900 };
|
|
201
|
-
|
|
202
|
-
const context = await browser.newContext({ viewport });
|
|
203
|
-
const page = await context.newPage();
|
|
204
|
-
|
|
205
|
-
page.on('requestfailed', req => failedAssets.push({ url: req.url(), reason: req.failure()?.errorText || 'unknown' }));
|
|
206
|
-
page.on('console', msg => { if (msg.type() === 'error') consoleErrors.push(msg.text()); });
|
|
207
|
-
|
|
208
|
-
await page.goto(url, { waitUntil: waitFor, timeout: 30000 });
|
|
209
|
-
await page.evaluate(() => document.fonts.ready);
|
|
210
|
-
|
|
211
|
-
// Audit selectors
|
|
212
|
-
const layout = {};
|
|
213
|
-
for (const sel of (selectors.length ? selectors : ['body', 'main', 'header', 'footer'])) {
|
|
214
|
-
try {
|
|
215
|
-
const data = await page.evaluate((s) => {
|
|
216
|
-
const el = document.querySelector(s);
|
|
217
|
-
if (!el) return null;
|
|
218
|
-
const style = window.getComputedStyle(el);
|
|
219
|
-
const rect = el.getBoundingClientRect();
|
|
220
|
-
return {
|
|
221
|
-
display: style.display,
|
|
222
|
-
visibility: style.visibility,
|
|
223
|
-
w: Math.round(rect.width),
|
|
224
|
-
h: Math.round(rect.height),
|
|
225
|
-
top: Math.round(rect.top),
|
|
226
|
-
};
|
|
227
|
-
}, sel);
|
|
228
|
-
if (data) layout[sel] = data;
|
|
229
|
-
} catch (_) {}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
// Font audit
|
|
233
|
-
const fonts = await page.evaluate(() =>
|
|
234
|
-
[...document.fonts].map(f => ({ family: f.family, status: f.status }))
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
// Gap analysis — find elements with suspicious zero height
|
|
238
|
-
const gapSuspects = await page.evaluate(() => {
|
|
239
|
-
const suspects = [];
|
|
240
|
-
document.querySelectorAll('section, div[class*="section"], div[class*="hero"], div[class*="wrap"]').forEach(el => {
|
|
241
|
-
const rect = el.getBoundingClientRect();
|
|
242
|
-
if (rect.height === 0 && el.children.length > 0) {
|
|
243
|
-
suspects.push({ selector: el.className || el.tagName, issue: 'zero height with children' });
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
return suspects.slice(0, 10);
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
await browser.close();
|
|
250
|
-
|
|
251
|
-
return {
|
|
252
|
-
status: 'SUCCESS',
|
|
253
|
-
url,
|
|
254
|
-
audit: { layout, fonts: fonts.slice(0, 20), gapSuspects, assetErrors: failedAssets.slice(0, 10), consoleErrors: consoleErrors.slice(0, 10) },
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
} catch (err) {
|
|
258
|
-
if (browser) await browser.close().catch(() => {});
|
|
259
|
-
throw err;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// ── cloak_diff ────────────────────────────────────────────────────────────────
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Return what changed on a URL since last fetch.
|
|
267
|
-
* Requires cloak_fetch to have been called at least twice for the URL.
|
|
268
|
-
*
|
|
269
|
-
* @param {string} url
|
|
270
|
-
* @returns {Promise<{added: string[], removed: string[], unchanged: boolean}>}
|
|
271
|
-
*/
|
|
272
|
-
async function cloak_diff(url, opts = {}) {
|
|
273
|
-
const fingerprint = _fingerprintUrl(url);
|
|
274
|
-
const cached = _getCached(fingerprint);
|
|
275
|
-
|
|
276
|
-
if (!cached) {
|
|
277
|
-
// First visit — fetch and cache
|
|
278
|
-
const result = await cloak_fetch(url, opts);
|
|
279
|
-
return { unchanged: true, message: 'First visit — no previous state to diff. Run again to detect changes.' };
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
// Fetch fresh
|
|
283
|
-
const fresh = await cloak_fetch(url, { ...opts, force: true });
|
|
284
|
-
|
|
285
|
-
const cachedWords = new Set(cached.text.split(/\s+/).filter(w => w.length > 4));
|
|
286
|
-
const freshWords = new Set(fresh.text.split(/\s+/).filter(w => w.length > 4));
|
|
287
|
-
|
|
288
|
-
const added = [...freshWords].filter(w => !cachedWords.has(w));
|
|
289
|
-
const removed = [...cachedWords].filter(w => !freshWords.has(w));
|
|
290
|
-
|
|
291
|
-
if (added.length === 0 && removed.length === 0) {
|
|
292
|
-
return { unchanged: true, message: 'No semantic changes detected.' };
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return {
|
|
296
|
-
unchanged: false,
|
|
297
|
-
added: added.slice(0, 50),
|
|
298
|
-
removed: removed.slice(0, 50),
|
|
299
|
-
summary: `+${added.length} new terms, -${removed.length} removed terms`,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// ── cloak_diff_text ───────────────────────────────────────────────────────────
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* Structural diff between two text blobs or JSON objects.
|
|
307
|
-
* No browser required — pure local comparison.
|
|
308
|
-
*
|
|
309
|
-
* @param {string|object} a — previous state
|
|
310
|
-
* @param {string|object} b — current state
|
|
311
|
-
* @returns {{added: string[], removed: string[], changed: string[]}}
|
|
312
|
-
*/
|
|
313
|
-
function cloak_diff_text(a, b) {
|
|
314
|
-
const strA = typeof a === 'object' ? JSON.stringify(a, null, 2) : String(a);
|
|
315
|
-
const strB = typeof b === 'object' ? JSON.stringify(b, null, 2) : String(b);
|
|
316
|
-
|
|
317
|
-
const linesA = new Set(strA.split('\n').map(l => l.trim()).filter(Boolean));
|
|
318
|
-
const linesB = new Set(strB.split('\n').map(l => l.trim()).filter(Boolean));
|
|
319
|
-
|
|
320
|
-
const added = [...linesB].filter(l => !linesA.has(l));
|
|
321
|
-
const removed = [...linesA].filter(l => !linesB.has(l));
|
|
322
|
-
|
|
323
|
-
return {
|
|
324
|
-
added,
|
|
325
|
-
removed,
|
|
326
|
-
unchanged: added.length === 0 && removed.length === 0,
|
|
327
|
-
summary: `+${added.length} lines added, -${removed.length} lines removed`,
|
|
328
|
-
};
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
// ── cloak_passport ────────────────────────────────────────────────────────────
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Read and write to the encrypted ~/.vektor/vault.enc credential store.
|
|
335
|
-
* AES-256-GCM encrypted. Decryption key is machine-bound (hostname + platform + homedir).
|
|
336
|
-
* A compromised vault file is unreadable on any other machine.
|
|
337
|
-
*
|
|
338
|
-
* @param {string} key — credential name (e.g. 'GITHUB_TOKEN', 'OPENAI_KEY')
|
|
339
|
-
* @param {string} value — if provided, write this value. If omitted, read.
|
|
340
|
-
* @returns {string|null} — value if reading, 'stored' if writing
|
|
341
|
-
*/
|
|
342
|
-
function cloak_passport(key, value) {
|
|
343
|
-
if (!key) throw new Error('cloak_passport: key is required');
|
|
344
|
-
|
|
345
|
-
const vault = _loadVault();
|
|
346
|
-
|
|
347
|
-
if (value !== undefined) {
|
|
348
|
-
vault[key] = value;
|
|
349
|
-
_saveVault(vault);
|
|
350
|
-
return 'stored';
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
return vault[key] || null;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// ── tokens_saved ──────────────────────────────────────────────────────────────
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Log and calculate token efficiency for a session.
|
|
360
|
-
* Compares tokens consumed vs what would have been used without VEKTOR memory compression.
|
|
361
|
-
*
|
|
362
|
-
* @param {object} session
|
|
363
|
-
* @param {number} session.raw_tokens — tokens without VEKTOR (estimated)
|
|
364
|
-
* @param {number} session.actual_tokens — tokens actually used
|
|
365
|
-
* @param {string} session.agent_id — agent identifier
|
|
366
|
-
* @param {string} session.provider — LLM provider (openai, gemini, etc.)
|
|
367
|
-
* @param {number} session.cost_per_1m — cost per 1M input tokens in USD
|
|
368
|
-
* @returns {{saved: number, reduction_pct: number, cost_saved_usd: number, roi_multiple: number}}
|
|
369
|
-
*/
|
|
370
|
-
function tokens_saved(session = {}) {
|
|
371
|
-
const raw = session.raw_tokens || 0;
|
|
372
|
-
const actual = session.actual_tokens || 0;
|
|
373
|
-
const cpm = session.cost_per_1m || 2.50; // default GPT-4o rate
|
|
374
|
-
|
|
375
|
-
if (raw === 0) return { saved: 0, reduction_pct: 0, cost_saved_usd: 0, roi_multiple: 0 };
|
|
376
|
-
|
|
377
|
-
const saved = raw - actual;
|
|
378
|
-
const reduction_pct = Math.round((saved / raw) * 100);
|
|
379
|
-
const cost_saved = (saved / 1_000_000) * cpm;
|
|
380
|
-
const monthly_cost = (actual / 1_000_000) * cpm;
|
|
381
|
-
const roi_multiple = monthly_cost > 0 ? Math.round((cost_saved / monthly_cost) * 10) / 10 : 0;
|
|
382
|
-
|
|
383
|
-
// Log to vault for audit trail
|
|
384
|
-
try {
|
|
385
|
-
const vault = _loadVault();
|
|
386
|
-
const log = vault['_token_audit'] || [];
|
|
387
|
-
log.push({
|
|
388
|
-
timestamp: new Date().toISOString(),
|
|
389
|
-
agent_id: session.agent_id || 'unknown',
|
|
390
|
-
provider: session.provider || 'unknown',
|
|
391
|
-
raw_tokens: raw,
|
|
392
|
-
actual_tokens: actual,
|
|
393
|
-
saved,
|
|
394
|
-
reduction_pct,
|
|
395
|
-
cost_saved_usd: cost_saved,
|
|
396
|
-
});
|
|
397
|
-
vault['_token_audit'] = log.slice(-100); // keep last 100 sessions
|
|
398
|
-
_saveVault(vault);
|
|
399
|
-
} catch (_) {}
|
|
400
|
-
|
|
401
|
-
return {
|
|
402
|
-
saved,
|
|
403
|
-
reduction_pct,
|
|
404
|
-
cost_saved_usd: Math.round(cost_saved * 10000) / 10000,
|
|
405
|
-
roi_multiple,
|
|
406
|
-
summary: `${reduction_pct}% token reduction · $${cost_saved.toFixed(4)} saved · ${roi_multiple}x ROI`,
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// ── MCP tool definitions (for use in MCP servers) ────────────────────────────
|
|
411
|
-
|
|
412
|
-
const CLOAK_MCP_TOOLS = [
|
|
413
|
-
{
|
|
414
|
-
name: 'cloak_fetch',
|
|
415
|
-
description: 'Fetch a URL using a stealth headless browser. Returns clean compressed text. Caches locally — run again to get diff.',
|
|
416
|
-
input_schema: {
|
|
417
|
-
type: 'object',
|
|
418
|
-
properties: {
|
|
419
|
-
url: { type: 'string', description: 'URL to fetch' },
|
|
420
|
-
force: { type: 'boolean', description: 'Bypass cache (default false)' },
|
|
421
|
-
limit: { type: 'integer', description: 'Max chars returned (default 8000)' },
|
|
422
|
-
},
|
|
423
|
-
required: ['url'],
|
|
424
|
-
},
|
|
425
|
-
},
|
|
426
|
-
{
|
|
427
|
-
name: 'cloak_render',
|
|
428
|
-
description: 'High-fidelity layout sensor. Headless browser renders page, executes JS, resolves CSS. Returns computed styles, font audit, gap analysis, asset errors.',
|
|
429
|
-
input_schema: {
|
|
430
|
-
type: 'object',
|
|
431
|
-
properties: {
|
|
432
|
-
url: { type: 'string', description: 'URL to render' },
|
|
433
|
-
selectors: { type: 'array', items: { type: 'string' }, description: 'CSS selectors to audit' },
|
|
434
|
-
mobile: { type: 'boolean', description: 'Render in mobile viewport (default false)' },
|
|
435
|
-
},
|
|
436
|
-
required: ['url'],
|
|
437
|
-
},
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
name: 'cloak_diff',
|
|
441
|
-
description: 'Return what semantically changed on a URL since last fetch.',
|
|
442
|
-
input_schema: {
|
|
443
|
-
type: 'object',
|
|
444
|
-
properties: {
|
|
445
|
-
url: { type: 'string', description: 'URL to check for changes' },
|
|
446
|
-
},
|
|
447
|
-
required: ['url'],
|
|
448
|
-
},
|
|
449
|
-
},
|
|
450
|
-
{
|
|
451
|
-
name: 'cloak_diff_text',
|
|
452
|
-
description: 'Structural diff between two text blobs or JSON objects. No browser needed.',
|
|
453
|
-
input_schema: {
|
|
454
|
-
type: 'object',
|
|
455
|
-
properties: {
|
|
456
|
-
a: { type: 'string', description: 'Previous state (text or JSON string)' },
|
|
457
|
-
b: { type: 'string', description: 'Current state (text or JSON string)' },
|
|
458
|
-
},
|
|
459
|
-
required: ['a', 'b'],
|
|
460
|
-
},
|
|
461
|
-
},
|
|
462
|
-
{
|
|
463
|
-
name: 'cloak_passport',
|
|
464
|
-
description: 'Read or write to the AES-256 encrypted credential vault (~/.vektor/vault.enc). Machine-bound — unreadable on other machines.',
|
|
465
|
-
input_schema: {
|
|
466
|
-
type: 'object',
|
|
467
|
-
properties: {
|
|
468
|
-
key: { type: 'string', description: 'Credential name (e.g. GITHUB_TOKEN)' },
|
|
469
|
-
value: { type: 'string', description: 'Value to store. Omit to read.' },
|
|
470
|
-
},
|
|
471
|
-
required: ['key'],
|
|
472
|
-
},
|
|
473
|
-
},
|
|
474
|
-
{
|
|
475
|
-
name: 'tokens_saved',
|
|
476
|
-
description: 'Calculate token efficiency and ROI for a session. Logs to audit trail.',
|
|
477
|
-
input_schema: {
|
|
478
|
-
type: 'object',
|
|
479
|
-
properties: {
|
|
480
|
-
raw_tokens: { type: 'integer', description: 'Estimated tokens without VEKTOR' },
|
|
481
|
-
actual_tokens: { type: 'integer', description: 'Actual tokens used with VEKTOR' },
|
|
482
|
-
agent_id: { type: 'string', description: 'Agent identifier' },
|
|
483
|
-
provider: { type: 'string', description: 'LLM provider (openai, gemini, etc.)' },
|
|
484
|
-
cost_per_1m: { type: 'number', description: 'Cost per 1M input tokens in USD (default 2.50)' },
|
|
485
|
-
},
|
|
486
|
-
required: ['raw_tokens', 'actual_tokens'],
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
];
|
|
490
|
-
|
|
491
|
-
module.exports = {
|
|
492
|
-
cloak_fetch,
|
|
493
|
-
cloak_render,
|
|
494
|
-
cloak_diff,
|
|
495
|
-
cloak_diff_text,
|
|
496
|
-
cloak_passport,
|
|
497
|
-
tokens_saved,
|
|
498
|
-
CLOAK_MCP_TOOLS,
|
|
499
|
-
};
|