@lanonasis/cli 3.3.15 → 3.5.15

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.
Files changed (38) hide show
  1. package/README.md +57 -13
  2. package/dist/commands/auth.js +11 -5
  3. package/dist/commands/completion.js +2 -0
  4. package/dist/commands/config.js +4 -4
  5. package/dist/commands/enhanced-memory.js +1 -1
  6. package/dist/commands/mcp.js +15 -9
  7. package/dist/core/achievements.js +1 -1
  8. package/dist/core/power-mode.js +5 -3
  9. package/dist/core/welcome.js +6 -6
  10. package/dist/enhanced-cli.js +6 -3
  11. package/dist/index-simple.js +5 -1
  12. package/dist/index.js +5 -1
  13. package/dist/mcp/access-control.d.ts +1 -1
  14. package/dist/mcp/access-control.js +4 -4
  15. package/dist/mcp/client/enhanced-client.js +5 -7
  16. package/dist/mcp/schemas/tool-schemas.d.ts +1 -1
  17. package/dist/mcp/schemas/tool-schemas.js +1 -1
  18. package/dist/mcp/server/lanonasis-server.d.ts +2 -1
  19. package/dist/mcp/server/lanonasis-server.js +7 -5
  20. package/dist/mcp/transports/transport-manager.js +3 -3
  21. package/dist/mcp-server.d.ts +1 -0
  22. package/dist/mcp-server.js +43 -9
  23. package/dist/utils/config.d.ts +10 -1
  24. package/dist/utils/config.js +97 -17
  25. package/dist/utils/mcp-client.d.ts +21 -2
  26. package/dist/utils/mcp-client.js +117 -46
  27. package/package.json +3 -3
  28. package/dist/__tests__/auth-persistence.test.d.ts +0 -1
  29. package/dist/__tests__/auth-persistence.test.js +0 -243
  30. package/dist/__tests__/cross-device-integration.test.d.ts +0 -1
  31. package/dist/__tests__/cross-device-integration.test.js +0 -305
  32. package/dist/__tests__/mcp-connection-reliability.test.d.ts +0 -1
  33. package/dist/__tests__/mcp-connection-reliability.test.js +0 -489
  34. package/dist/__tests__/setup.d.ts +0 -1
  35. package/dist/__tests__/setup.js +0 -26
  36. package/dist/mcp/server/mcp/server/lanonasis-server.js +0 -911
  37. package/dist/mcp/server/utils/api.js +0 -431
  38. package/dist/mcp/server/utils/config.js +0 -855
