@lanonasis/cli 1.5.0 → 1.5.1
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 +80 -357
- package/dist/commands/api-keys.d.ts +3 -0
- package/dist/commands/api-keys.js +812 -0
- package/dist/commands/auth.js +1 -151
- package/dist/commands/mcp.js +30 -37
- package/dist/commands/memory.js +53 -78
- package/dist/index-simple.js +522 -189
- package/dist/index.js +327 -221
- package/dist/mcp-server.d.ts +2 -0
- package/dist/mcp-server.js +519 -0
- package/dist/utils/api.d.ts +12 -2
- package/dist/utils/api.js +17 -0
- package/dist/utils/config.d.ts +0 -2
- package/dist/utils/config.js +2 -15
- package/dist/utils/formatting.d.ts +2 -0
- package/dist/utils/formatting.js +13 -0
- package/dist/utils/mcp-client.d.ts +49 -6
- package/dist/utils/mcp-client.js +161 -82
- package/package.json +17 -10
- package/dist/utils/completions.d.ts +0 -28
- package/dist/utils/completions.js +0 -276
- package/dist/utils/mcp-client.test.d.ts +0 -1
- package/dist/utils/mcp-client.test.js +0 -125
- package/dist/utils/output.d.ts +0 -23
- package/dist/utils/output.js +0 -97
- package/dist/utils/websocket-mcp-client.d.ts +0 -60
- package/dist/utils/websocket-mcp-client.js +0 -182
- package/dist/utils/websocket-mcp-client.test.d.ts +0 -1
- package/dist/utils/websocket-mcp-client.test.js +0 -126
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { CLIConfig } from './config.js';
|
|
3
|
-
export class TabCompletions {
|
|
4
|
-
config;
|
|
5
|
-
completionData;
|
|
6
|
-
constructor() {
|
|
7
|
-
this.config = new CLIConfig();
|
|
8
|
-
this.completionData = {
|
|
9
|
-
commands: [
|
|
10
|
-
'auth', 'login', 'logout', 'status',
|
|
11
|
-
'memory', 'mem', 'create', 'search', 'list', 'get', 'update', 'delete',
|
|
12
|
-
'topic', 'topics', 'org', 'organization',
|
|
13
|
-
'config', 'mcp', 'init', 'docs', 'help'
|
|
14
|
-
],
|
|
15
|
-
memory: {
|
|
16
|
-
types: ['context', 'project', 'knowledge', 'reference', 'personal', 'workflow'],
|
|
17
|
-
tags: [],
|
|
18
|
-
recentIds: []
|
|
19
|
-
},
|
|
20
|
-
topics: [],
|
|
21
|
-
organizations: []
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
async init() {
|
|
25
|
-
await this.config.init();
|
|
26
|
-
await this.loadDynamicCompletions();
|
|
27
|
-
}
|
|
28
|
-
async loadDynamicCompletions() {
|
|
29
|
-
const isAuth = await this.config.isAuthenticated();
|
|
30
|
-
if (!isAuth)
|
|
31
|
-
return;
|
|
32
|
-
try {
|
|
33
|
-
// Load recent memory IDs, tags, topics from API
|
|
34
|
-
// This would be enhanced with actual API calls
|
|
35
|
-
await this.loadRecentMemories();
|
|
36
|
-
await this.loadTopics();
|
|
37
|
-
await this.loadTags();
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
// Fail silently for completions
|
|
41
|
-
if (process.env.CLI_VERBOSE === 'true') {
|
|
42
|
-
console.error(chalk.gray('Failed to load completions data'));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async loadRecentMemories() {
|
|
47
|
-
// This would call the API to get recent memory IDs
|
|
48
|
-
// For now, we'll use mock data
|
|
49
|
-
this.completionData.memory.recentIds = [
|
|
50
|
-
'mem_12345', 'mem_67890', 'mem_abcdef'
|
|
51
|
-
];
|
|
52
|
-
}
|
|
53
|
-
async loadTopics() {
|
|
54
|
-
// This would call the API to get user's topics
|
|
55
|
-
this.completionData.topics = [
|
|
56
|
-
'work', 'personal', 'learning', 'projects'
|
|
57
|
-
];
|
|
58
|
-
}
|
|
59
|
-
async loadTags() {
|
|
60
|
-
// This would call the API to get commonly used tags
|
|
61
|
-
this.completionData.memory.tags = [
|
|
62
|
-
'important', 'todo', 'reference', 'meeting', 'idea'
|
|
63
|
-
];
|
|
64
|
-
}
|
|
65
|
-
getCompletions(line, position) {
|
|
66
|
-
const words = line.trim().split(/\s+/);
|
|
67
|
-
const currentWord = words[words.length - 1] || '';
|
|
68
|
-
// If we're at the beginning or after a space, suggest commands
|
|
69
|
-
if (words.length <= 1 || line.endsWith(' ')) {
|
|
70
|
-
return this.completionData.commands.filter(cmd => cmd.startsWith(currentWord.toLowerCase()));
|
|
71
|
-
}
|
|
72
|
-
const command = words[0];
|
|
73
|
-
const subcommand = words[1];
|
|
74
|
-
// Context-aware completions
|
|
75
|
-
switch (command) {
|
|
76
|
-
case 'memory':
|
|
77
|
-
case 'mem':
|
|
78
|
-
return this.getMemoryCompletions(words, currentWord);
|
|
79
|
-
case 'topic':
|
|
80
|
-
case 'topics':
|
|
81
|
-
return this.getTopicCompletions(words, currentWord);
|
|
82
|
-
case 'auth':
|
|
83
|
-
return ['login', 'logout', 'status'].filter(cmd => cmd.startsWith(currentWord));
|
|
84
|
-
case 'config':
|
|
85
|
-
return ['show', 'set', 'get', 'reset'].filter(cmd => cmd.startsWith(currentWord));
|
|
86
|
-
default:
|
|
87
|
-
return [];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
getMemoryCompletions(words, currentWord) {
|
|
91
|
-
if (words.length === 2) {
|
|
92
|
-
// Memory subcommands
|
|
93
|
-
return ['create', 'search', 'list', 'get', 'update', 'delete', 'stats']
|
|
94
|
-
.filter(cmd => cmd.startsWith(currentWord));
|
|
95
|
-
}
|
|
96
|
-
const subcommand = words[1];
|
|
97
|
-
switch (subcommand) {
|
|
98
|
-
case 'create':
|
|
99
|
-
return this.getCreateCompletions(words, currentWord);
|
|
100
|
-
case 'search':
|
|
101
|
-
return this.getSearchCompletions(words, currentWord);
|
|
102
|
-
case 'list':
|
|
103
|
-
return this.getListCompletions(words, currentWord);
|
|
104
|
-
case 'get':
|
|
105
|
-
case 'update':
|
|
106
|
-
case 'delete':
|
|
107
|
-
return this.completionData.memory.recentIds.filter(id => id.startsWith(currentWord));
|
|
108
|
-
default:
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
getCreateCompletions(words, currentWord) {
|
|
113
|
-
// Look for flags
|
|
114
|
-
const prevWord = words[words.length - 2];
|
|
115
|
-
if (prevWord === '--type' || prevWord === '-t') {
|
|
116
|
-
return this.completionData.memory.types.filter(type => type.startsWith(currentWord));
|
|
117
|
-
}
|
|
118
|
-
if (prevWord === '--tags') {
|
|
119
|
-
return this.completionData.memory.tags.filter(tag => tag.startsWith(currentWord));
|
|
120
|
-
}
|
|
121
|
-
// Suggest flags
|
|
122
|
-
if (currentWord.startsWith('-')) {
|
|
123
|
-
return ['--title', '--content', '--type', '--tags', '--topic']
|
|
124
|
-
.filter(flag => flag.startsWith(currentWord));
|
|
125
|
-
}
|
|
126
|
-
return [];
|
|
127
|
-
}
|
|
128
|
-
getSearchCompletions(words, currentWord) {
|
|
129
|
-
const prevWord = words[words.length - 2];
|
|
130
|
-
if (prevWord === '--type') {
|
|
131
|
-
return this.completionData.memory.types.filter(type => type.startsWith(currentWord));
|
|
132
|
-
}
|
|
133
|
-
if (prevWord === '--topic') {
|
|
134
|
-
return this.completionData.topics.filter(topic => topic.startsWith(currentWord));
|
|
135
|
-
}
|
|
136
|
-
if (currentWord.startsWith('-')) {
|
|
137
|
-
return ['--limit', '--type', '--topic', '--tags']
|
|
138
|
-
.filter(flag => flag.startsWith(currentWord));
|
|
139
|
-
}
|
|
140
|
-
return [];
|
|
141
|
-
}
|
|
142
|
-
getListCompletions(words, currentWord) {
|
|
143
|
-
const prevWord = words[words.length - 2];
|
|
144
|
-
if (prevWord === '--type') {
|
|
145
|
-
return this.completionData.memory.types.filter(type => type.startsWith(currentWord));
|
|
146
|
-
}
|
|
147
|
-
if (currentWord.startsWith('-')) {
|
|
148
|
-
return ['--limit', '--type', '--topic', '--tags']
|
|
149
|
-
.filter(flag => flag.startsWith(currentWord));
|
|
150
|
-
}
|
|
151
|
-
return [];
|
|
152
|
-
}
|
|
153
|
-
getTopicCompletions(words, currentWord) {
|
|
154
|
-
if (words.length === 2) {
|
|
155
|
-
return ['list', 'create', 'get', 'update', 'delete']
|
|
156
|
-
.filter(cmd => cmd.startsWith(currentWord));
|
|
157
|
-
}
|
|
158
|
-
const subcommand = words[1];
|
|
159
|
-
if (['get', 'update', 'delete'].includes(subcommand)) {
|
|
160
|
-
return this.completionData.topics.filter(topic => topic.startsWith(currentWord));
|
|
161
|
-
}
|
|
162
|
-
return [];
|
|
163
|
-
}
|
|
164
|
-
// Generate shell completion scripts
|
|
165
|
-
generateBashCompletion() {
|
|
166
|
-
return `
|
|
167
|
-
_lanonasis_completion() {
|
|
168
|
-
local cur prev opts
|
|
169
|
-
COMPREPLY=()
|
|
170
|
-
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
171
|
-
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
172
|
-
|
|
173
|
-
# Basic command completion
|
|
174
|
-
if [[ \${COMP_CWORD} == 1 ]] ; then
|
|
175
|
-
opts="auth login logout status memory mem topic topics config mcp init docs help"
|
|
176
|
-
COMPREPLY=( \$(compgen -W "\${opts}" -- \${cur}) )
|
|
177
|
-
return 0
|
|
178
|
-
fi
|
|
179
|
-
|
|
180
|
-
# Memory subcommands
|
|
181
|
-
if [[ \${COMP_WORDS[1]} == "memory" || \${COMP_WORDS[1]} == "mem" ]] ; then
|
|
182
|
-
if [[ \${COMP_CWORD} == 2 ]] ; then
|
|
183
|
-
opts="create search list get update delete stats"
|
|
184
|
-
COMPREPLY=( \$(compgen -W "\${opts}" -- \${cur}) )
|
|
185
|
-
return 0
|
|
186
|
-
fi
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
# Topic subcommands
|
|
190
|
-
if [[ \${COMP_WORDS[1]} == "topic" || \${COMP_WORDS[1]} == "topics" ]] ; then
|
|
191
|
-
if [[ \${COMP_CWORD} == 2 ]] ; then
|
|
192
|
-
opts="list create get update delete"
|
|
193
|
-
COMPREPLY=( \$(compgen -W "\${opts}" -- \${cur}) )
|
|
194
|
-
return 0
|
|
195
|
-
fi
|
|
196
|
-
fi
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
complete -F _lanonasis_completion lanonasis onasis memory maas
|
|
200
|
-
`;
|
|
201
|
-
}
|
|
202
|
-
generateZshCompletion() {
|
|
203
|
-
return `
|
|
204
|
-
#compdef lanonasis onasis memory maas
|
|
205
|
-
|
|
206
|
-
_lanonasis() {
|
|
207
|
-
local context state line
|
|
208
|
-
typeset -A opt_args
|
|
209
|
-
|
|
210
|
-
_arguments -C \\
|
|
211
|
-
'1: :_lanonasis_commands' \\
|
|
212
|
-
'*::arg:->args'
|
|
213
|
-
|
|
214
|
-
case $state in
|
|
215
|
-
args)
|
|
216
|
-
case $words[1] in
|
|
217
|
-
memory|mem)
|
|
218
|
-
_lanonasis_memory
|
|
219
|
-
;;
|
|
220
|
-
topic|topics)
|
|
221
|
-
_lanonasis_topic
|
|
222
|
-
;;
|
|
223
|
-
auth)
|
|
224
|
-
_arguments \\
|
|
225
|
-
'1:(login logout status)'
|
|
226
|
-
;;
|
|
227
|
-
esac
|
|
228
|
-
;;
|
|
229
|
-
esac
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
_lanonasis_commands() {
|
|
233
|
-
local commands
|
|
234
|
-
commands=(
|
|
235
|
-
'auth:Authentication commands'
|
|
236
|
-
'memory:Memory management'
|
|
237
|
-
'topic:Topic management'
|
|
238
|
-
'config:Configuration'
|
|
239
|
-
'mcp:MCP server management'
|
|
240
|
-
'init:Initialize CLI'
|
|
241
|
-
'docs:Open documentation'
|
|
242
|
-
'help:Show help'
|
|
243
|
-
)
|
|
244
|
-
_describe 'commands' commands
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
_lanonasis_memory() {
|
|
248
|
-
local subcommands
|
|
249
|
-
subcommands=(
|
|
250
|
-
'create:Create new memory'
|
|
251
|
-
'search:Search memories'
|
|
252
|
-
'list:List memories'
|
|
253
|
-
'get:Get specific memory'
|
|
254
|
-
'update:Update memory'
|
|
255
|
-
'delete:Delete memory'
|
|
256
|
-
'stats:Memory statistics'
|
|
257
|
-
)
|
|
258
|
-
_describe 'memory commands' subcommands
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
_lanonasis_topic() {
|
|
262
|
-
local subcommands
|
|
263
|
-
subcommands=(
|
|
264
|
-
'list:List topics'
|
|
265
|
-
'create:Create topic'
|
|
266
|
-
'get:Get topic'
|
|
267
|
-
'update:Update topic'
|
|
268
|
-
'delete:Delete topic'
|
|
269
|
-
)
|
|
270
|
-
_describe 'topic commands' subcommands
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
_lanonasis
|
|
274
|
-
`;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'bun:test';
|
|
2
|
-
import { MCPClient } from './mcp-client';
|
|
3
|
-
describe('MCPClient', () => {
|
|
4
|
-
let client;
|
|
5
|
-
beforeEach(() => {
|
|
6
|
-
client = new MCPClient();
|
|
7
|
-
});
|
|
8
|
-
describe('constructor', () => {
|
|
9
|
-
it('should create client instance', () => {
|
|
10
|
-
expect(client).toBeDefined();
|
|
11
|
-
expect(client.isConnected()).toBe(false);
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
describe('connection modes', () => {
|
|
15
|
-
it('should support local connection mode', async () => {
|
|
16
|
-
const result = await client.connect({ mode: 'local' });
|
|
17
|
-
// Local mode may fail without actual server, but should not throw
|
|
18
|
-
expect(typeof result).toBe('boolean');
|
|
19
|
-
});
|
|
20
|
-
it('should support remote connection mode', async () => {
|
|
21
|
-
const result = await client.connect({ mode: 'remote' });
|
|
22
|
-
// Remote mode may fail without credentials, but should not throw
|
|
23
|
-
expect(typeof result).toBe('boolean');
|
|
24
|
-
});
|
|
25
|
-
it('should support websocket connection mode', async () => {
|
|
26
|
-
const result = await client.connect({ mode: 'websocket' });
|
|
27
|
-
// WebSocket mode may fail without server, but should not throw
|
|
28
|
-
expect(typeof result).toBe('boolean');
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('connection options', () => {
|
|
32
|
-
it('should handle server path option', async () => {
|
|
33
|
-
const options = {
|
|
34
|
-
mode: 'local',
|
|
35
|
-
serverPath: '/custom/path/to/server'
|
|
36
|
-
};
|
|
37
|
-
const result = await client.connect(options);
|
|
38
|
-
expect(typeof result).toBe('boolean');
|
|
39
|
-
});
|
|
40
|
-
it('should handle server URL option', async () => {
|
|
41
|
-
const options = {
|
|
42
|
-
mode: 'websocket',
|
|
43
|
-
serverUrl: 'ws://custom.server.com:8081'
|
|
44
|
-
};
|
|
45
|
-
const result = await client.connect(options);
|
|
46
|
-
expect(typeof result).toBe('boolean');
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
describe('tool operations', () => {
|
|
50
|
-
it('should handle list tools request', async () => {
|
|
51
|
-
// Mock successful connection first
|
|
52
|
-
client.isConnected = () => true;
|
|
53
|
-
try {
|
|
54
|
-
const tools = await client.listTools();
|
|
55
|
-
expect(Array.isArray(tools)).toBe(true);
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
// Expected if no actual connection
|
|
59
|
-
expect(error).toBeDefined();
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
it('should handle call tool request', async () => {
|
|
63
|
-
// Mock successful connection first
|
|
64
|
-
client.isConnected = () => true;
|
|
65
|
-
try {
|
|
66
|
-
const result = await client.callTool('test_tool', { param: 'value' });
|
|
67
|
-
expect(result).toBeDefined();
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
// Expected if no actual connection
|
|
71
|
-
expect(error).toBeDefined();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
describe('memory operations', () => {
|
|
76
|
-
it('should handle create memory request', async () => {
|
|
77
|
-
// Mock successful connection first
|
|
78
|
-
client.isConnected = () => true;
|
|
79
|
-
try {
|
|
80
|
-
const result = await client.createMemory({
|
|
81
|
-
title: 'Test Memory',
|
|
82
|
-
content: 'Test content',
|
|
83
|
-
tags: ['test']
|
|
84
|
-
});
|
|
85
|
-
expect(result).toBeDefined();
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
// Expected if no actual connection
|
|
89
|
-
expect(error).toBeDefined();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
it('should handle search memories request', async () => {
|
|
93
|
-
// Mock successful connection first
|
|
94
|
-
client.isConnected = () => true;
|
|
95
|
-
try {
|
|
96
|
-
const result = await client.searchMemories({
|
|
97
|
-
query: 'test query',
|
|
98
|
-
limit: 10
|
|
99
|
-
});
|
|
100
|
-
expect(result).toBeDefined();
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
// Expected if no actual connection
|
|
104
|
-
expect(error).toBeDefined();
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
describe('error handling', () => {
|
|
109
|
-
it('should handle connection failures gracefully', async () => {
|
|
110
|
-
const result = await client.connect({
|
|
111
|
-
mode: 'websocket',
|
|
112
|
-
serverUrl: 'ws://nonexistent.server:9999'
|
|
113
|
-
});
|
|
114
|
-
expect(result).toBe(false);
|
|
115
|
-
});
|
|
116
|
-
it('should handle invalid connection modes', async () => {
|
|
117
|
-
try {
|
|
118
|
-
await client.connect({ mode: 'invalid' });
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
expect(error).toBeDefined();
|
|
122
|
-
}
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
});
|
package/dist/utils/output.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export interface OutputOptions {
|
|
2
|
-
format?: string;
|
|
3
|
-
silent?: boolean;
|
|
4
|
-
json?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export declare class OutputManager {
|
|
7
|
-
private static instance;
|
|
8
|
-
private options;
|
|
9
|
-
static getInstance(): OutputManager;
|
|
10
|
-
setOptions(options: OutputOptions): void;
|
|
11
|
-
isJsonOutput(): boolean;
|
|
12
|
-
isSilent(): boolean;
|
|
13
|
-
log(...args: any[]): void;
|
|
14
|
-
error(...args: any[]): void;
|
|
15
|
-
json(data: any): void;
|
|
16
|
-
table(data: any[]): void;
|
|
17
|
-
success(message: string): void;
|
|
18
|
-
warning(message: string): void;
|
|
19
|
-
info(message: string): void;
|
|
20
|
-
}
|
|
21
|
-
export declare const output: OutputManager;
|
|
22
|
-
export declare function showOutput(format?: string): boolean;
|
|
23
|
-
export declare function formatOutput(data: any, format?: string): string;
|
package/dist/utils/output.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
export class OutputManager {
|
|
3
|
-
static instance;
|
|
4
|
-
options = {};
|
|
5
|
-
static getInstance() {
|
|
6
|
-
if (!OutputManager.instance) {
|
|
7
|
-
OutputManager.instance = new OutputManager();
|
|
8
|
-
}
|
|
9
|
-
return OutputManager.instance;
|
|
10
|
-
}
|
|
11
|
-
setOptions(options) {
|
|
12
|
-
this.options = { ...this.options, ...options };
|
|
13
|
-
}
|
|
14
|
-
isJsonOutput() {
|
|
15
|
-
return this.options.format === 'json' ||
|
|
16
|
-
this.options.json === true ||
|
|
17
|
-
process.env.CLI_OUTPUT_FORMAT === 'json';
|
|
18
|
-
}
|
|
19
|
-
isSilent() {
|
|
20
|
-
return this.options.silent === true ||
|
|
21
|
-
this.isJsonOutput() ||
|
|
22
|
-
process.env.CLI_SILENT === 'true';
|
|
23
|
-
}
|
|
24
|
-
log(...args) {
|
|
25
|
-
if (!this.isSilent()) {
|
|
26
|
-
console.log(...args);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
error(...args) {
|
|
30
|
-
if (this.isJsonOutput()) {
|
|
31
|
-
console.error(JSON.stringify({
|
|
32
|
-
error: true,
|
|
33
|
-
message: args.join(' ').replace(/\x1b\[[0-9;]*m/g, '') // Strip ANSI codes
|
|
34
|
-
}));
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
console.error(...args);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
json(data) {
|
|
41
|
-
console.log(JSON.stringify(data, null, 2));
|
|
42
|
-
}
|
|
43
|
-
table(data) {
|
|
44
|
-
if (this.isJsonOutput()) {
|
|
45
|
-
this.json(data);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
console.table(data);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
success(message) {
|
|
52
|
-
if (this.isJsonOutput()) {
|
|
53
|
-
this.json({ success: true, message });
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
this.log(chalk.green('✓'), message);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
warning(message) {
|
|
60
|
-
if (this.isJsonOutput()) {
|
|
61
|
-
this.json({ warning: true, message });
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
this.log(chalk.yellow('⚠️'), message);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
info(message) {
|
|
68
|
-
if (!this.isSilent()) {
|
|
69
|
-
if (this.isJsonOutput()) {
|
|
70
|
-
this.json({ info: true, message });
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
this.log(chalk.blue('ℹ'), message);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
export const output = OutputManager.getInstance();
|
|
79
|
-
// Helper to conditionally show output
|
|
80
|
-
export function showOutput(format) {
|
|
81
|
-
return format !== 'json' && process.env.CLI_OUTPUT_FORMAT !== 'json';
|
|
82
|
-
}
|
|
83
|
-
// Helper to format output based on format
|
|
84
|
-
export function formatOutput(data, format) {
|
|
85
|
-
const outputFormat = format || process.env.CLI_OUTPUT_FORMAT || 'table';
|
|
86
|
-
switch (outputFormat) {
|
|
87
|
-
case 'json':
|
|
88
|
-
return JSON.stringify(data, null, 2);
|
|
89
|
-
case 'yaml':
|
|
90
|
-
// Simple YAML-like format
|
|
91
|
-
return Object.entries(data)
|
|
92
|
-
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
93
|
-
.join('\n');
|
|
94
|
-
default:
|
|
95
|
-
return data;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WebSocket MCP Client for Enterprise Connections
|
|
3
|
-
* Connects to mcp.lanonasis.com WebSocket server for real-time MCP operations
|
|
4
|
-
*/
|
|
5
|
-
import { EventEmitter } from 'events';
|
|
6
|
-
export interface MCPParams {
|
|
7
|
-
[key: string]: unknown;
|
|
8
|
-
}
|
|
9
|
-
export interface MCPResult {
|
|
10
|
-
[key: string]: unknown;
|
|
11
|
-
}
|
|
12
|
-
export interface MCPError {
|
|
13
|
-
code: number;
|
|
14
|
-
message: string;
|
|
15
|
-
data?: unknown;
|
|
16
|
-
}
|
|
17
|
-
export interface MCPMessage {
|
|
18
|
-
id?: string;
|
|
19
|
-
type: 'request' | 'response' | 'notification' | 'error';
|
|
20
|
-
method?: string;
|
|
21
|
-
params?: MCPParams;
|
|
22
|
-
result?: MCPResult;
|
|
23
|
-
error?: MCPError;
|
|
24
|
-
}
|
|
25
|
-
export interface WebSocketMCPClientOptions {
|
|
26
|
-
url?: string;
|
|
27
|
-
apiKey: string;
|
|
28
|
-
reconnectInterval?: number;
|
|
29
|
-
maxReconnectAttempts?: number;
|
|
30
|
-
timeout?: number;
|
|
31
|
-
}
|
|
32
|
-
export declare class WebSocketMCPClient extends EventEmitter {
|
|
33
|
-
private ws;
|
|
34
|
-
private url;
|
|
35
|
-
private apiKey;
|
|
36
|
-
private reconnectInterval;
|
|
37
|
-
private maxReconnectAttempts;
|
|
38
|
-
private timeout;
|
|
39
|
-
private reconnectAttempts;
|
|
40
|
-
private isConnected;
|
|
41
|
-
private messageId;
|
|
42
|
-
private pendingRequests;
|
|
43
|
-
constructor(options: WebSocketMCPClientOptions);
|
|
44
|
-
connect(): Promise<void>;
|
|
45
|
-
private handleMessage;
|
|
46
|
-
sendRequest(method: string, params?: MCPParams): Promise<MCPResult>;
|
|
47
|
-
listTools(): Promise<MCPResult>;
|
|
48
|
-
callTool(name: string, arguments_?: MCPParams): Promise<MCPResult>;
|
|
49
|
-
deleteMemory(id: string): Promise<MCPResult>;
|
|
50
|
-
searchMemories(args: MCPParams): Promise<MCPResult>;
|
|
51
|
-
listResources(): Promise<MCPResult>;
|
|
52
|
-
getMemories(query?: string): Promise<MCPResult>;
|
|
53
|
-
disconnect(): void;
|
|
54
|
-
getConnectionStatus(): {
|
|
55
|
-
connected: boolean;
|
|
56
|
-
url: string;
|
|
57
|
-
reconnectAttempts: number;
|
|
58
|
-
pendingRequests: number;
|
|
59
|
-
};
|
|
60
|
-
}
|