vektor-slipstream 1.2.0 → 1.2.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.2.0",
3
+ "version": "1.2.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
  "bin": {
@@ -86,4 +86,5 @@
86
86
  "devDependencies": {
87
87
  "javascript-obfuscator": "^5.4.1"
88
88
  }
89
- }
89
+ }
90
+
@@ -1,15 +1,109 @@
1
1
  'use strict';
2
- const os = require('os');
2
+
3
+ /**
4
+ * vektor-banner-loader.js
5
+ * Prints the VEKTOR ASCII banner with a real animated progress bar.
6
+ * Bar animates while the process boots, resolves when ready.
7
+ * Works on Windows (no ANSI cursor tricks that break cmd.exe).
8
+ */
9
+
10
+ const PKG = require('./package.json');
3
11
  const start = Date.now();
4
- console.log('');
5
- console.log(' ██╗ ██╗███████╗██╗ ██╗████████╗ ██████╗ ██████╗ ');
6
- console.log(' ██║ ██║██╔════╝██║ ██╔╝╚══██╔══╝██╔═══██╗██╔══██╗');
7
- console.log(' ██║ ██║█████╗ █████╔╝ ██║ ██║ ██║██████╔╝ ');
8
- console.log(' ╚██╗ ██╔╝██╔══╝ ██╔═██╗ ██║ ██║ ██║██╔══██╗ ');
9
- console.log(' ╚████╔╝ ███████╗██║ ██╗ ██║ ╚██████╔╝██║ ██║ ');
10
- console.log(' ╚═══╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ');
11
- console.log('');
12
- console.log(' SLIPSTREAM v' + require('./package.json').version + ' · Sovereign Agent Memory');
13
- process.stderr.write(' └─ Loading model [░░░░░░░░░░░░░░░░░░░░] 0% ');
14
- console.log('');
15
- module.exports = { loadedAt: start };
12
+
13
+ // ── Colours ───────────────────────────────────────────────────────────────────
14
+ const ESC = '\x1b[';
15
+ const RESET = '\x1b[0m';
16
+ const ORANGE = '\x1b[38;5;214m';
17
+ const DIM = '\x1b[2m';
18
+ const BOLD = '\x1b[1m';
19
+ const CYAN = '\x1b[36m';
20
+
21
+ // ── Banner lines (stored as plain ASCII — encoding-safe) ──────────────────────
22
+ const BANNER = [
23
+ ' ██╗ ██╗███████╗██╗ ██╗████████╗ ██████╗ ██████╗ ',
24
+ ' ██║ ██║██╔════╝██║ ██╔╝╚══██╔══╝██╔═══██╗██╔══██╗',
25
+ ' ██║ ██║█████╗ █████╔╝ ██║ ██║ ██║██████╔╝',
26
+ ' ╚██╗ ██╔╝██╔══╝ ██╔═██╗ ██║ ██║ ██║██╔══██╗',
27
+ ' ╚████╔╝ ███████╗██║ ██╗ ██║ ╚██████╔╝██║ ██║',
28
+ " ╚═══╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝",
29
+ ];
30
+
31
+ // ── Print banner immediately ───────────────────────────────────────────────────
32
+ process.stderr.write('\n');
33
+ BANNER.forEach(l => process.stderr.write(ORANGE + l + RESET + '\n'));
34
+ process.stderr.write('\n');
35
+ process.stderr.write(DIM + ' SLIPSTREAM v' + PKG.version + ' · Sovereign Agent Memory' + RESET + '\n');
36
+ process.stderr.write('\n');
37
+
38
+ // ── Progress bar state ────────────────────────────────────────────────────────
39
+ const BAR_WIDTH = 20;
40
+ let _pct = 0;
41
+ let _label = 'Initialising';
42
+ let _done = false;
43
+ let _timer = null;
44
+
45
+ function renderBar(pct, label) {
46
+ const filled = Math.round((pct / 100) * BAR_WIDTH);
47
+ const empty = BAR_WIDTH - filled;
48
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
49
+ const pctStr = String(pct).padStart(3) + '%';
50
+ // \r moves to start of line, overwrites in place — works on Windows
51
+ // Pad label to 20 chars to fully overwrite any previous longer label on \r
52
+ const paddedLabel = (label + ' ').slice(0, 20);
53
+ process.stderr.write(
54
+ '\r ' + DIM + '└─ ' + RESET +
55
+ CYAN + '[' + bar + ']' + RESET + ' ' +
56
+ DIM + pctStr + ' ' + paddedLabel + RESET
57
+ );
58
+ }
59
+
60
+ // Animate: slowly tick up to 85% while waiting for real completion
61
+ function startAnimation() {
62
+ const ticks = [
63
+ { at: 100, pct: 10, label: 'Initialising' },
64
+ { at: 200, pct: 25, label: 'Loading core' },
65
+ { at: 400, pct: 40, label: 'Opening DB' },
66
+ { at: 700, pct: 55, label: 'Warming cache' },
67
+ { at: 1000, pct: 70, label: 'Ready' },
68
+ { at: 1400, pct: 82, label: 'Ready' },
69
+ ];
70
+
71
+ renderBar(0, 'Initialising');
72
+
73
+ ticks.forEach(({ at, pct, label }) => {
74
+ setTimeout(() => {
75
+ if (_done) return;
76
+ _pct = pct;
77
+ _label = label;
78
+ renderBar(_pct, _label);
79
+ }, at);
80
+ });
81
+ }
82
+
83
+ function completeBar(label) {
84
+ if (_done) return;
85
+ _done = true;
86
+ if (_timer) clearInterval(_timer);
87
+ renderBar(100, label || 'Ready');
88
+ process.stderr.write('\n\n');
89
+ }
90
+
91
+ // ── Auto-complete on process ready ────────────────────────────────────────────
92
+ // If nothing calls complete() explicitly, finish bar when event loop drains
93
+ _timer = setTimeout(() => {
94
+ if (!_done) completeBar('Ready');
95
+ }, 2000);
96
+
97
+ // Don't let this timer keep the process alive
98
+ if (_timer.unref) _timer.unref();
99
+
100
+ // ── Exports ───────────────────────────────────────────────────────────────────
101
+ module.exports = {
102
+ loadedAt: start,
103
+ progress: (pct, label) => { if (!_done) { _pct = pct; _label = label; renderBar(pct, label); } },
104
+ complete: completeBar,
105
+ fail: (msg) => { completeBar('Error'); process.stderr.write('\n ' + msg + '\n'); },
106
+ };
107
+
108
+ // Start animation
109
+ startAnimation();
package/vektor-cli.js CHANGED
@@ -1,17 +1,25 @@
1
1
  #!/usr/bin/env node