@@ -1,855 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __generator = (this && this.__generator) || function (thisArg, body) {
12
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
13
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
- function verb(n) { return function (v) { return step([n, v]); }; }
15
- function step(op) {
16
- if (f) throw new TypeError("Generator is already executing.");
17
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
- if (y = 0, t) op = [op[0] & 2, t.value];
20
- switch (op[0]) {
21
- case 0: case 1: t = op; break;
22
- case 4: _.label++; return { value: op[1], done: false };
23
- case 5: _.label++; y = op[1]; op = [0]; continue;
24
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
- default:
26
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
- if (t[2]) _.ops.pop();
31
- _.trys.pop(); continue;
32
- }
33
- op = body.call(thisArg, _);
34
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
- }
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.CLIConfig = void 0;
40
- var fs = require("fs/promises");
41
- var path = require("path");
42
- var os = require("os");
43
- var jwt_decode_1 = require("jwt-decode");
44
- var crypto_1 = require("crypto");
45
- var CLIConfig = /** @class */ (function () {
46
- function CLIConfig() {
47
- this.config = {};
48
- this.configDir = path.join(os.homedir(), '.maas');
49
- this.configPath = path.join(this.configDir, 'config.json');
50
- this.lockFile = path.join(this.configDir, 'config.lock');
51
- }
52
- CLIConfig.prototype.init = function () {
53
- return __awaiter(this, void 0, void 0, function () {
54
- var _a;
55
- return __generator(this, function (_b) {
56
- switch (_b.label) {
57
- case 0:
58
- _b.trys.push([0, 3, , 4]);
59
- return [4 /*yield*/, fs.mkdir(this.configDir, { recursive: true })];
60
- case 1:
61
- _b.sent();
62
- return [4 /*yield*/, this.load()];
63
- case 2:
64
- _b.sent();
65
- return [3 /*break*/, 4];
66
- case 3:
67
- _a = _b.sent();
68
- return [3 /*break*/, 4];
69
- case 4: return [2 /*return*/];
70
- }
71
- });
72
- });
73
- };
74
- CLIConfig.prototype.load = function () {
75
- return __awaiter(this, void 0, void 0, function () {
76
- var data, _a;
77
- return __generator(this, function (_b) {
78
- switch (_b.label) {
79
- case 0:
80
- _b.trys.push([0, 3, , 4]);
81
- return [4 /*yield*/, fs.readFile(this.configPath, 'utf-8')];
82
- case 1:
83
- data = _b.sent();
84
- this.config = JSON.parse(data);
85
- // Handle version migration if needed
86
- return [4 /*yield*/, this.migrateConfigIfNeeded()];
87
- case 2:
88
- // Handle version migration if needed
89
- _b.sent();
90
- return [3 /*break*/, 4];
91
- case 3:
92
- _a = _b.sent();
93
- this.config = {};
94
- // Set version for new config
95
- this.config.version = CLIConfig.CONFIG_VERSION;
96
- return [3 /*break*/, 4];
97
- case 4: return [2 /*return*/];
98
- }
99
- });
100
- });
101
- };
102
- CLIConfig.prototype.migrateConfigIfNeeded = function () {
103
- return __awaiter(this, void 0, void 0, function () {
104
- var currentVersion;
105
- return __generator(this, function (_a) {
106
- switch (_a.label) {
107
- case 0:
108
- currentVersion = this.config.version;
109
- if (!!currentVersion) return [3 /*break*/, 2];
110
- // Legacy config without version, migrate to current version
111
- this.config.version = CLIConfig.CONFIG_VERSION;
112
- // Perform any necessary migrations for legacy configs
113
- // For now, just ensure the version is set
114
- return [4 /*yield*/, this.save()];
115
- case 1:
116
- // Perform any necessary migrations for legacy configs
117
- // For now, just ensure the version is set
118
- _a.sent();
119
- return [3 /*break*/, 4];
120
- case 2:
121
- if (!(currentVersion !== CLIConfig.CONFIG_VERSION)) return [3 /*break*/, 4];
122
- // Future version migrations would go here
123
- // For now, just update the version
124
- this.config.version = CLIConfig.CONFIG_VERSION;
125
- return [4 /*yield*/, this.save()];
126
- case 3:
127
- _a.sent();
128
- _a.label = 4;
129
- case 4: return [2 /*return*/];
130
- }
131
- });
132
- });
133
- };
134
- CLIConfig.prototype.save = function () {
135
- return __awaiter(this, void 0, void 0, function () {
136
- return __generator(this, function (_a) {
137
- switch (_a.label) {
138
- case 0: return [4 /*yield*/, this.atomicSave()];
139
- case 1:
140
- _a.sent();
141
- return [2 /*return*/];
142
- }
143
- });
144
- });
145
- };
146
- CLIConfig.prototype.atomicSave = function () {
147
- return __awaiter(this, void 0, void 0, function () {
148
- var lockAcquired, tempPath;
149
- return __generator(this, function (_a) {
150
- switch (_a.label) {
151
- case 0: return [4 /*yield*/, fs.mkdir(this.configDir, { recursive: true })];
152
- case 1:
153
- _a.sent();
154
- return [4 /*yield*/, this.acquireLock()];
155
- case 2:
156
- lockAcquired = _a.sent();
157
- if (!lockAcquired) {
158
- throw new Error('Could not acquire configuration lock. Another process may be modifying the config.');
159
- }
160
- _a.label = 3;
161
- case 3:
162
- _a.trys.push([3, , 6, 8]);
163
- // Set version and update timestamp
164
- this.config.version = CLIConfig.CONFIG_VERSION;
165
- this.config.lastUpdated = new Date().toISOString();
166
- tempPath = "".concat(this.configPath, ".tmp.").concat((0, crypto_1.randomUUID)());
167
- // Write to temporary file first
168
- return [4 /*yield*/, fs.writeFile(tempPath, JSON.stringify(this.config, null, 2), 'utf-8')];
169
- case 4:
170
- // Write to temporary file first
171
- _a.sent();
172
- // Atomic rename - this is the critical atomic operation
173
- return [4 /*yield*/, fs.rename(tempPath, this.configPath)];
174
- case 5:
175
- // Atomic rename - this is the critical atomic operation
176
- _a.sent();
177
- return [3 /*break*/, 8];
178
- case 6:
179
- // Always release the lock
180
- return [4 /*yield*/, this.releaseLock()];
181
- case 7:
182
- // Always release the lock
183
- _a.sent();
184
- return [7 /*endfinally*/];
185
- case 8: return [2 /*return*/];
186
- }
187
- });
188
- });
189
- };
190
- CLIConfig.prototype.backupConfig = function () {
191
- return __awaiter(this, void 0, void 0, function () {
192
- var timestamp, backupPath, error_1;
193
- return __generator(this, function (_a) {
194
- switch (_a.label) {
195
- case 0:
196
- timestamp = new Date().toISOString().replace(/[:.]/g, '-');
197
- backupPath = path.join(this.configDir, "config.backup.".concat(timestamp, ".json"));
198
- _a.label = 1;
199
- case 1:
200
- _a.trys.push([1, 4, , 7]);
201
- // Check if config exists before backing up
202
- return [4 /*yield*/, fs.access(this.configPath)];
203
- case 2:
204
- // Check if config exists before backing up
205
- _a.sent();
206
- return [4 /*yield*/, fs.copyFile(this.configPath, backupPath)];
207
- case 3:
208
- _a.sent();
209
- return [2 /*return*/, backupPath];
210
- case 4:
211
- error_1 = _a.sent();
212
- if (!(error_1.code === 'ENOENT')) return [3 /*break*/, 6];
213
- // Config doesn't exist, create empty backup
214
- return [4 /*yield*/, fs.writeFile(backupPath, JSON.stringify({}, null, 2))];
215
- case 5:
216
- // Config doesn't exist, create empty backup
217
- _a.sent();
218
- return [2 /*return*/, backupPath];
219
- case 6: throw error_1;
220
- case 7: return [2 /*return*/];
221
- }
222
- });
223
- });
224
- };
225
- CLIConfig.prototype.acquireLock = function () {
226
- return __awaiter(this, arguments, void 0, function (timeoutMs) {
227
- var startTime, error_2, pidStr, pid, _a, _b;
228
- if (timeoutMs === void 0) { timeoutMs = 5000; }
229
- return __generator(this, function (_c) {
230
- switch (_c.label) {
231
- case 0:
232
- startTime = Date.now();
233
- _c.label = 1;
234
- case 1:
235
- if (!(Date.now() - startTime < timeoutMs)) return [3 /*break*/, 18];
236
- _c.label = 2;
237
- case 2:
238
- _c.trys.push([2, 4, , 17]);
239
- // Try to create lock file exclusively
240
- return [4 /*yield*/, fs.writeFile(this.lockFile, process.pid.toString(), { flag: 'wx' })];
241
- case 3:
242
- // Try to create lock file exclusively
243
- _c.sent();
244
- return [2 /*return*/, true];
245
- case 4:
246
- error_2 = _c.sent();
247
- if (!(error_2.code === 'EEXIST')) return [3 /*break*/, 15];
248
- _c.label = 5;
249
- case 5:
250
- _c.trys.push([5, 12, , 14]);
251
- return [4 /*yield*/, fs.readFile(this.lockFile, 'utf-8')];
252
- case 6:
253
- pidStr = _c.sent();
254
- pid = parseInt(pidStr.trim());
255
- if (!!isNaN(pid)) return [3 /*break*/, 11];
256
- _c.label = 7;
257
- case 7:
258
- _c.trys.push([7, 9, , 11]);
259
- // Check if process is still running (works on Unix-like systems)
260
- process.kill(pid, 0);
261
- // Process is running, wait and retry
262
- return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 100); })];
263
- case 8:
264
- // Process is running, wait and retry
265
- _c.sent();
266
- return [3 /*break*/, 1];
267
- case 9:
268
- _a = _c.sent();
269
- // Process is not running, remove stale lock
270
- return [4 /*yield*/, fs.unlink(this.lockFile).catch(function () { })];
271
- case 10:
272
- // Process is not running, remove stale lock
273
- _c.sent();
274
- return [3 /*break*/, 1];
275
- case 11: return [3 /*break*/, 14];
276
- case 12:
277
- _b = _c.sent();
278
- // Can't read lock file, remove it and retry
279
- return [4 /*yield*/, fs.unlink(this.lockFile).catch(function () { })];
280
- case 13:
281
- // Can't read lock file, remove it and retry
282
- _c.sent();
283
- return [3 /*break*/, 1];
284
- case 14: return [3 /*break*/, 16];
285
- case 15: throw error_2;
286
- case 16: return [3 /*break*/, 17];
287
- case 17: return [3 /*break*/, 1];
288
- case 18: return [2 /*return*/, false];
289
- }
290
- });
291
- });
292
- };
293
- CLIConfig.prototype.releaseLock = function () {
294
- return __awaiter(this, void 0, void 0, function () {
295
- var _a;
296
- return __generator(this, function (_b) {
297
- switch (_b.label) {
298
- case 0:
299
- _b.trys.push([0, 2, , 3]);
300
- return [4 /*yield*/, fs.unlink(this.lockFile)];
301
- case 1:
302
- _b.sent();
303
- return [3 /*break*/, 3];
304
- case 2:
305
- _a = _b.sent();
306
- return [3 /*break*/, 3];
307
- case 3: return [2 /*return*/];
308
- }
309
- });
310
- });
311
- };
312
- CLIConfig.prototype.getApiUrl = function () {
313
- return process.env.MEMORY_API_URL ||
314
- this.config.apiUrl ||
315
- 'https://api.lanonasis.com/api/v1';
316
- };
317
- // Service Discovery Integration
318
- CLIConfig.prototype.discoverServices = function () {
319
- return __awaiter(this, void 0, void 0, function () {
320
- var axios, discoveryUrl, response, discovered, _a;
321
- var _b, _c, _d, _e, _f;
322
- return __generator(this, function (_g) {
323
- switch (_g.label) {
324
- case 0:
325
- _g.trys.push([0, 4, , 6]);
326
- return [4 /*yield*/, Promise.resolve().then(function () { return require('axios'); })];
327
- case 1:
328
- axios = (_g.sent()).default;
329
- discoveryUrl = 'https://mcp.lanonasis.com/.well-known/onasis.json';
330
- return [4 /*yield*/, axios.get(discoveryUrl)];
331
- case 2:
332
- response = _g.sent();
333
- discovered = response.data;
334
- this.config.discoveredServices = {
335
- auth_base: ((_c = (_b = discovered.auth) === null || _b === void 0 ? void 0 : _b.login) === null || _c === void 0 ? void 0 : _c.replace('/auth/login', '')) || 'https://api.lanonasis.com',
336
- memory_base: 'https://api.lanonasis.com/api/v1',
337
- mcp_base: ((_d = discovered.endpoints) === null || _d === void 0 ? void 0 : _d.http) || 'https://mcp.lanonasis.com/api/v1',
338
- mcp_ws_base: ((_e = discovered.endpoints) === null || _e === void 0 ? void 0 : _e.websocket) || 'wss://mcp.lanonasis.com/ws',
339
- mcp_sse_base: ((_f = discovered.endpoints) === null || _f === void 0 ? void 0 : _f.sse) || 'https://mcp.lanonasis.com/api/v1/events',
340
- project_scope: 'lanonasis-maas'
341
- };
342
- return [4 /*yield*/, this.save()];
343
- case 3:
344
- _g.sent();
345
- return [3 /*break*/, 6];
346
- case 4:
347
- _a = _g.sent();
348
- // Service discovery failed, use fallback defaults
349
- if (process.env.CLI_VERBOSE === 'true') {
350
- console.log('Service discovery failed, using fallback defaults');
351
- }
352
- // Set fallback service endpoints to prevent double slash issues
353
- // Use mcp.lanonasis.com for MCP services (proxied to port 3001)
354
- this.config.discoveredServices = {
355
- auth_base: 'https://api.lanonasis.com', // CLI auth goes to central auth system
356
- memory_base: 'https://api.lanonasis.com/api/v1', // Memory via onasis-core
357
- mcp_base: 'https://mcp.lanonasis.com/api/v1', // MCP HTTP/REST
358
- mcp_ws_base: 'wss://mcp.lanonasis.com/ws', // MCP WebSocket
359
- mcp_sse_base: 'https://mcp.lanonasis.com/api/v1/events', // MCP SSE
360
- project_scope: 'lanonasis-maas' // Correct project scope
361
- };
362
- return [4 /*yield*/, this.save()];
363
- case 5:
364
- _g.sent();
365
- return [3 /*break*/, 6];
366
- case 6: return [2 /*return*/];
367
- }
368
- });
369
- });
370
- };
371
- CLIConfig.prototype.getDiscoveredApiUrl = function () {
372
- var _a;
373
- return ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.auth_base) || this.getApiUrl();
374
- };
375
- // Enhanced authentication support
376
- CLIConfig.prototype.setVendorKey = function (vendorKey) {
377
- return __awaiter(this, void 0, void 0, function () {
378
- return __generator(this, function (_a) {
379
- switch (_a.label) {
380
- case 0:
381
- // Validate vendor key format (pk_*.sk_*)
382
- if (!vendorKey.match(/^pk_[a-zA-Z0-9]+\.sk_[a-zA-Z0-9]+$/)) {
383
- throw new Error('Invalid vendor key format. Expected: pk_xxx.sk_xxx');
384
- }
385
- // Server-side validation
386
- return [4 /*yield*/, this.validateVendorKeyWithServer(vendorKey)];
387
- case 1:
388
- // Server-side validation
389
- _a.sent();
390
- this.config.vendorKey = vendorKey;
391
- this.config.authMethod = 'vendor_key';
392
- this.config.lastValidated = new Date().toISOString();
393
- return [4 /*yield*/, this.resetFailureCount()];
394
- case 2:
395
- _a.sent(); // Reset failure count on successful auth
396
- return [4 /*yield*/, this.save()];
397
- case 3:
398
- _a.sent();
399
- return [2 /*return*/];
400
- }
401
- });
402
- });
403
- };
404
- CLIConfig.prototype.validateVendorKeyWithServer = function (vendorKey) {
405
- return __awaiter(this, void 0, void 0, function () {
406
- var axios, authBase, error_3;
407
- var _a, _b, _c;
408
- return __generator(this, function (_d) {
409
- switch (_d.label) {
410
- case 0:
411
- _d.trys.push([0, 4, , 5]);
412
- return [4 /*yield*/, Promise.resolve().then(function () { return require('axios'); })];
413
- case 1:
414
- axios = (_d.sent()).default;
415
- // Ensure service discovery is done
416
- return [4 /*yield*/, this.discoverServices()];
417
- case 2:
418
- // Ensure service discovery is done
419
- _d.sent();
420
- authBase = ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.auth_base) || 'https://api.lanonasis.com';
421
- // Test vendor key with health endpoint
422
- return [4 /*yield*/, axios.get("".concat(authBase, "/api/v1/health"), {
423
- headers: {
424
- 'X-API-Key': vendorKey,
425
- 'X-Auth-Method': 'vendor_key',
426
- 'X-Project-Scope': 'lanonasis-maas'
427
- },
428
- timeout: 10000
429
- })];
430
- case 3:
431
- // Test vendor key with health endpoint
432
- _d.sent();
433
- return [3 /*break*/, 5];
434
- case 4:
435
- error_3 = _d.sent();
436
- if (((_b = error_3.response) === null || _b === void 0 ? void 0 : _b.status) === 401 || ((_c = error_3.response) === null || _c === void 0 ? void 0 : _c.status) === 403) {
437
- throw new Error('Invalid vendor key: Authentication failed with server');
438
- }
439
- else if (error_3.code === 'ECONNREFUSED' || error_3.code === 'ENOTFOUND') {
440
- throw new Error('Cannot validate vendor key: Server unreachable');
441
- }
442
- else {
443
- throw new Error("Vendor key validation failed: ".concat(error_3.message));
444
- }
445
- return [3 /*break*/, 5];
446
- case 5: return [2 /*return*/];
447
- }
448
- });
449
- });
450
- };
451
- CLIConfig.prototype.getVendorKey = function () {
452
- return this.config.vendorKey;
453
- };
454
- CLIConfig.prototype.hasVendorKey = function () {
455
- return !!this.config.vendorKey;
456
- };
457
- CLIConfig.prototype.setApiUrl = function (url) {
458
- return __awaiter(this, void 0, void 0, function () {
459
- return __generator(this, function (_a) {
460
- switch (_a.label) {
461
- case 0:
462
- this.config.apiUrl = url;
463
- return [4 /*yield*/, this.save()];
464
- case 1:
465
- _a.sent();
466
- return [2 /*return*/];
467
- }
468
- });
469
- });
470
- };
471
- CLIConfig.prototype.setToken = function (token) {
472
- return __awaiter(this, void 0, void 0, function () {
473
- var decoded;
474
- return __generator(this, function (_a) {
475
- switch (_a.label) {
476
- case 0:
477
- this.config.token = token;
478
- this.config.authMethod = 'jwt';
479
- this.config.lastValidated = new Date().toISOString();
480
- return [4 /*yield*/, this.resetFailureCount()];
481
- case 1:
482
- _a.sent(); // Reset failure count on successful auth
483
- // Decode token to get user info and expiry
484
- try {
485
- decoded = (0, jwt_decode_1.jwtDecode)(token);
486
- // Store token expiry
487
- if (typeof decoded.exp === 'number') {
488
- this.config.tokenExpiry = decoded.exp;
489
- }
490
- // Store user info
491
- this.config.user = {
492
- email: String(decoded.email || ''),
493
- organization_id: String(decoded.organizationId || ''),
494
- role: String(decoded.role || ''),
495
- plan: String(decoded.plan || '')
496
- };
497
- }
498
- catch (_b) {
499
- // Invalid token, don't store user info or expiry
500
- this.config.tokenExpiry = undefined;
501
- }
502
- return [4 /*yield*/, this.save()];
503
- case 2:
504
- _a.sent();
505
- return [2 /*return*/];
506
- }
507
- });
508
- });
509
- };
510
- CLIConfig.prototype.getToken = function () {
511
- return this.config.token;
512
- };
513
- CLIConfig.prototype.getCurrentUser = function () {
514
- return __awaiter(this, void 0, void 0, function () {
515
- return __generator(this, function (_a) {
516
- return [2 /*return*/, this.config.user];
517
- });
518
- });
519
- };
520
- CLIConfig.prototype.isAuthenticated = function () {
521
- return __awaiter(this, void 0, void 0, function () {
522
- var token, parts, lastPart, timestamp, thirtyDaysInMs, decoded, now;
523
- return __generator(this, function (_a) {
524
- token = this.getToken();
525
- if (!token)
526
- return [2 /*return*/, false];
527
- // Handle simple CLI tokens (format: cli_xxx_timestamp)
528
- if (token.startsWith('cli_')) {
529
- parts = token.split('_');
530
- if (parts.length >= 3) {
531
- lastPart = parts[parts.length - 1];
532
- timestamp = lastPart ? parseInt(lastPart) : NaN;
533
- if (!isNaN(timestamp)) {
534
- thirtyDaysInMs = 30 * 24 * 60 * 60 * 1000;
535
- return [2 /*return*/, (Date.now() - timestamp) < thirtyDaysInMs];
536
- }
537
- }
538
- // If we can't parse timestamp, assume valid (fallback)
539
- return [2 /*return*/, true];
540
- }
541
- // Handle JWT tokens
542
- try {
543
- decoded = (0, jwt_decode_1.jwtDecode)(token);
544
- now = Date.now() / 1000;
545
- return [2 /*return*/, typeof decoded.exp === 'number' && decoded.exp > now];
546
- }
547
- catch (_b) {
548
- return [2 /*return*/, false];
549
- }
550
- return [2 /*return*/];
551
- });
552
- });
553
- };
554
- CLIConfig.prototype.logout = function () {
555
- return __awaiter(this, void 0, void 0, function () {
556
- return __generator(this, function (_a) {
557
- switch (_a.label) {
558
- case 0:
559
- this.config.token = undefined;
560
- this.config.user = undefined;
561
- return [4 /*yield*/, this.save()];
562
- case 1:
563
- _a.sent();
564
- return [2 /*return*/];
565
- }
566
- });
567
- });
568
- };
569
- CLIConfig.prototype.clear = function () {
570
- return __awaiter(this, void 0, void 0, function () {
571
- return __generator(this, function (_a) {
572
- switch (_a.label) {
573
- case 0:
574
- this.config = {};
575
- return [4 /*yield*/, this.save()];
576
- case 1:
577
- _a.sent();
578
- return [2 /*return*/];
579
- }
580
- });
581
- });
582
- };
583
- CLIConfig.prototype.getConfigPath = function () {
584
- return this.configPath;
585
- };
586
- CLIConfig.prototype.exists = function () {
587
- return __awaiter(this, void 0, void 0, function () {
588
- var _a;
589
- return __generator(this, function (_b) {
590
- switch (_b.label) {
591
- case 0:
592
- _b.trys.push([0, 2, , 3]);
593
- return [4 /*yield*/, fs.access(this.configPath)];
594
- case 1:
595
- _b.sent();
596
- return [2 /*return*/, true];
597
- case 2:
598
- _a = _b.sent();
599
- return [2 /*return*/, false];
600
- case 3: return [2 /*return*/];
601
- }
602
- });
603
- });
604
- };
605
- // Enhanced credential validation methods
606
- CLIConfig.prototype.validateStoredCredentials = function () {
607
- return __awaiter(this, void 0, void 0, function () {
608
- var vendorKey, token, axios, authBase, headers, error_4;
609
- var _a;
610
- return __generator(this, function (_b) {
611
- switch (_b.label) {
612
- case 0:
613
- _b.trys.push([0, 6, , 8]);
614
- vendorKey = this.getVendorKey();
615
- token = this.getToken();
616
- if (!vendorKey && !token) {
617
- return [2 /*return*/, false];
618
- }
619
- return [4 /*yield*/, Promise.resolve().then(function () { return require('axios'); })];
620
- case 1:
621
- axios = (_b.sent()).default;
622
- // Ensure service discovery is done
623
- return [4 /*yield*/, this.discoverServices()];
624
- case 2:
625
- // Ensure service discovery is done
626
- _b.sent();
627
- authBase = ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.auth_base) || 'https://api.lanonasis.com';
628
- headers = {
629
- 'X-Project-Scope': 'lanonasis-maas'
630
- };
631
- if (vendorKey) {
632
- headers['X-API-Key'] = vendorKey;
633
- headers['X-Auth-Method'] = 'vendor_key';
634
- }
635
- else if (token) {
636
- headers['Authorization'] = "Bearer ".concat(token);
637
- headers['X-Auth-Method'] = 'jwt';
638
- }
639
- // Validate against server with health endpoint
640
- return [4 /*yield*/, axios.get("".concat(authBase, "/api/v1/health"), {
641
- headers: headers,
642
- timeout: 10000
643
- })];
644
- case 3:
645
- // Validate against server with health endpoint
646
- _b.sent();
647
- // Update last validated timestamp
648
- this.config.lastValidated = new Date().toISOString();
649
- return [4 /*yield*/, this.resetFailureCount()];
650
- case 4:
651
- _b.sent();
652
- return [4 /*yield*/, this.save()];
653
- case 5:
654
- _b.sent();
655
- return [2 /*return*/, true];
656
- case 6:
657
- error_4 = _b.sent();
658
- // Increment failure count
659
- return [4 /*yield*/, this.incrementFailureCount()];
660
- case 7:
661
- // Increment failure count
662
- _b.sent();
663
- return [2 /*return*/, false];
664
- case 8: return [2 /*return*/];
665
- }
666
- });
667
- });
668
- };
669
- CLIConfig.prototype.refreshTokenIfNeeded = function () {
670
- return __awaiter(this, void 0, void 0, function () {
671
- var token, decoded, now, exp, axios, authBase, response, error_5;
672
- var _a;
673
- return __generator(this, function (_b) {
674
- switch (_b.label) {
675
- case 0:
676
- token = this.getToken();
677
- if (!token) {
678
- return [2 /*return*/];
679
- }
680
- _b.label = 1;
681
- case 1:
682
- _b.trys.push([1, 7, , 9]);
683
- // Check if token is JWT and if it's close to expiry
684
- if (token.startsWith('cli_')) {
685
- // CLI tokens don't need refresh, they're long-lived
686
- return [2 /*return*/];
687
- }
688
- decoded = (0, jwt_decode_1.jwtDecode)(token);
689
- now = Date.now() / 1000;
690
- exp = typeof decoded.exp === 'number' ? decoded.exp : 0;
691
- if (!(exp > 0 && (exp - now) < 300)) return [3 /*break*/, 6];
692
- return [4 /*yield*/, Promise.resolve().then(function () { return require('axios'); })];
693
- case 2:
694
- axios = (_b.sent()).default;
695
- return [4 /*yield*/, this.discoverServices()];
696
- case 3:
697
- _b.sent();
698
- authBase = ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.auth_base) || 'https://api.lanonasis.com';
699
- return [4 /*yield*/, axios.post("".concat(authBase, "/v1/auth/refresh"), {}, {
700
- headers: {
701
- 'Authorization': "Bearer ".concat(token),
702
- 'X-Project-Scope': 'lanonasis-maas'
703
- },
704
- timeout: 10000
705
- })];
706
- case 4:
707
- response = _b.sent();
708
- if (!response.data.token) return [3 /*break*/, 6];
709
- return [4 /*yield*/, this.setToken(response.data.token)];
710
- case 5:
711
- _b.sent();
712
- _b.label = 6;
713
- case 6: return [3 /*break*/, 9];
714
- case 7:
715
- error_5 = _b.sent();
716
- // If refresh fails, mark credentials as potentially invalid
717
- return [4 /*yield*/, this.incrementFailureCount()];
718
- case 8:
719
- // If refresh fails, mark credentials as potentially invalid
720
- _b.sent();
721
- return [3 /*break*/, 9];
722
- case 9: return [2 /*return*/];
723
- }
724
- });
725
- });
726
- };
727
- CLIConfig.prototype.clearInvalidCredentials = function () {
728
- return __awaiter(this, void 0, void 0, function () {
729
- return __generator(this, function (_a) {
730
- switch (_a.label) {
731
- case 0:
732
- this.config.token = undefined;
733
- this.config.vendorKey = undefined;
734
- this.config.user = undefined;
735
- this.config.authMethod = undefined;
736
- this.config.tokenExpiry = undefined;
737
- this.config.lastValidated = undefined;
738
- this.config.authFailureCount = 0;
739
- this.config.lastAuthFailure = undefined;
740
- return [4 /*yield*/, this.save()];
741
- case 1:
742
- _a.sent();
743
- return [2 /*return*/];
744
- }
745
- });
746
- });
747
- };
748
- CLIConfig.prototype.incrementFailureCount = function () {
749
- return __awaiter(this, void 0, void 0, function () {
750
- return __generator(this, function (_a) {
751
- switch (_a.label) {
752
- case 0:
753
- this.config.authFailureCount = (this.config.authFailureCount || 0) + 1;
754
- this.config.lastAuthFailure = new Date().toISOString();
755
- return [4 /*yield*/, this.save()];
756
- case 1:
757
- _a.sent();
758
- return [2 /*return*/];
759
- }
760
- });
761
- });
762
- };
763
- CLIConfig.prototype.resetFailureCount = function () {
764
- return __awaiter(this, void 0, void 0, function () {
765
- return __generator(this, function (_a) {
766
- switch (_a.label) {
767
- case 0:
768
- this.config.authFailureCount = 0;
769
- this.config.lastAuthFailure = undefined;
770
- return [4 /*yield*/, this.save()];
771
- case 1:
772
- _a.sent();
773
- return [2 /*return*/];
774
- }
775
- });
776
- });
777
- };
778
- CLIConfig.prototype.getFailureCount = function () {
779
- return this.config.authFailureCount || 0;
780
- };
781
- CLIConfig.prototype.getLastAuthFailure = function () {
782
- return this.config.lastAuthFailure;
783
- };
784
- CLIConfig.prototype.shouldDelayAuth = function () {
785
- var failureCount = this.getFailureCount();
786
- return failureCount >= 3;
787
- };
788
- CLIConfig.prototype.getAuthDelayMs = function () {
789
- var failureCount = this.getFailureCount();
790
- if (failureCount < 3)
791
- return 0;
792
- // Progressive delays: 3 failures = 2s, 4 = 4s, 5 = 8s, 6+ = 16s max
793
- var baseDelay = 2000; // 2 seconds
794
- var maxDelay = 16000; // 16 seconds max
795
- var delay = Math.min(baseDelay * Math.pow(2, failureCount - 3), maxDelay);
796
- return delay;
797
- };
798
- // Generic get/set methods for MCP and other dynamic config
799
- CLIConfig.prototype.get = function (key) {
800
- return this.config[key];
801
- };
802
- CLIConfig.prototype.set = function (key, value) {
803
- this.config[key] = value;
804
- };
805
- CLIConfig.prototype.setAndSave = function (key, value) {
806
- return __awaiter(this, void 0, void 0, function () {
807
- return __generator(this, function (_a) {
808
- switch (_a.label) {
809
- case 0:
810
- this.set(key, value);
811
- return [4 /*yield*/, this.save()];
812
- case 1:
813
- _a.sent();
814
- return [2 /*return*/];
815
- }
816
- });
817
- });
818
- };
819
- // MCP-specific helpers
820
- CLIConfig.prototype.getMCPServerPath = function () {
821
- return this.config.mcpServerPath || path.join(process.cwd(), 'onasis-gateway/mcp-server/server.js');
822
- };
823
- CLIConfig.prototype.getMCPServerUrl = function () {
824
- var _a;
825
- return ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.mcp_ws_base) ||
826
- this.config.mcpServerUrl ||
827
- 'wss://mcp.lanonasis.com/ws';
828
- };
829
- CLIConfig.prototype.getMCPRestUrl = function () {
830
- var _a;
831
- return ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.mcp_base) ||
832
- 'https://mcp.lanonasis.com/api/v1';
833
- };
834
- CLIConfig.prototype.getMCPSSEUrl = function () {
835
- var _a;
836
- return ((_a = this.config.discoveredServices) === null || _a === void 0 ? void 0 : _a.mcp_sse_base) ||
837
- 'https://mcp.lanonasis.com/api/v1/events';
838
- };
839
- CLIConfig.prototype.shouldUseRemoteMCP = function () {
840
- var preference = this.config.mcpPreference || 'auto';
841
- switch (preference) {
842
- case 'remote':
843
- return true;
844
- case 'local':
845
- return false;
846
- case 'auto':
847
- default:
848
- // Use remote if authenticated, otherwise local
849
- return !!this.config.token;
850
- }
851
- };
852
- CLIConfig.CONFIG_VERSION = '1.0.0';
853
- return CLIConfig;
854
- }());
855
- exports.CLIConfig = CLIConfig;