@lanonasis/cli 3.6.4 → 3.6.5

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 (41) hide show
  1. package/dist/commands/api-keys.d.ts +1 -2
  2. package/dist/commands/api-keys.js +78 -73
  3. package/dist/commands/auth.js +167 -160
  4. package/dist/commands/completion.js +39 -31
  5. package/dist/commands/config.js +201 -162
  6. package/dist/commands/enhanced-memory.js +17 -11
  7. package/dist/commands/guide.js +88 -79
  8. package/dist/commands/init.js +20 -14
  9. package/dist/commands/mcp.js +173 -142
  10. package/dist/commands/memory.js +83 -77
  11. package/dist/commands/organization.js +21 -15
  12. package/dist/commands/topics.js +58 -52
  13. package/dist/core/achievements.js +26 -19
  14. package/dist/core/architecture.js +59 -42
  15. package/dist/core/dashboard.js +81 -71
  16. package/dist/core/error-handler.js +39 -30
  17. package/dist/core/power-mode.js +53 -46
  18. package/dist/core/progress.js +44 -35
  19. package/dist/core/welcome.js +64 -56
  20. package/dist/enhanced-cli.js +58 -49
  21. package/dist/index-simple.js +112 -74
  22. package/dist/index.js +68 -63
  23. package/dist/mcp/access-control.js +17 -13
  24. package/dist/mcp/client/enhanced-client.js +23 -16
  25. package/dist/mcp/enhanced-server.js +14 -10
  26. package/dist/mcp/logger.js +6 -2
  27. package/dist/mcp/memory-state.js +17 -13
  28. package/dist/mcp/schemas/tool-schemas.d.ts +28 -28
  29. package/dist/mcp/schemas/tool-schemas.js +126 -122
  30. package/dist/mcp/server/lanonasis-server.js +51 -44
  31. package/dist/mcp/transports/transport-manager.js +25 -18
  32. package/dist/mcp/vector-store.js +10 -6
  33. package/dist/mcp-server.js +21 -17
  34. package/dist/utils/api.js +30 -21
  35. package/dist/utils/config.js +59 -13
  36. package/dist/utils/formatting.js +14 -6
  37. package/dist/utils/mcp-client.js +132 -77
  38. package/package.json +17 -93
  39. package/dist/completions/bash-completion.sh +0 -88
  40. package/dist/completions/fish-completion.fish +0 -132
  41. package/dist/completions/zsh-completion.zsh +0 -196