2
2
  'use strict';
3
- require('./vektor-banner-loader');
4
3
 
5
- const path = require('path');
6
- const os = require('fs') && require('os');
7
- const fs = require('fs');
8
- const PKG = require('./package.json');
4
+ const path = require('path');
5
+ const os = require('os');
6
+ const fs = require('fs');
7
+ const PKG = require('./package.json');
8
+ const loader = require('./vektor-banner-loader');
9
9
 
10
10
  const command = process.argv[2] || 'help';
11
11
 
12
+ // ── Colours ───────────────────────────────────────────────────────────────────
13
+
12
14
  const C = {
13
- reset: '\x1b[0m', cyan: '\x1b[36m', green: '\x1b[32m',
14
- yellow: '\x1b[33m', red: '\x1b[31m', dim: '\x1b[2m', bold: '\x1b[1m',
15
+ reset: '\x1b[0m',
16
+ cyan: '\x1b[36m',
17
+ green: '\x1b[32m',
18
+ yellow: '\x1b[33m',
19
+ red: '\x1b[31m',
20
+ dim: '\x1b[2m',
21
+ bold: '\x1b[1m',
22
+ orange: '\x1b[38;5;214m',
15
23
  };
16
24
  const cyan = s => C.cyan + s + C.reset;
17
25
  const green = s => C.green + s + C.reset;
@@ -19,9 +27,12 @@ const yellow = s => C.yellow + s + C.reset;
19
27
  const red = s => C.red + s + C.reset;
20
28
  const dim = s => C.dim + s + C.reset;
21
29
  const bold = s => C.bold + s + C.reset;
30
+ const orange = s => C.orange + s + C.reset;
22
31
 
