@lanonasis/cli 3.3.15 → 3.4.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.
- package/README.md +57 -13
- package/dist/commands/auth.js +7 -7
- package/dist/commands/completion.js +2 -0
- package/dist/commands/config.js +4 -4
- package/dist/commands/enhanced-memory.js +1 -1
- package/dist/commands/mcp.js +15 -9
- package/dist/core/achievements.js +1 -1
- package/dist/core/power-mode.js +5 -3
- package/dist/core/welcome.js +7 -6
- package/dist/enhanced-cli.js +6 -3
- package/dist/index-simple.js +5 -1
- package/dist/index.js +5 -1
- package/dist/mcp/access-control.d.ts +1 -1
- package/dist/mcp/access-control.js +4 -4
- package/dist/mcp/client/enhanced-client.js +4 -5
- package/dist/mcp/schemas/tool-schemas.d.ts +1 -1
- package/dist/mcp/schemas/tool-schemas.js +1 -1
- package/dist/mcp/server/lanonasis-server.d.ts +2 -1
- package/dist/mcp/server/lanonasis-server.js +7 -5
- package/dist/mcp/transports/transport-manager.js +3 -3
- package/dist/mcp-server.js +3 -3
- package/dist/utils/config.js +34 -6
- package/dist/utils/mcp-client.d.ts +4 -2
- package/dist/utils/mcp-client.js +86 -42
- package/package.json +3 -3
- package/dist/__tests__/auth-persistence.test.d.ts +0 -1
- package/dist/__tests__/auth-persistence.test.js +0 -243
- package/dist/__tests__/cross-device-integration.test.d.ts +0 -1
- package/dist/__tests__/cross-device-integration.test.js +0 -305
- package/dist/__tests__/mcp-connection-reliability.test.d.ts +0 -1
- package/dist/__tests__/mcp-connection-reliability.test.js +0 -489
- package/dist/__tests__/setup.d.ts +0 -1
- package/dist/__tests__/setup.js +0 -26
- package/dist/mcp/server/mcp/server/lanonasis-server.js +0 -911
- package/dist/mcp/server/utils/api.js +0 -431
- package/dist/mcp/server/utils/config.js +0 -855
package/dist/index-simple.js
CHANGED
|
@@ -65,7 +65,11 @@ program
|
|
|
65
65
|
}
|
|
66
66
|
process.env.CLI_OUTPUT_FORMAT = opts.output;
|
|
67
67
|
// Auto-initialize MCP unless disabled
|
|
68
|
-
|
|
68
|
+
const isMcpFlow = actionCommand.name() === 'mcp' ||
|
|
69
|
+
actionCommand.parent?.name?.() === 'mcp' ||
|
|
70
|
+
actionCommand.name() === 'mcp-server' ||
|
|
71
|
+
actionCommand.parent?.name?.() === 'mcp-server';
|
|
72
|
+
if (opts.mcp !== false && !isMcpFlow && !['init', 'auth', 'login', 'health', 'status'].includes(actionCommand.name())) {
|
|
69
73
|
try {
|
|
70
74
|
const client = getMCPClient();
|
|
71
75
|
if (!client.isConnectedToServer()) {
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,11 @@ program
|
|
|
52
52
|
}
|
|
53
53
|
process.env.CLI_OUTPUT_FORMAT = opts.output;
|
|
54
54
|
// Auto-initialize MCP unless disabled
|
|
55
|
-
|
|
55
|
+
const isMcpFlow = actionCommand.name() === 'mcp' ||
|
|
56
|
+
actionCommand.parent?.name?.() === 'mcp' ||
|
|
57
|
+
actionCommand.name() === 'mcp-server' ||
|
|
58
|
+
actionCommand.parent?.name?.() === 'mcp-server';
|
|
59
|
+
if (opts.mcp !== false && !isMcpFlow && !['init', 'auth', 'login', 'health', 'status'].includes(actionCommand.name())) {
|
|
56
60
|
try {
|
|
57
61
|
const client = getMCPClient();
|
|
58
62
|
if (!client.isConnectedToServer()) {
|
|
@@ -50,7 +50,7 @@ export declare class MemoryAccessControl {
|
|
|
50
50
|
/**
|
|
51
51
|
* Revoke access to a memory or app
|
|
52
52
|
*/
|
|
53
|
-
revokeAccess(
|
|
53
|
+
revokeAccess(_userId: string, _appId: string, memoryId?: string): Promise<void>;
|
|
54
54
|
/**
|
|
55
55
|
* Get access logs for audit purposes
|
|
56
56
|
*/
|
|
@@ -123,8 +123,8 @@ export class MemoryAccessControl {
|
|
|
123
123
|
/**
|
|
124
124
|
* Revoke access to a memory or app
|
|
125
125
|
*/
|
|
126
|
-
async revokeAccess(
|
|
127
|
-
const key = `${
|
|
126
|
+
async revokeAccess(_userId, _appId, memoryId) {
|
|
127
|
+
const key = `${_userId}:${_appId}`;
|
|
128
128
|
const existingRules = this.accessRules.get(key) || [];
|
|
129
129
|
const updatedRules = existingRules.map(rule => {
|
|
130
130
|
if (!memoryId || rule.memory_id === memoryId) {
|
|
@@ -133,7 +133,7 @@ export class MemoryAccessControl {
|
|
|
133
133
|
return rule;
|
|
134
134
|
});
|
|
135
135
|
this.accessRules.set(key, updatedRules);
|
|
136
|
-
logger.info('Access revoked', { userId, appId, memoryId });
|
|
136
|
+
logger.info('Access revoked', { userId: _userId, appId: _appId, memoryId });
|
|
137
137
|
}
|
|
138
138
|
/**
|
|
139
139
|
* Get access logs for audit purposes
|
|
@@ -215,7 +215,7 @@ export class MemoryAccessControl {
|
|
|
215
215
|
return [];
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
|
-
async getSharedMemories(
|
|
218
|
+
async getSharedMemories(_userId, _appId) {
|
|
219
219
|
// This would implement logic to find memories shared with the user
|
|
220
220
|
// through explicit permissions or app-level sharing
|
|
221
221
|
return [];
|
|
@@ -115,7 +115,6 @@ export class EnhancedMCPClient extends EventEmitter {
|
|
|
115
115
|
// HTTP transport is not directly supported by MCP SDK
|
|
116
116
|
// Use stdio or websocket instead
|
|
117
117
|
throw new Error('HTTP transport not directly supported. Use websocket or stdio transport.');
|
|
118
|
-
break;
|
|
119
118
|
case 'websocket':
|
|
120
119
|
if (!config.url) {
|
|
121
120
|
throw new Error('URL required for websocket transport');
|
|
@@ -225,7 +224,7 @@ export class EnhancedMCPClient extends EventEmitter {
|
|
|
225
224
|
/**
|
|
226
225
|
* Select the best server for a tool based on availability and latency
|
|
227
226
|
*/
|
|
228
|
-
async selectBestServer(
|
|
227
|
+
async selectBestServer(_toolName) {
|
|
229
228
|
const availableServers = Array.from(this.clients.keys()).filter(name => {
|
|
230
229
|
const status = this.connectionStatus.get(name);
|
|
231
230
|
return status?.status === 'connected';
|
|
@@ -240,7 +239,7 @@ export class EnhancedMCPClient extends EventEmitter {
|
|
|
240
239
|
/**
|
|
241
240
|
* Select a failover server
|
|
242
241
|
*/
|
|
243
|
-
async selectFailoverServer(excludeServer,
|
|
242
|
+
async selectFailoverServer(excludeServer, _toolName) {
|
|
244
243
|
const availableServers = Array.from(this.clients.keys()).filter(name => {
|
|
245
244
|
const status = this.connectionStatus.get(name);
|
|
246
245
|
return name !== excludeServer && status?.status === 'connected';
|
|
@@ -318,7 +317,7 @@ export class EnhancedMCPClient extends EventEmitter {
|
|
|
318
317
|
/**
|
|
319
318
|
* Get server configuration (placeholder - should be stored during connect)
|
|
320
319
|
*/
|
|
321
|
-
getServerConfig(
|
|
320
|
+
getServerConfig(_serverName) {
|
|
322
321
|
// TODO: Store and retrieve server configs
|
|
323
322
|
return null;
|
|
324
323
|
}
|
|
@@ -343,7 +342,7 @@ export class EnhancedMCPClient extends EventEmitter {
|
|
|
343
342
|
await client.close();
|
|
344
343
|
console.log(chalk.gray(`Disconnected from ${name}`));
|
|
345
344
|
}
|
|
346
|
-
catch
|
|
345
|
+
catch {
|
|
347
346
|
console.log(chalk.yellow(`Warning: Error disconnecting from ${name}`));
|
|
348
347
|
}
|
|
349
348
|
}
|
|
@@ -371,7 +371,7 @@ export declare class SchemaValidator {
|
|
|
371
371
|
/**
|
|
372
372
|
* Get schema as JSON Schema for documentation
|
|
373
373
|
*/
|
|
374
|
-
static toJsonSchema(
|
|
374
|
+
static toJsonSchema(_schema: z.ZodSchema<any>): any;
|
|
375
375
|
}
|
|
376
376
|
export declare const MCPSchemas: {
|
|
377
377
|
memory: {
|
|
@@ -333,7 +333,7 @@ export class SchemaValidator {
|
|
|
333
333
|
/**
|
|
334
334
|
* Get schema as JSON Schema for documentation
|
|
335
335
|
*/
|
|
336
|
-
static toJsonSchema(
|
|
336
|
+
static toJsonSchema(_schema) {
|
|
337
337
|
// This would require zodToJsonSchema package
|
|
338
338
|
// For now, return a simplified version
|
|
339
339
|
return {
|
|
@@ -600,9 +600,10 @@ Please choose an option (1-4):`
|
|
|
600
600
|
});
|
|
601
601
|
} /**
|
|
602
602
|
|
|
603
|
-
|
|
603
|
+
/**
|
|
604
|
+
* Handle tool calls
|
|
604
605
|
*/
|
|
605
|
-
async handleToolCall(name, args,
|
|
606
|
+
async handleToolCall(name, args, _clientId) {
|
|
606
607
|
// Ensure we're initialized
|
|
607
608
|
if (!this.apiClient) {
|
|
608
609
|
await this.initialize();
|
|
@@ -666,7 +667,7 @@ Please choose an option (1-4):`
|
|
|
666
667
|
// Transport management operations
|
|
667
668
|
case 'transport_status':
|
|
668
669
|
return this.getTransportStatus();
|
|
669
|
-
case 'transport_test':
|
|
670
|
+
case 'transport_test': {
|
|
670
671
|
if (!args.transport) {
|
|
671
672
|
throw new Error('transport is required');
|
|
672
673
|
}
|
|
@@ -676,6 +677,7 @@ Please choose an option (1-4):`
|
|
|
676
677
|
available: isAvailable,
|
|
677
678
|
tested_at: new Date().toISOString()
|
|
678
679
|
};
|
|
680
|
+
}
|
|
679
681
|
case 'transport_reset_failures':
|
|
680
682
|
if (args.transport) {
|
|
681
683
|
this.transportFailures.delete(args.transport);
|
|
@@ -1178,7 +1180,7 @@ Please choose an option (1-4):`
|
|
|
1178
1180
|
}
|
|
1179
1181
|
return true;
|
|
1180
1182
|
}
|
|
1181
|
-
catch
|
|
1183
|
+
catch {
|
|
1182
1184
|
return false;
|
|
1183
1185
|
}
|
|
1184
1186
|
}
|
|
@@ -1199,7 +1201,7 @@ Please choose an option (1-4):`
|
|
|
1199
1201
|
}
|
|
1200
1202
|
return true;
|
|
1201
1203
|
}
|
|
1202
|
-
catch
|
|
1204
|
+
catch {
|
|
1203
1205
|
return false;
|
|
1204
1206
|
}
|
|
1205
1207
|
}
|
|
@@ -162,7 +162,7 @@ class WebSocketTransport extends EventEmitter {
|
|
|
162
162
|
const message = JSON.parse(data.toString());
|
|
163
163
|
this.emit('message', message);
|
|
164
164
|
}
|
|
165
|
-
catch
|
|
165
|
+
catch {
|
|
166
166
|
this.emit('error', new Error('Failed to parse WebSocket message'));
|
|
167
167
|
}
|
|
168
168
|
});
|
|
@@ -270,7 +270,7 @@ class SSETransport extends EventEmitter {
|
|
|
270
270
|
const data = JSON.parse(event.data);
|
|
271
271
|
this.emit('message', data);
|
|
272
272
|
}
|
|
273
|
-
catch
|
|
273
|
+
catch {
|
|
274
274
|
this.emit('error', new Error('Failed to parse SSE message'));
|
|
275
275
|
}
|
|
276
276
|
};
|
|
@@ -282,7 +282,7 @@ class SSETransport extends EventEmitter {
|
|
|
282
282
|
};
|
|
283
283
|
});
|
|
284
284
|
}
|
|
285
|
-
async send(
|
|
285
|
+
async send(_data) {
|
|
286
286
|
// SSE is receive-only, but we can send data via HTTP POST
|
|
287
287
|
throw new Error('SSE transport is read-only. Use HTTP for sending data.');
|
|
288
288
|
}
|
package/dist/mcp-server.js
CHANGED
|
@@ -20,7 +20,7 @@ export class CLIMCPServer {
|
|
|
20
20
|
*/
|
|
21
21
|
async start(options = {}) {
|
|
22
22
|
await this.config.init();
|
|
23
|
-
const {
|
|
23
|
+
const { useRemote = this.config.shouldUseRemoteMCP() } = options;
|
|
24
24
|
if (useRemote) {
|
|
25
25
|
await this.startRemoteMCP(options);
|
|
26
26
|
}
|
|
@@ -33,8 +33,8 @@ export class CLIMCPServer {
|
|
|
33
33
|
*/
|
|
34
34
|
async startLocalMCP(options) {
|
|
35
35
|
const { mode, port, verbose } = options;
|
|
36
|
-
// Path to
|
|
37
|
-
const mcpServerPath = join(__dirname, '../../../mcp-server/
|
|
36
|
+
// Path to production MCP server (uses CommonJS, no build needed)
|
|
37
|
+
const mcpServerPath = join(__dirname, '../../../mcp-server/src/production-mcp-server.cjs');
|
|
38
38
|
const args = mode === 'http' ? ['--http'] : ['--stdio'];
|
|
39
39
|
if (verbose) {
|
|
40
40
|
console.error('🚀 Starting CLI-aligned MCP Server...');
|
package/dist/utils/config.js
CHANGED
|
@@ -446,6 +446,8 @@ export class CLIConfig {
|
|
|
446
446
|
catch {
|
|
447
447
|
// Invalid token, don't store user info or expiry
|
|
448
448
|
this.config.tokenExpiry = undefined;
|
|
449
|
+
// Mark as non-JWT (e.g., OAuth/CLI token)
|
|
450
|
+
this.config.authMethod = this.config.authMethod || 'oauth';
|
|
449
451
|
}
|
|
450
452
|
await this.save();
|
|
451
453
|
}
|
|
@@ -493,8 +495,32 @@ export class CLIConfig {
|
|
|
493
495
|
locallyValid = false;
|
|
494
496
|
}
|
|
495
497
|
}
|
|
496
|
-
// If
|
|
498
|
+
// If not locally valid, attempt server verification before failing
|
|
497
499
|
if (!locallyValid) {
|
|
500
|
+
try {
|
|
501
|
+
const axios = (await import('axios')).default;
|
|
502
|
+
const endpoints = [
|
|
503
|
+
'http://localhost:4000/v1/auth/verify-token',
|
|
504
|
+
'https://auth.lanonasis.com/v1/auth/verify-token',
|
|
505
|
+
'https://api.lanonasis.com/auth/verify'
|
|
506
|
+
];
|
|
507
|
+
for (const endpoint of endpoints) {
|
|
508
|
+
try {
|
|
509
|
+
const resp = await axios.post(endpoint, { token }, { timeout: 3000 });
|
|
510
|
+
if (resp.data?.valid === true) {
|
|
511
|
+
this.authCheckCache = { isValid: true, timestamp: Date.now() };
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch {
|
|
516
|
+
// try next endpoint
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
catch {
|
|
522
|
+
// ignore, will fall back to failure below
|
|
523
|
+
}
|
|
498
524
|
this.authCheckCache = { isValid: false, timestamp: Date.now() };
|
|
499
525
|
return false;
|
|
500
526
|
}
|
|
@@ -515,7 +541,7 @@ export class CLIConfig {
|
|
|
515
541
|
break;
|
|
516
542
|
}
|
|
517
543
|
}
|
|
518
|
-
catch
|
|
544
|
+
catch {
|
|
519
545
|
// Try next endpoint
|
|
520
546
|
continue;
|
|
521
547
|
}
|
|
@@ -527,7 +553,7 @@ export class CLIConfig {
|
|
|
527
553
|
this.authCheckCache = { isValid: true, timestamp: Date.now() };
|
|
528
554
|
return true;
|
|
529
555
|
}
|
|
530
|
-
catch
|
|
556
|
+
catch {
|
|
531
557
|
// If all server checks fail, fall back to local validation
|
|
532
558
|
// This allows offline usage but is less secure
|
|
533
559
|
console.warn('⚠️ Unable to verify token with server, using local validation');
|
|
@@ -591,7 +617,7 @@ export class CLIConfig {
|
|
|
591
617
|
await this.save();
|
|
592
618
|
return true;
|
|
593
619
|
}
|
|
594
|
-
catch
|
|
620
|
+
catch {
|
|
595
621
|
// Increment failure count
|
|
596
622
|
await this.incrementFailureCount();
|
|
597
623
|
return false;
|
|
@@ -630,7 +656,7 @@ export class CLIConfig {
|
|
|
630
656
|
}
|
|
631
657
|
}
|
|
632
658
|
}
|
|
633
|
-
catch
|
|
659
|
+
catch {
|
|
634
660
|
// If refresh fails, mark credentials as potentially invalid
|
|
635
661
|
await this.incrementFailureCount();
|
|
636
662
|
}
|
|
@@ -697,7 +723,9 @@ export class CLIConfig {
|
|
|
697
723
|
}
|
|
698
724
|
// MCP-specific helpers
|
|
699
725
|
getMCPServerPath() {
|
|
700
|
-
return
|
|
726
|
+
// Only return an explicitly configured path. No implicit bundled defaults.
|
|
727
|
+
// Returning an empty string if unset helps callers decide how to proceed safely.
|
|
728
|
+
return this.config.mcpServerPath || '';
|
|
701
729
|
}
|
|
702
730
|
getMCPServerUrl() {
|
|
703
731
|
return this.config.discoveredServices?.mcp_ws_base ||
|
|
@@ -4,6 +4,7 @@ interface MCPConnectionOptions {
|
|
|
4
4
|
useRemote?: boolean;
|
|
5
5
|
useWebSocket?: boolean;
|
|
6
6
|
connectionMode?: 'local' | 'remote' | 'websocket';
|
|
7
|
+
localArgs?: string[];
|
|
7
8
|
}
|
|
8
9
|
/**
|
|
9
10
|
* Interface for MCP tool arguments
|
|
@@ -24,10 +25,10 @@ export interface MCPToolResponse {
|
|
|
24
25
|
title?: string;
|
|
25
26
|
memory_type?: string;
|
|
26
27
|
length?: number;
|
|
27
|
-
forEach?: (callback: (item:
|
|
28
|
+
forEach?: (callback: (item: unknown, index: number) => void) => void;
|
|
28
29
|
code?: number;
|
|
29
30
|
message?: string;
|
|
30
|
-
response?:
|
|
31
|
+
response?: unknown;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
34
|
* Interface for MCP WebSocket messages
|
|
@@ -54,6 +55,7 @@ export declare class MCPClient {
|
|
|
54
55
|
private healthCheckInterval;
|
|
55
56
|
private connectionStartTime;
|
|
56
57
|
private lastHealthCheck;
|
|
58
|
+
private activeConnectionMode;
|
|
57
59
|
constructor();
|
|
58
60
|
/**
|
|
59
61
|
* Initialize the MCP client configuration
|