@@ -1,9 +1,45 @@
1
- import * as fs from 'fs/promises';
2
- import * as path from 'path';
3
- import * as os from 'os';
4
- import { jwtDecode } from 'jwt-decode';
5
- import { randomUUID } from 'crypto';
6
- export class CLIConfig {
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CLIConfig = void 0;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const jwt_decode_1 = require("jwt-decode");
41
+ const crypto_1 = require("crypto");
42
+ class CLIConfig {
7
43
  configDir;
8
44
  configPath;
9
45
  config = {};
@@ -83,7 +119,7 @@ export class CLIConfig {
83
119
  this.config.version = CLIConfig.CONFIG_VERSION;
84
120
  this.config.lastUpdated = new Date().toISOString();
85
121
  // Create temporary file with unique name
86
- const tempPath = `${this.configPath}.tmp.${randomUUID()}`;
122
+ const tempPath = `${this.configPath}.tmp.${(0, crypto_1.randomUUID)()}`;
87
123
  // Write to temporary file first
88
124
  await fs.writeFile(tempPath, JSON.stringify(this.config, null, 2), 'utf-8');
89
125
  // Atomic rename - this is the critical atomic operation
@@ -178,14 +214,22 @@ export class CLIConfig {
178
214
  }
179
215
  const response = await axios.get(discoveryUrl, {
180
216
  timeout: 10000,
217
+ maxRedirects: 5,
218
+ proxy: false, // Bypass proxy to avoid redirect loops
181
219
  headers: {
182
220
  'User-Agent': 'Lanonasis-CLI/3.0.13'
183
221
  }
184
222
  });
185
223
  // Map discovery response to our config format
186
224
  const discovered = response.data;
225
+ // Extract auth base, but filter out localhost URLs
226
+ let authBase = discovered.auth?.base || discovered.auth?.login?.replace('/auth/login', '') || '';
227
+ // Override localhost with production auth endpoint
228
+ if (authBase.includes('localhost') || authBase.includes('127.0.0.1')) {
229
+ authBase = 'https://auth.lanonasis.com';
230
+ }
187
231
  this.config.discoveredServices = {
188
- auth_base: discovered.auth?.login?.replace('/auth/login', '') || 'https://api.lanonasis.com',
232
+ auth_base: authBase || 'https://auth.lanonasis.com',
189
233
  memory_base: 'https://api.lanonasis.com/api/v1',
190
234
  mcp_base: discovered.endpoints?.http || 'https://mcp.lanonasis.com/api/v1',
191
235
  mcp_ws_base: discovered.endpoints?.websocket || 'wss://mcp.lanonasis.com/ws',
@@ -389,7 +433,8 @@ export class CLIConfig {
389
433
  'X-Auth-Method': 'vendor_key',
390
434
  'X-Project-Scope': 'lanonasis-maas'
391
435
  },
392
- timeout: 10000
436
+ timeout: 10000,
437
+ proxy: false // Bypass proxy to avoid redirect loops
393
438
  });
394
439
  }
395
440
  catch (error) {
@@ -452,7 +497,7 @@ export class CLIConfig {
452
497
  await this.resetFailureCount(); // Reset failure count on successful auth
453
498
  // Decode token to get user info and expiry
454
499
  try {
455
- const decoded = jwtDecode(token);
500
+ const decoded = (0, jwt_decode_1.jwtDecode)(token);
456
501
  // Store token expiry
457
502
  if (typeof decoded.exp === 'number') {
458
503
  this.config.tokenExpiry = decoded.exp;
@@ -509,7 +554,7 @@ export class CLIConfig {
509
554
  else {
510
555
  // Handle JWT tokens
511
556
  try {
512
- const decoded = jwtDecode(token);
557
+ const decoded = (0, jwt_decode_1.jwtDecode)(token);
513
558
  const now = Date.now() / 1000;
514
559
  locallyValid = typeof decoded.exp === 'number' && decoded.exp > now;
515
560
  }
@@ -676,7 +721,7 @@ export class CLIConfig {
676
721
  // CLI tokens don't need refresh, they're long-lived
677
722
  return;
678
723
  }
679
- const decoded = jwtDecode(token);
724
+ const decoded = (0, jwt_decode_1.jwtDecode)(token);
680
725
  const now = Date.now() / 1000;
681
726
  const exp = typeof decoded.exp === 'number' ? decoded.exp : 0;
682
727
  // Refresh if token expires within 5 minutes
@@ -750,7 +795,7 @@ export class CLIConfig {
750
795
  async getDeviceId() {
751
796
  if (!this.config.deviceId) {
752
797
  // Generate a new device ID
753
- this.config.deviceId = randomUUID();
798
+ this.config.deviceId = (0, crypto_1.randomUUID)();
754
799
  await this.save();
755
800
  }
756
801
  return this.config.deviceId;
@@ -799,3 +844,4 @@ export class CLIConfig {
799
844
  }
800
845
  }
801
846
  }
847
+ exports.CLIConfig = CLIConfig;
@@ -1,4 +1,12 @@
1
- export function formatOutput(data, format = 'table') {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatOutput = formatOutput;
4
+ exports.formatBytes = formatBytes;
5
+ exports.truncateText = truncateText;
6
+ exports.formatDuration = formatDuration;
7
+ exports.formatDate = formatDate;
8
+ exports.formatTableData = formatTableData;
9
+ function formatOutput(data, format = 'table') {
2
10
  switch (format) {
3
11
  case 'json':
4
12
  console.log(JSON.stringify(data, null, 2));
@@ -12,7 +20,7 @@ export function formatOutput(data, format = 'table') {
12
20
  break;
13
21
  }
14
22
  }
15
- export function formatBytes(bytes) {
23
+ function formatBytes(bytes) {
16
24
  if (bytes === 0)
17
25
  return '0 Bytes';
18
26
  const k = 1024;
@@ -20,23 +28,23 @@ export function formatBytes(bytes) {
20
28
  const i = Math.floor(Math.log(bytes) / Math.log(k));
21
29
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
22
30
  }
23
- export function truncateText(text, maxLength) {
31
+ function truncateText(text, maxLength) {
24
32
  if (text.length <= maxLength)
25
33
  return text;
26
34
  return text.substring(0, maxLength - 3) + '...';
27
35
  }
28
- export function formatDuration(ms) {
36
+ function formatDuration(ms) {
29
37
  if (ms < 1000)
30
38
  return `${ms}ms`;
31
39
  if (ms < 60000)
32
40
  return `${(ms / 1000).toFixed(1)}s`;
33
41
  return `${(ms / 60000).toFixed(1)}m`;
34
42
  }
35
- export function formatDate(date) {
43
+ function formatDate(date) {
36
44
  const d = new Date(date);
37
45
  return d.toLocaleString();
38
46
  }
39
- export function formatTableData(data) {
47
+ function formatTableData(data) {
40
48
  return data.map(item => {
41
49
  if (Array.isArray(item))
42
50
  return item.map(String);
@@ -1,11 +1,51 @@
1
- import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
- import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
- import chalk from 'chalk';
4
- import { CLIConfig } from './config.js';
5
- import * as fs from 'fs';
6
- import { EventSource } from 'eventsource';
7
- import WebSocket from 'ws';
8
- export class MCPClient {
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.MCPClient = void 0;
40
+ exports.getMCPClient = getMCPClient;
41
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
42
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
43
+ const chalk_1 = __importDefault(require("chalk"));
44
+ const config_js_1 = require("./config.js");
45
+ const fs = __importStar(require("fs"));
46
+ const eventsource_1 = require("eventsource");
47
+ const ws_1 = __importDefault(require("ws"));
48
+ class MCPClient {
9
49
  client = null;
10
50
  config;
11
51
  isConnected = false;
@@ -18,7 +58,7 @@ export class MCPClient {
18
58
  lastHealthCheck = null;
19
59
  activeConnectionMode = 'local'; // Track actual connection mode
20
60
  constructor() {
21
- this.config = new CLIConfig();
61
+ this.config = new config_js_1.CLIConfig();
22
62
  }
23
63
  /**
24
64
  * Overrides the configuration directory used by the underlying CLI config.
@@ -94,10 +134,10 @@ export class MCPClient {
94
134
  'wss://mcp.lanonasis.com/ws';
95
135
  wsUrl = wsUrlValue;
96
136
  if (this.retryAttempts === 0) {
97
- console.log(chalk.cyan(`Connecting to WebSocket MCP server at ${wsUrl}...`));
137
+ console.log(chalk_1.default.cyan(`Connecting to WebSocket MCP server at ${wsUrl}...`));
98
138
  }
99
139
  else {
100
- console.log(chalk.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to WebSocket MCP server...`));
140
+ console.log(chalk_1.default.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to WebSocket MCP server...`));
101
141
  }
102
142
  // Initialize WebSocket connection
103
143
  await this.initializeWebSocket(wsUrl);
@@ -115,10 +155,10 @@ export class MCPClient {
115
155
  'https://mcp.lanonasis.com/api/v1';
116
156
  serverUrl = serverUrlValue;
117
157
  if (this.retryAttempts === 0) {
118
- console.log(chalk.cyan(`Connecting to remote MCP server at ${serverUrl}...`));
158
+ console.log(chalk_1.default.cyan(`Connecting to remote MCP server at ${serverUrl}...`));
119
159
  }
120
160
  else {
121
- console.log(chalk.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to remote MCP server...`));
161
+ console.log(chalk_1.default.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to remote MCP server...`));
122
162
  }
123
163
  // Initialize SSE connection for real-time updates
124
164
  await this.initializeSSE(serverUrl);
@@ -132,22 +172,22 @@ export class MCPClient {
132
172
  // Local MCP server connection requires explicit path via option or config
133
173
  serverPath = options.serverPath ?? this.config.get('mcpServerPath');
134
174
  if (!serverPath) {
135
- console.log(chalk.yellow('⚠️ No local MCP server path configured.'));
136
- console.log(chalk.cyan('💡 Prefer using WebSocket mode (default). Or configure a local path via:'));
137
- console.log(chalk.cyan(' lanonasis config set mcpServerPath /absolute/path/to/server.js'));
175
+ console.log(chalk_1.default.yellow('⚠️ No local MCP server path configured.'));
176
+ console.log(chalk_1.default.cyan('💡 Prefer using WebSocket mode (default). Or configure a local path via:'));
177
+ console.log(chalk_1.default.cyan(' lanonasis config set mcpServerPath /absolute/path/to/server.js'));
138
178
  throw new Error('Local MCP server path not provided');
139
179
  }
140
180
  // Check if the server file exists
141
181
  if (!fs.existsSync(serverPath)) {
142
- console.log(chalk.yellow(`⚠️ Local MCP server not found at ${serverPath}`));
143
- console.log(chalk.cyan('💡 For remote use WebSocket: lanonasis mcp connect --mode websocket --url wss://mcp.lanonasis.com/ws'));
182
+ console.log(chalk_1.default.yellow(`⚠️ Local MCP server not found at ${serverPath}`));
183
+ console.log(chalk_1.default.cyan('💡 For remote use WebSocket: lanonasis mcp connect --mode websocket --url wss://mcp.lanonasis.com/ws'));
144
184
  throw new Error(`MCP server not found at ${serverPath}`);
145
185
  }
146
186
  if (this.retryAttempts === 0) {
147
- console.log(chalk.cyan(`Connecting to local MCP server at ${serverPath}...`));
187
+ console.log(chalk_1.default.cyan(`Connecting to local MCP server at ${serverPath}...`));
148
188
  }
149
189
  else {
150
- console.log(chalk.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to local MCP server...`));
190
+ console.log(chalk_1.default.yellow(`Retry ${this.retryAttempts}/${this.maxRetries}: Connecting to local MCP server...`));
151
191
  }
152
192
  // Allow passing extra args to local server (e.g., --stdio) via options or env/config
153
193
  // Precedence: options.localArgs -> env.MCP_LOCAL_SERVER_ARGS -> config.mcpLocalArgs -> none
@@ -160,11 +200,11 @@ export class MCPClient {
160
200
  ? options.localArgs
161
201
  : (envArgs.length > 0 ? envArgs : configArgs);
162
202
  const args = [serverPath, ...extraArgs];
163
- const localTransport = new StdioClientTransport({
203
+ const localTransport = new stdio_js_1.StdioClientTransport({
164
204
  command: 'node',
165
205
  args
166
206
  });
167
- this.client = new Client({
207
+ this.client = new index_js_1.Client({
168
208
  name: '@lanonasis/cli',
169
209
  version: '3.0.1'
170
210
  });
@@ -172,7 +212,7 @@ export class MCPClient {
172
212
  this.isConnected = true;
173
213
  this.activeConnectionMode = 'local';
174
214
  this.retryAttempts = 0;
175
- console.log(chalk.green('✓ Connected to MCP server'));
215
+ console.log(chalk_1.default.green('✓ Connected to MCP server'));
176
216
  this.startHealthMonitoring();
177
217
  return true;
178
218
  }
@@ -183,7 +223,7 @@ export class MCPClient {
183
223
  ?? this.config.getMCPRestUrl()
184
224
  ?? 'https://mcp.lanonasis.com/api/v1';
185
225
  serverUrl = serverUrlValue;
186
- console.log(chalk.yellow(`Unknown connection mode '${String(connectionMode)}', falling back to remote at ${serverUrl}`));
226
+ console.log(chalk_1.default.yellow(`Unknown connection mode '${String(connectionMode)}', falling back to remote at ${serverUrl}`));
187
227
  await this.initializeSSE(serverUrl);
188
228
  this.isConnected = true;
189
229
  this.activeConnectionMode = 'remote';
@@ -204,23 +244,23 @@ export class MCPClient {
204
244
  // Check if this is an authentication error (don't retry these)
205
245
  if (this.isAuthenticationError(error)) {
206
246
  const authMsg = error?.message ?? '';
207
- console.error(chalk.red('Authentication failed:'), authMsg);
247
+ console.error(chalk_1.default.red('Authentication failed:'), authMsg);
208
248
  this.provideAuthenticationGuidance(error);
209
249
  this.isConnected = false;
210
250
  return false;
211
251
  }
212
252
  this.retryAttempts++;
213
253
  if (this.retryAttempts >= this.maxRetries) {
214
- console.error(chalk.red(`Failed to connect after ${this.maxRetries} attempts`));
254
+ console.error(chalk_1.default.red(`Failed to connect after ${this.maxRetries} attempts`));
215
255
  this.provideNetworkTroubleshootingGuidance(error);
216
256
  this.isConnected = false;
217
257
  return false;
218
258
  }
219
259
  // For network errors, retry with exponential backoff
220
260
  const delay = await this.exponentialBackoff(this.retryAttempts);
221
- console.log(chalk.yellow(`Network error, retrying in ${delay}ms... (${this.retryAttempts}/${this.maxRetries})`));
261
+ console.log(chalk_1.default.yellow(`Network error, retrying in ${delay}ms... (${this.retryAttempts}/${this.maxRetries})`));
222
262
  const message = error?.message ?? String(error);
223
- console.log(chalk.gray(`Error: ${message}`));
263
+ console.log(chalk_1.default.gray(`Error: ${message}`));
224
264
  await new Promise(resolve => setTimeout(resolve, delay));
225
265
  return this.connectWithRetry(options);
226
266
  }
@@ -243,61 +283,61 @@ export class MCPClient {
243
283
  * Provide authentication-specific guidance
244
284
  */
245
285
  provideAuthenticationGuidance(error) {
246
- console.log(chalk.yellow('\n🔐 Authentication Issue Detected:'));
286
+ console.log(chalk_1.default.yellow('\n🔐 Authentication Issue Detected:'));
247
287
  const msg = error?.message ?? '';
248
288
  if (msg.includes('AUTHENTICATION_REQUIRED')) {
249
- console.log(chalk.cyan('• No credentials found. Run: lanonasis auth login'));
250
- console.log(chalk.cyan('• Or set a vendor key: lanonasis auth login --vendor-key <your-key>'));
289
+ console.log(chalk_1.default.cyan('• No credentials found. Run: lanonasis auth login'));
290
+ console.log(chalk_1.default.cyan('• Or set a vendor key: lanonasis auth login --vendor-key <your-key>'));
251
291
  }
252
292
  else if (msg.includes('AUTHENTICATION_INVALID')) {
253
- console.log(chalk.cyan('• Invalid credentials. Confirm the vendor key matches your dashboard value'));
254
- console.log(chalk.cyan('• Try: lanonasis auth logout && lanonasis auth login'));
293
+ console.log(chalk_1.default.cyan('• Invalid credentials. Confirm the vendor key matches your dashboard value'));
294
+ console.log(chalk_1.default.cyan('• Try: lanonasis auth logout && lanonasis auth login'));
255
295
  }
256
296
  else if (msg.includes('expired')) {
257
- console.log(chalk.cyan('• Token expired. Re-authenticate: lanonasis auth login'));
258
- console.log(chalk.cyan('• Or refresh: lanonasis auth refresh (if available)'));
297
+ console.log(chalk_1.default.cyan('• Token expired. Re-authenticate: lanonasis auth login'));
298
+ console.log(chalk_1.default.cyan('• Or refresh: lanonasis auth refresh (if available)'));
259
299
  }
260
300
  else {
261
- console.log(chalk.cyan('• Check authentication status: lanonasis auth status'));
262
- console.log(chalk.cyan('• Re-authenticate: lanonasis auth login'));
263
- console.log(chalk.cyan('• Verify vendor key: lanonasis auth login --vendor-key <your-key>'));
301
+ console.log(chalk_1.default.cyan('• Check authentication status: lanonasis auth status'));
302
+ console.log(chalk_1.default.cyan('• Re-authenticate: lanonasis auth login'));
303
+ console.log(chalk_1.default.cyan('• Verify vendor key: lanonasis auth login --vendor-key <your-key>'));
264
304
  }
265
305
  }
266
306
  /**
267
307
  * Provide network troubleshooting guidance
268
308
  */
269
309
  provideNetworkTroubleshootingGuidance(_error) {
270
- console.log(chalk.yellow('\n🌐 Network Issue Detected:'));
310
+ console.log(chalk_1.default.yellow('\n🌐 Network Issue Detected:'));
271
311
  const msg = _error?.message ?? '';
272
312
  if (msg.includes('ECONNREFUSED') || msg.includes('connect ECONNREFUSED')) {
273
- console.log(chalk.cyan('• Connection refused. Service may be down:'));
274
- console.log(chalk.cyan(' - For remote: Check https://mcp.lanonasis.com/health'));
275
- console.log(chalk.cyan(' - For WebSocket: Check wss://mcp.lanonasis.com/ws'));
276
- console.log(chalk.cyan(' - For local: Install local MCP server'));
313
+ console.log(chalk_1.default.cyan('• Connection refused. Service may be down:'));
314
+ console.log(chalk_1.default.cyan(' - For remote: Check https://mcp.lanonasis.com/health'));
315
+ console.log(chalk_1.default.cyan(' - For WebSocket: Check wss://mcp.lanonasis.com/ws'));
316
+ console.log(chalk_1.default.cyan(' - For local: Install local MCP server'));
277
317
  }
278
318
  else if (msg.includes('timeout') || msg.includes('ETIMEDOUT')) {
279
- console.log(chalk.cyan('• Connection timeout. Check network:'));
280
- console.log(chalk.cyan(' - Verify internet connectivity'));
281
- console.log(chalk.cyan(' - Check firewall settings'));
282
- console.log(chalk.cyan(' - Try different connection mode: --mode remote'));
319
+ console.log(chalk_1.default.cyan('• Connection timeout. Check network:'));
320
+ console.log(chalk_1.default.cyan(' - Verify internet connectivity'));
321
+ console.log(chalk_1.default.cyan(' - Check firewall settings'));
322
+ console.log(chalk_1.default.cyan(' - Try different connection mode: --mode remote'));
283
323
  }
284
324
  else if (msg.includes('ENOTFOUND') || msg.includes('getaddrinfo')) {
285
- console.log(chalk.cyan('• DNS resolution failed:'));
286
- console.log(chalk.cyan(' - Check DNS settings'));
287
- console.log(chalk.cyan(' - Verify server URL is correct'));
288
- console.log(chalk.cyan(' - Try using IP address instead of hostname'));
325
+ console.log(chalk_1.default.cyan('• DNS resolution failed:'));
326
+ console.log(chalk_1.default.cyan(' - Check DNS settings'));
327
+ console.log(chalk_1.default.cyan(' - Verify server URL is correct'));
328
+ console.log(chalk_1.default.cyan(' - Try using IP address instead of hostname'));
289
329
  }
290
330
  else if (msg.includes('certificate') || msg.includes('SSL') || msg.includes('TLS')) {
291
- console.log(chalk.cyan('• SSL/TLS certificate issue:'));
292
- console.log(chalk.cyan(' - Check system time and date'));
293
- console.log(chalk.cyan(' - Update CA certificates'));
294
- console.log(chalk.cyan(' - Try different connection mode'));
331
+ console.log(chalk_1.default.cyan('• SSL/TLS certificate issue:'));
332
+ console.log(chalk_1.default.cyan(' - Check system time and date'));
333
+ console.log(chalk_1.default.cyan(' - Update CA certificates'));
334
+ console.log(chalk_1.default.cyan(' - Try different connection mode'));
295
335
  }
296
336
  else {
297
- console.log(chalk.cyan('• General network error:'));
298
- console.log(chalk.cyan(' - Check server status'));
299
- console.log(chalk.cyan(' - Verify network connectivity'));
300
- console.log(chalk.cyan(' - Try: lanonasis mcp diagnose (when available)'));
337
+ console.log(chalk_1.default.cyan('• General network error:'));
338
+ console.log(chalk_1.default.cyan(' - Check server status'));
339
+ console.log(chalk_1.default.cyan(' - Verify network connectivity'));
340
+ console.log(chalk_1.default.cyan(' - Try: lanonasis mcp diagnose (when available)'));
301
341
  }
302
342
  }
303
343
  /**
@@ -352,7 +392,7 @@ export class MCPClient {
352
392
  const currentTime = Math.floor(Date.now() / 1000);
353
393
  // Check if token is expired or expires within 5 minutes
354
394
  if (payload.exp && payload.exp < currentTime + 300) {
355
- console.log(chalk.yellow('Token is expired or expiring soon, attempting refresh...'));
395
+ console.log(chalk_1.default.yellow('Token is expired or expiring soon, attempting refresh...'));
356
396
  await this.refreshTokenIfNeeded();
357
397
  }
358
398
  }
@@ -380,7 +420,7 @@ export class MCPClient {
380
420
  });
381
421
  if (response.data.access_token) {
382
422
  await this.config.setAndSave('token', response.data.access_token);
383
- console.log(chalk.green('✓ Token refreshed successfully'));
423
+ console.log(chalk_1.default.green('✓ Token refreshed successfully'));
384
424
  }
385
425
  }
386
426
  catch {
@@ -420,18 +460,18 @@ export class MCPClient {
420
460
  const token = this.config.get('token');
421
461
  if (token) {
422
462
  // EventSource doesn't support headers directly, append token to URL
423
- this.sseConnection = new EventSource(`${sseUrl}?token=${encodeURIComponent(token)}`);
463
+ this.sseConnection = new eventsource_1.EventSource(`${sseUrl}?token=${encodeURIComponent(token)}`);
424
464
  this.sseConnection.onmessage = (event) => {
425
465
  try {
426
466
  const data = JSON.parse(event.data);
427
- console.log(chalk.blue('📡 Real-time update:'), data.type);
467
+ console.log(chalk_1.default.blue('📡 Real-time update:'), data.type);
428
468
  }
429
469
  catch {
430
470
  // Ignore parse errors
431
471
  }
432
472
  };
433
473
  this.sseConnection.onerror = () => {
434
- console.error(chalk.yellow('⚠️ SSE connection error (will retry)'));
474
+ console.error(chalk_1.default.yellow('⚠️ SSE connection error (will retry)'));
435
475
  };
436
476
  }
437
477
  }
@@ -451,14 +491,14 @@ export class MCPClient {
451
491
  this.wsConnection = null;
452
492
  }
453
493
  // Create new WebSocket connection with authentication
454
- this.wsConnection = new WebSocket(wsUrl, [], {
494
+ this.wsConnection = new ws_1.default(wsUrl, [], {
455
495
  headers: {
456
496
  'Authorization': `Bearer ${token}`,
457
497
  'X-API-Key': token
458
498
  }
459
499
  });
460
500
  this.wsConnection.on('open', () => {
461
- console.log(chalk.green('✅ Connected to MCP WebSocket server'));
501
+ console.log(chalk_1.default.green('✅ Connected to MCP WebSocket server'));
462
502
  // Send initialization message
463
503
  this.sendWebSocketMessage({
464
504
  id: 1,
@@ -479,22 +519,22 @@ export class MCPClient {
479
519
  this.wsConnection.on('message', (data) => {
480
520
  try {
481
521
  const message = JSON.parse(data.toString());
482
- console.log(chalk.blue('📡 MCP message:'), message.id, message.method || 'response');
522
+ console.log(chalk_1.default.blue('📡 MCP message:'), message.id, message.method || 'response');
483
523
  }
484
524
  catch (error) {
485
525
  console.error('Failed to parse WebSocket message:', error);
486
526
  }
487
527
  });
488
528
  this.wsConnection.on('error', (error) => {
489
- console.error(chalk.red('WebSocket error:'), error);
529
+ console.error(chalk_1.default.red('WebSocket error:'), error);
490
530
  reject(error);
491
531
  });
492
532
  this.wsConnection.on('close', (code, reason) => {
493
- console.log(chalk.yellow(`WebSocket connection closed (${code}): ${reason}`));
533
+ console.log(chalk_1.default.yellow(`WebSocket connection closed (${code}): ${reason}`));
494
534
  // Auto-reconnect after delay
495
535
  setTimeout(() => {
496
536
  if (this.isConnected) {
497
- console.log(chalk.blue('🔄 Attempting to reconnect to WebSocket...'));
537
+ console.log(chalk_1.default.blue('🔄 Attempting to reconnect to WebSocket...'));
498
538
  this.initializeWebSocket(wsUrl).catch(err => {
499
539
  console.error('Failed to reconnect:', err);
500
540
  });
@@ -562,7 +602,7 @@ export class MCPClient {
562
602
  }
563
603
  catch {
564
604
  const connectionMode = this.activeConnectionMode || 'remote';
565
- console.log(chalk.yellow(`⚠️ ${connectionMode} connection health check failed, attempting reconnection...`));
605
+ console.log(chalk_1.default.yellow(`⚠️ ${connectionMode} connection health check failed, attempting reconnection...`));
566
606
  await this.handleHealthCheckFailure();
567
607
  }
568
608
  }
@@ -570,7 +610,7 @@ export class MCPClient {
570
610
  * Check WebSocket connection health
571
611
  */
572
612
  async checkWebSocketHealth() {
573
- if (!this.wsConnection || this.wsConnection.readyState !== WebSocket.OPEN) {
613
+ if (!this.wsConnection || this.wsConnection.readyState !== ws_1.default.OPEN) {
574
614
  throw new Error('WebSocket connection not open');
575
615
  }
576
616
  // Send a ping message to check connectivity
@@ -631,7 +671,7 @@ export class MCPClient {
631
671
  const options = {
632
672
  connectionMode
633
673
  };
634
- console.log(chalk.yellow(`↻ Attempting reconnection using ${connectionMode} mode...`));
674
+ console.log(chalk_1.default.yellow(`↻ Attempting reconnection using ${connectionMode} mode...`));
635
675
  // Add specific URLs if available
636
676
  if (connectionMode === 'websocket') {
637
677
  options.serverUrl = this.config.get('mcpWebSocketUrl');
@@ -645,10 +685,10 @@ export class MCPClient {
645
685
  // Attempt reconnection
646
686
  const reconnected = await this.connect(options);
647
687
  if (reconnected) {
648
- console.log(chalk.green('✓ Reconnected to MCP server'));
688
+ console.log(chalk_1.default.green('✓ Reconnected to MCP server'));
649
689
  }
650
690
  else {
651
- console.log(chalk.red('✗ Failed to reconnect to MCP server'));
691
+ console.log(chalk_1.default.red('✗ Failed to reconnect to MCP server'));
652
692
  }
653
693
  }
654
694
  /**
@@ -823,7 +863,21 @@ export class MCPClient {
823
863
  * Get connection status details with health information
824
864
  */
825
865
  getConnectionStatus() {
826
- const connectionMode = this.activeConnectionMode;
866
+ // When disconnected, show the configured preference instead of the stale activeConnectionMode
867
+ let connectionMode = this.activeConnectionMode;
868
+ if (!this.isConnected) {
869
+ // Check configured preference
870
+ const mcpPreference = this.config.get('mcpPreference');
871
+ const mcpConnectionMode = this.config.get('mcpConnectionMode');
872
+ const preferRemote = this.config.get('mcpUseRemote');
873
+ connectionMode = mcpConnectionMode
874
+ ?? mcpPreference
875
+ ?? (preferRemote ? 'remote' : 'websocket');
876
+ // If preference is 'auto', resolve to default (websocket)
877
+ if (connectionMode === 'auto') {
878
+ connectionMode = 'websocket';
879
+ }
880
+ }
827
881
  let server;
828
882
  switch (connectionMode) {
829
883
  case 'websocket':
@@ -849,9 +903,10 @@ export class MCPClient {
849
903
  };
850
904
  }
851
905
  }
906
+ exports.MCPClient = MCPClient;
852
907
  // Singleton instance
853
908
  let mcpClientInstance = null;
854
- export function getMCPClient() {
909
+ function getMCPClient() {
855
910
  if (!mcpClientInstance) {
856
911
  mcpClientInstance = new MCPClient();
857
912
  }