23
- function printBanner() {
24
- console.log('');
32
+ // Banner is printed automatically by vektor-banner-loader on require
33
+
34
+ function printBox() {
35
+ loader.complete('Ready');
25
36
  console.log(cyan(' +------------------------------------------------------+'));
26
37
  console.log(cyan(' |') + bold(' VEKTOR SLIPSTREAM CLI ') + cyan('|'));
27
38
  console.log(cyan(' +------------------------------------------------------+'));
@@ -29,26 +40,33 @@ function printBanner() {
29
40
  console.log('');
30
41
  }
31
42
 
43
+ // ── Help ──────────────────────────────────────────────────────────────────────
44
+
32
45
  async function cmdHelp() {
33
- printBanner();
46
+ printBox();
34
47
  console.log(bold(' COMMANDS\n'));
48
+
35
49
  const cmds = [
36
- ['setup', 'First-run wizard -- activate licence, test memory, configure integrations'],
50
+ ['setup', 'First-run wizard activate licence, test memory, configure integrations'],
37
51
  ['activate', 'Activate your licence key on this machine'],
38
52
  ['deactivate', "Free up this machine's activation slot"],
39
53
  ['status', 'Show licence status, memory stats, and system info'],
40
- ['test', 'Run a quick memory test (remember + recall)'],
54
+ ['test', 'Run a quick memory test (remember + recall + briefing)'],
41
55
  ['mcp', 'Start the Claude MCP server (for Claude Desktop)'],
56
+ ['tui', 'Launch the interactive memory browser (terminal UI)'],
42
57
  ['rem', 'Run the REM dream cycle on your memory database'],
58
+ ['briefing', 'Generate a morning briefing from recent memories'],
43
59
  ['help', 'Show this help message'],
44
60
  ];
61
+
45
62
  cmds.forEach(([cmd, desc]) => {
46
- console.log(' ' + cyan(('npx vektor ' + cmd).padEnd(24)) + dim(desc));
63
+ console.log(' ' + cyan(('npx vektor ' + cmd).padEnd(26)) + dim(desc));
47
64
  });
65
+
48
66
  console.log('');
49
67
  console.log(bold(' ENVIRONMENT\n'));
50
68
  console.log(' ' + cyan('VEKTOR_LICENCE_KEY') + ' ' + dim('Your Polar licence key (skips interactive prompt)'));
51
- console.log(' ' + cyan('VEKTOR_DB_PATH ') + ' ' + dim('Path to memory database (default: ./slipstream-memory.db)'));
69
+ console.log(' ' + cyan('VEKTOR_DB_PATH ') + ' ' + dim('Path to memory database (default: ~/vektor-slipstream-memory.db)'));
52
70
  console.log(' ' + cyan('VEKTOR_AGENT_ID ') + ' ' + dim('Agent identifier (default: default)'));
53
71
  console.log('');
54
72
  console.log(bold(' EXAMPLES\n'));
@@ -56,165 +74,285 @@ async function cmdHelp() {
56
74
  console.log(' npx vektor setup\n');
57
75
  console.log(dim(' # Connect to Claude Desktop'));
58
76
  console.log(' npx vektor mcp\n');
77
+ console.log(dim(' # Browse your memory interactively'));
78
+ console.log(' npx vektor tui\n');
79
+ console.log(dim(' # Run overnight memory compression'));
80
+ console.log(' npx vektor rem\n');
59
81
  console.log(dim(' # Check everything is working'));
60
82
  console.log(' npx vektor status\n');
61
- console.log(' Purchase at: https://vektormemory.com/product#pricing');
83
+ console.log(' ' + dim('Purchase at: https://vektormemory.com/product#pricing'));
62
84
  console.log('');
63
85
  }
64
86
 
87
+ // ── Status ────────────────────────────────────────────────────────────────────
88
+
65
89
  async function cmdStatus() {
66
- printBanner();
90
+ printBox();
67
91
  console.log(bold(' SYSTEM STATUS\n'));
68
- const nodeOk = parseInt(process.version.slice(1)) >= 18;
69
- console.log(' Node.js ' + (nodeOk ? green('OK') : red('FAIL')) + ' ' + process.version);
92
+
93
+ const nodeVer = parseInt(process.version.slice(1));
94
+ const nodeOk = nodeVer >= 18;
95
+ console.log(' Node.js ' + (nodeOk ? green('✓ ' + process.version) : red('✗ ' + process.version + ' (requires >=18)')));
96
+
70
97
  const cacheFile = path.join(os.homedir(), '.vektor', 'licence.json');
71
98
  const hasCache = fs.existsSync(cacheFile);
72
- console.log(' Licence cache ' + (hasCache ? green('OK') : yellow('--')) + ' ' + (hasCache ? dim(cacheFile) : dim('not found -- run: npx vektor activate')));
99
+ console.log(' Licence cache ' + (hasCache ? green('✓ found') : yellow('– not found')) + dim(' (' + cacheFile + ')'));
100
+
73
101
  const envKey = process.env.VEKTOR_LICENCE_KEY;
74
- console.log(' Licence env ' + (envKey ? green('OK') : dim('--')) + ' ' + (envKey ? green('VEKTOR_LICENCE_KEY is set') : dim('not set')));
75
- const dbPath = process.env.VEKTOR_DB_PATH || './slipstream-memory.db';
76
- const hasDb = fs.existsSync(dbPath);
77
- console.log(' Memory DB ' + (hasDb ? green('OK') : dim('--')) + ' ' + (hasDb ? dim(path.resolve(dbPath)) : dim('not found -- run: npx vektor test')));
102
+ console.log(' Licence env ' + (envKey ? green(' VEKTOR_LICENCE_KEY set') : dim('not set')));
103
+
104
+ const dbPath = process.env.VEKTOR_DB_PATH ||
105
+ path.join(os.homedir(), 'vektor-slipstream-memory.db');
106
+ const hasDb = fs.existsSync(dbPath);
107
+ console.log(' Memory DB ' + (hasDb ? green('✓ ' + dbPath) : dim('– not found (run: npx vektor test)')));
108
+
78
109
  const vaultFile = path.join(os.homedir(), '.vektor', 'vault.enc');
79
- console.log(' Cloak vault ' + (fs.existsSync(vaultFile) ? green('OK') : dim('--')));
110
+ console.log(' Cloak vault ' + (fs.existsSync(vaultFile) ? green('✓ found') : dim('– not initialised')));
111
+
80
112
  let hasPw = false;
81
113
  try { require('playwright'); hasPw = true; } catch (_) {}
82
- console.log(' Playwright ' + (hasPw ? green('OK') : yellow('--')) + ' ' + (hasPw ? green('installed') : yellow('optional -- npx playwright install chromium')));
83
- console.log('\n Package ' + cyan('vektor-slipstream') + ' ' + dim('v' + PKG.version));
114
+ console.log(' Playwright ' + (hasPw ? green(' installed') : yellow('optional (npx playwright install chromium)')));
115
+
116
+ let hasOnnx = false;
117
+ try { require('onnxruntime-node'); hasOnnx = true; } catch (_) {}
118
+ console.log(' ONNX runtime ' + (hasOnnx ? green('✓ installed') : red('✗ missing (npm install onnxruntime-node)')));
119
+
120
+ console.log('\n ' + cyan('vektor-slipstream') + ' ' + dim('v' + PKG.version));
84
121
  console.log('');
85
122
  }
86
123
 
124
+ // ── Activate ──────────────────────────────────────────────────────────────────
125
+
87
126
  async function cmdActivate() {
88
- printBanner();
127
+ printBox();
89
128
  console.log(' Activating licence...\n');
90
129
  try {
91
130
  const { resolveAndValidateLicence } = require('./vektor-licence-prompt');
92
131
  const { validateLicence } = require('./vektor-licence');
93
132
  await resolveAndValidateLicence(validateLicence);
94
- console.log(green(' Licence activated successfully.'));
133
+ console.log(green(' Licence activated successfully.'));
95
134
  console.log(dim(' Run: npx vektor status'));
96
135
  } catch (e) {
97
- console.error(red(' Activation failed: ') + e.message);
136
+ console.error(red(' Activation failed: ') + e.message);
98
137
  process.exit(1);
99
138
  }
100
139
  console.log('');
101
140
  }
102
141
 
142
+ // ── Deactivate ────────────────────────────────────────────────────────────────
143
+
103
144
  async function cmdDeactivate() {
104
- printBanner();
145
+ printBox();
105
146
  const key = process.env.VEKTOR_LICENCE_KEY;
106
147
  if (!key) {
107
- console.error(red(' VEKTOR_LICENCE_KEY not set.'));
108
- console.log(dim(' Set it: export VEKTOR_LICENCE_KEY=YOUR-KEY'));
148
+ console.error(red(' VEKTOR_LICENCE_KEY not set.'));
149
+ console.log(dim(' Set it: set VEKTOR_LICENCE_KEY=YOUR-KEY (Windows) or export VEKTOR_LICENCE_KEY=YOUR-KEY (Unix)'));
109
150
  process.exit(1);
110
151
  }
111
152
  try {
112
153
  const { deactivateMachine } = require('./vektor-licence');
113
154
  await deactivateMachine(key);
155
+ console.log(green(' ✓ Machine deactivated. Activation slot freed.'));
114
156
  } catch (e) {
115
- console.error(red(' Deactivation error: ') + e.message);
157
+ console.error(red(' Deactivation error: ') + e.message);
116
158
  process.exit(1);
117
159
  }
160
+ console.log('');
118
161
  }
119
162
 
163
+ // ── Test ──────────────────────────────────────────────────────────────────────
164
+
120
165
  async function cmdTest() {
121
- printBanner();
166
+ printBox();
122
167
  console.log(' Running memory test...\n');
168
+
123
169
  const steps = ['Boot engine', 'Store memory', 'Recall memory', 'Briefing', 'Cleanup'];
124
170
  let step = 0;
125
- const bar = () => {
126
- const pct = Math.round((step / steps.length) * 100);
171
+
172
+ const bar = (label) => {
173
+ const pct = Math.round((step / steps.length) * 100);
127
174
  const filled = Math.round((step / steps.length) * 30);
128
- const b = '[' + '#'.repeat(filled) + '-'.repeat(30 - filled) + ']';
129
- process.stdout.write('\r ' + b + ' ' + pct + '% ' + (steps[step] || 'Done') + ' ');
175
+ const b = '[' + '#'.repeat(filled) + '-'.repeat(30 - filled) + ']';
176
+ process.stdout.write('\r ' + cyan(b) + ' ' + String(pct).padStart(3) + '% ' + dim(label || steps[step] || 'Done') + ' ');
130
177
  };
178
+
131
179
  bar();
180
+
132
181
  try {
133
182
  const { createMemory } = require('./slipstream-core');
183
+ const testDb = path.join(os.tmpdir(), 'vektor-test-' + Date.now() + '.db');
184
+
134
185
  const memory = await createMemory({
135
- agentId: 'vektor-cli-test', dbPath: './vektor-test.db',
136
- silent: true, licenceKey: process.env.VEKTOR_LICENCE_KEY,
186
+ agentId: 'vektor-cli-test',
187
+ dbPath: testDb,
188
+ silent: true,
189
+ licenceKey: process.env.VEKTOR_LICENCE_KEY,
137
190
  });
138
- step++; bar(); console.log(''); console.log(green(' Memory engine booted'));
139
- const { id } = await memory.remember('VEKTOR CLI test -- memory is working correctly');
140
- step++; bar(); console.log(''); console.log(green(' Stored memory (id: ' + id + ')'));
191
+ step++; bar(); process.stdout.write('\n'); console.log(green(' Memory engine booted'));
192
+
193
+ const { id } = await memory.remember('VEKTOR CLI test — memory is working correctly', { importance: 3 });
194
+ step++; bar(); process.stdout.write('\n'); console.log(green(' ✓ Stored memory (id: ' + id + ')'));
195
+
141
196
  const results = await memory.recall('CLI test memory working', 3);
197
+ step++; bar(); process.stdout.write('\n');
142
198
  if (results.length > 0) {
143
- step++; bar(); console.log(''); console.log(green(' Recalled ' + results.length + ' result(s) -- score: ' + results[0].score));
199
+ console.log(green(' Recalled ' + results.length + ' result(s) top score: ' + results[0].score.toFixed(4)));
144
200
  } else {
145
- console.log(yellow(' Recall returned 0 results'));
201
+ console.log(yellow(' Recall returned 0 results'));
202
+ }
203
+
204
+ try {
205
+ await memory.briefing();
206
+ step++; bar(); process.stdout.write('\n'); console.log(green(' ✓ Briefing generated'));
207
+ } catch (_) {
208
+ step++; bar(); process.stdout.write('\n'); console.log(dim(' – Briefing skipped (not enough memories)'));
146
209
  }
147
- await memory.briefing();
148
- step++; bar(); console.log(''); console.log(green(' Briefing generated'));
149
- try { memory.db.close(); } catch(_) {}
210
+
211
+ try { if (memory.db) memory.db.close(); } catch (_) {}
150
212
  await new Promise(r => setTimeout(r, 200));
151
- try { fs.unlinkSync('./vektor-test.db'); step++; bar(); console.log(''); console.log(green(' Test database cleaned up')); } catch(_) {}
152
- console.log('\n' + green(' All tests passed. VEKTOR is working correctly.'));
213
+ try { fs.unlinkSync(testDb); } catch (_) {}
214
+ step++; bar('Done'); process.stdout.write('\n'); console.log(green(' Test database cleaned up'));
215
+
216
+ console.log('\n' + green(' ✓ All tests passed. VEKTOR is working correctly.\n'));
153
217
  } catch (e) {
154
- console.error(red(' Test failed: ') + e.message);
218
+ process.stdout.write('\n');
219
+ console.error(red('\n ✗ Test failed: ') + e.message);
155
220
  if (e.message.includes('better-sqlite3')) {
156
221
  console.log(yellow(' Fix: npm rebuild better-sqlite3'));
157
222
  }
223
+ if (e.message.includes('licence')) {
224
+ console.log(yellow(' Fix: npx vektor activate'));
225
+ }
158
226
  process.exit(1);
159
227
  }
160
- console.log('');
161
228
  }
162
229
 
230
+ // ── MCP ───────────────────────────────────────────────────────────────────────
231
+
163
232
  async function cmdMcp() {
164
233
  const mcpScript = path.join(__dirname, 'examples', 'example-claude-mcp.js');
165
234
  if (!fs.existsSync(mcpScript)) {
166
- console.error(red(' MCP server not found: ') + mcpScript);
235
+ console.error(red(' MCP server not found: ') + mcpScript);
167
236
  process.exit(1);
168
237
  }
238
+ // Override argv so the MCP script sees --mcp flag
169
239
  process.argv = ['node', mcpScript, '--mcp'];
170
240
  require(mcpScript);
171
241
  }
172
242
 
243
+ // ── TUI ───────────────────────────────────────────────────────────────────────
244
+
245
+ async function cmdTui() {
246
+ const tuiScript = path.join(__dirname, 'vektor-tui.js');
247
+ if (!fs.existsSync(tuiScript)) {
248
+ console.error(red(' ✗ TUI not found: ') + tuiScript);
249
+ process.exit(1);
250
+ }
251
+ loader.complete('Launching TUI');
252
+ require(tuiScript);
253
+ }
254
+
255
+ // ── REM ───────────────────────────────────────────────────────────────────────
256
+
173
257
  async function cmdRem() {
174
- printBanner();
258
+ printBox();
175
259
  console.log(' Running REM dream cycle...\n');
176
260
  try {
177
261
  const { createMemory } = require('./slipstream-core');
178
- const dbPath = process.env.VEKTOR_DB_PATH || './slipstream-memory.db';
262
+ const dbPath = process.env.VEKTOR_DB_PATH ||
263
+ path.join(os.homedir(), 'vektor-slipstream-memory.db');
264
+
179
265
  if (!fs.existsSync(dbPath)) {
180
- console.error(yellow(' No memory database found at: ' + dbPath));
266
+ console.error(yellow(' No memory database found at: ' + dbPath));
267
+ console.log(dim(' Run: npx vektor test to create one'));
181
268
  process.exit(1);
182
269
  }
270
+
183
271
  const memory = await createMemory({
184
- agentId: process.env.VEKTOR_AGENT_ID || 'default',
185
- dbPath, silent: true, licenceKey: process.env.VEKTOR_LICENCE_KEY,
272
+ agentId: process.env.VEKTOR_AGENT_ID || 'default',
273
+ dbPath,
274
+ silent: true,
275
+ licenceKey: process.env.VEKTOR_LICENCE_KEY,
186
276
  });
187
- console.log(' Starting REM cycle...');
277
+
278
+ console.log(' ' + dim('Starting REM cycle...'));
188
279
  const result = await memory.dream();
189
- console.log(green(' REM cycle complete'));
190
- if (result) console.log(dim(' ' + JSON.stringify(result)));
280
+ console.log(green(' REM cycle complete'));
281
+ if (result) console.log(dim(' ' + JSON.stringify(result, null, 2)));
191
282
  } catch (e) {
192
- console.error(red(' REM error: ') + e.message);
283
+ console.error(red(' REM error: ') + e.message);
193
284
  process.exit(1);
194
285
  }
195
286
  console.log('');
196
287
  }
197
288
 
289
+ // ── Briefing ──────────────────────────────────────────────────────────────────
290
+
291
+ async function cmdBriefing() {
292
+ printBox();
293
+ console.log(' Generating memory briefing...\n');
294
+ try {
295
+ const { createMemory } = require('./slipstream-core');
296
+ const dbPath = process.env.VEKTOR_DB_PATH ||
297
+ path.join(os.homedir(), 'vektor-slipstream-memory.db');
298
+
299
+ if (!fs.existsSync(dbPath)) {
300
+ console.error(yellow(' ⚠ No memory database found at: ' + dbPath));
301
+ console.log(dim(' Run: npx vektor test to create one'));
302
+ process.exit(1);
303
+ }
304
+
305
+ const memory = await createMemory({
306
+ agentId: process.env.VEKTOR_AGENT_ID || 'default',
307
+ dbPath,
308
+ silent: true,
309
+ licenceKey: process.env.VEKTOR_LICENCE_KEY,
310
+ });
311
+
312
+ const brief = await memory.briefing();
313
+ if (brief) {
314
+ console.log(bold(' ── MEMORY BRIEFING ──────────────────────────────────\n'));
315
+ console.log(' ' + brief.split('\n').join('\n '));
316
+ console.log('\n ' + dim('─────────────────────────────────────────────────────'));
317
+ } else {
318
+ console.log(dim(' No briefing available — add more memories first.'));
319
+ }
320
+ } catch (e) {
321
+ console.error(red(' ✗ Briefing error: ') + e.message);
322
+ process.exit(1);
323
+ }
324
+ console.log('');
325
+ }
326
+
327
+ // ── Setup ─────────────────────────────────────────────────────────────────────
328
+
198
329
  async function cmdSetup() {
199
330
  require('./vektor-setup');
200
331
  }
201
332
 
202
- async function cmdTui() { require('./vektor-tui'); }
333
+ // ── Router ────────────────────────────────────────────────────────────────────
203
334
 
204
335
  const commands = {
205
- help: cmdHelp, status: cmdStatus, activate: cmdActivate,
206
- deactivate: cmdDeactivate, test: cmdTest, mcp: cmdMcp,
207
- rem: cmdRem, setup: cmdSetup, tui: async function(){ require('./vektor-tui'); },
336
+ help: cmdHelp,
337
+ status: cmdStatus,
338
+ activate: cmdActivate,
339
+ deactivate: cmdDeactivate,
340
+ test: cmdTest,
341
+ mcp: cmdMcp,
342
+ tui: cmdTui,
343
+ rem: cmdRem,
344
+ briefing: cmdBriefing,
345
+ setup: cmdSetup,
208
346
  };
209
347
 
210
348
  const fn = commands[command];
211
349
  if (!fn) {
212
- console.error(red('\n Unknown command: ' + command));
350
+ console.error(red('\n Unknown command: ') + bold(command));
213
351
  console.log(dim(' Run: npx vektor help\n'));
214
352
  process.exit(1);
215
353
  }
216
354
 
217
355
  fn().catch(e => {
218
- console.error(red('\n Error: ') + e.message);
356
+ console.error(red('\n Error: ') + e.message);
219
357
  process.exit(1);
220
- });
358
+ });