@lanonasis/cli 1.0.1 â 1.2.0
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 +166 -6
- package/dist/commands/auth.d.ts +6 -1
- package/dist/commands/auth.js +7 -4
- package/dist/commands/config.js +88 -4
- package/dist/commands/init.d.ts +5 -1
- package/dist/commands/mcp.d.ts +2 -0
- package/dist/commands/mcp.js +318 -0
- package/dist/commands/memory.js +37 -27
- package/dist/commands/topics.js +12 -7
- package/dist/index-simple.js +1 -1
- package/dist/index.js +28 -5
- package/dist/utils/api.d.ts +155 -15
- package/dist/utils/config.d.ts +6 -0
- package/dist/utils/config.js +46 -12
- package/dist/utils/formatting.d.ts +1 -1
- package/dist/utils/mcp-client.d.ts +53 -0
- package/dist/utils/mcp-client.js +249 -0
- package/package.json +17 -4
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { table } from 'table';
|
|
4
|
+
import { getMCPClient } from '../utils/mcp-client.js';
|
|
5
|
+
import { CLIConfig } from '../utils/config.js';
|
|
6
|
+
export function mcpCommands(program) {
|
|
7
|
+
const mcp = program
|
|
8
|
+
.command('mcp')
|
|
9
|
+
.description('MCP (Model Context Protocol) server operations');
|
|
10
|
+
// Also register mcp-server command directly on program for convenience
|
|
11
|
+
const mcpServer = program
|
|
12
|
+
.command('mcp-server')
|
|
13
|
+
.description('MCP server initialization and management');
|
|
14
|
+
mcpServer.command('init')
|
|
15
|
+
.description('Initialize MCP server configuration')
|
|
16
|
+
.action(async () => {
|
|
17
|
+
console.log(chalk.cyan('đ Initializing MCP Server Configuration'));
|
|
18
|
+
console.log('');
|
|
19
|
+
const config = new CLIConfig();
|
|
20
|
+
const isAuthenticated = !!config.get('token');
|
|
21
|
+
if (isAuthenticated) {
|
|
22
|
+
console.log(chalk.green('â Authenticated - Using remote MCP mode'));
|
|
23
|
+
console.log(' Your memory operations will use api.lanonasis.com');
|
|
24
|
+
console.log(' with real-time SSE updates enabled');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
console.log(chalk.yellow('â ī¸ Not authenticated - Using local MCP mode'));
|
|
28
|
+
console.log(' Run "lanonasis auth login" to enable remote mode');
|
|
29
|
+
}
|
|
30
|
+
console.log('');
|
|
31
|
+
console.log(chalk.cyan('Available MCP Commands:'));
|
|
32
|
+
console.log(' lanonasis mcp connect # Auto-connect to best mode');
|
|
33
|
+
console.log(' lanonasis mcp connect -r # Force remote mode');
|
|
34
|
+
console.log(' lanonasis mcp connect -l # Force local mode');
|
|
35
|
+
console.log(' lanonasis mcp status # Check connection status');
|
|
36
|
+
console.log(' lanonasis mcp tools # List available tools');
|
|
37
|
+
console.log('');
|
|
38
|
+
console.log(chalk.cyan('Memory operations are MCP-powered by default!'));
|
|
39
|
+
// Auto-connect to MCP
|
|
40
|
+
const spinner = ora('Auto-connecting to MCP...').start();
|
|
41
|
+
try {
|
|
42
|
+
const client = getMCPClient();
|
|
43
|
+
const connected = await client.connect({ useRemote: isAuthenticated });
|
|
44
|
+
if (connected) {
|
|
45
|
+
spinner.succeed(chalk.green(`Connected to ${isAuthenticated ? 'remote' : 'local'} MCP server`));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
spinner.fail('Failed to auto-connect to MCP');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
spinner.fail('MCP auto-connect failed');
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Connect command
|
|
56
|
+
mcp.command('connect')
|
|
57
|
+
.description('Connect to MCP server (local or remote)')
|
|
58
|
+
.option('-l, --local', 'Connect to local MCP server')
|
|
59
|
+
.option('-r, --remote', 'Connect to remote MCP server (api.lanonasis.com)')
|
|
60
|
+
.option('-s, --server <path>', 'Local MCP server path')
|
|
61
|
+
.option('-u, --url <url>', 'Remote MCP server URL')
|
|
62
|
+
.action(async (options) => {
|
|
63
|
+
const spinner = ora('Connecting to MCP server...').start();
|
|
64
|
+
const config = new CLIConfig();
|
|
65
|
+
try {
|
|
66
|
+
// Determine connection mode
|
|
67
|
+
let useRemote = options.remote;
|
|
68
|
+
if (!options.local && !options.remote) {
|
|
69
|
+
// Default to remote if authenticated, otherwise local
|
|
70
|
+
useRemote = !!config.get('token');
|
|
71
|
+
}
|
|
72
|
+
// Save preference
|
|
73
|
+
config.set('mcpUseRemote', useRemote);
|
|
74
|
+
if (options.server) {
|
|
75
|
+
config.set('mcpServerPath', options.server);
|
|
76
|
+
}
|
|
77
|
+
if (options.url) {
|
|
78
|
+
config.set('mcpServerUrl', options.url);
|
|
79
|
+
}
|
|
80
|
+
const client = getMCPClient();
|
|
81
|
+
const connected = await client.connect({
|
|
82
|
+
useRemote,
|
|
83
|
+
serverPath: options.server,
|
|
84
|
+
serverUrl: options.url
|
|
85
|
+
});
|
|
86
|
+
if (connected) {
|
|
87
|
+
spinner.succeed(chalk.green(`Connected to ${useRemote ? 'remote' : 'local'} MCP server`));
|
|
88
|
+
if (useRemote) {
|
|
89
|
+
console.log(chalk.cyan('âšī¸ Using remote MCP via api.lanonasis.com'));
|
|
90
|
+
console.log(chalk.cyan('đĄ SSE endpoint active for real-time updates'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
spinner.fail('Failed to connect to MCP server');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
spinner.fail(`Connection failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// Disconnect command
|
|
103
|
+
mcp.command('disconnect')
|
|
104
|
+
.description('Disconnect from MCP server')
|
|
105
|
+
.action(async () => {
|
|
106
|
+
const client = getMCPClient();
|
|
107
|
+
await client.disconnect();
|
|
108
|
+
console.log(chalk.green('â Disconnected from MCP server'));
|
|
109
|
+
});
|
|
110
|
+
// Status command
|
|
111
|
+
mcp.command('status')
|
|
112
|
+
.description('Show MCP connection status')
|
|
113
|
+
.action(async () => {
|
|
114
|
+
const client = getMCPClient();
|
|
115
|
+
const status = client.getConnectionStatus();
|
|
116
|
+
console.log(chalk.cyan('\nđ MCP Connection Status'));
|
|
117
|
+
console.log(chalk.cyan('========================'));
|
|
118
|
+
console.log(`Status: ${status.connected ? chalk.green('Connected') : chalk.red('Disconnected')}`);
|
|
119
|
+
console.log(`Mode: ${status.mode === 'remote' ? chalk.blue('Remote (API)') : chalk.yellow('Local')}`);
|
|
120
|
+
console.log(`Server: ${status.server}`);
|
|
121
|
+
if (status.connected && status.mode === 'remote') {
|
|
122
|
+
console.log(`\n${chalk.cyan('Features:')}`);
|
|
123
|
+
console.log('âĸ Real-time updates via SSE');
|
|
124
|
+
console.log('âĸ Authenticated API access');
|
|
125
|
+
console.log('âĸ MCP-compatible tool interface');
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
// List tools command
|
|
129
|
+
mcp.command('tools')
|
|
130
|
+
.description('List available MCP tools')
|
|
131
|
+
.action(async () => {
|
|
132
|
+
const spinner = ora('Fetching available tools...').start();
|
|
133
|
+
try {
|
|
134
|
+
const client = getMCPClient();
|
|
135
|
+
if (!client.isConnectedToServer()) {
|
|
136
|
+
spinner.info('Not connected. Attempting auto-connect...');
|
|
137
|
+
const config = new CLIConfig();
|
|
138
|
+
const useRemote = !!config.get('token');
|
|
139
|
+
await client.connect({ useRemote });
|
|
140
|
+
}
|
|
141
|
+
const tools = await client.listTools();
|
|
142
|
+
spinner.succeed('Tools fetched successfully');
|
|
143
|
+
console.log(chalk.cyan('\nđ§ Available MCP Tools'));
|
|
144
|
+
console.log(chalk.cyan('====================='));
|
|
145
|
+
const tableData = [
|
|
146
|
+
[chalk.bold('Tool Name'), chalk.bold('Description')]
|
|
147
|
+
];
|
|
148
|
+
tools.forEach(tool => {
|
|
149
|
+
tableData.push([
|
|
150
|
+
chalk.green(tool.name),
|
|
151
|
+
tool.description
|
|
152
|
+
]);
|
|
153
|
+
});
|
|
154
|
+
console.log(table(tableData, {
|
|
155
|
+
border: {
|
|
156
|
+
topBody: 'â',
|
|
157
|
+
topJoin: 'âŦ',
|
|
158
|
+
topLeft: 'â',
|
|
159
|
+
topRight: 'â',
|
|
160
|
+
bottomBody: 'â',
|
|
161
|
+
bottomJoin: 'â´',
|
|
162
|
+
bottomLeft: 'â',
|
|
163
|
+
bottomRight: 'â',
|
|
164
|
+
bodyLeft: 'â',
|
|
165
|
+
bodyRight: 'â',
|
|
166
|
+
bodyJoin: 'â',
|
|
167
|
+
joinBody: 'â',
|
|
168
|
+
joinLeft: 'â',
|
|
169
|
+
joinRight: 'â¤',
|
|
170
|
+
joinJoin: 'âŧ'
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
spinner.fail(`Failed to fetch tools: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
// Call tool command
|
|
180
|
+
mcp.command('call')
|
|
181
|
+
.description('Call an MCP tool directly')
|
|
182
|
+
.argument('<tool>', 'Tool name to call')
|
|
183
|
+
.option('-a, --args <json>', 'Tool arguments as JSON')
|
|
184
|
+
.action(async (toolName, options) => {
|
|
185
|
+
const spinner = ora(`Calling tool: ${toolName}...`).start();
|
|
186
|
+
try {
|
|
187
|
+
const client = getMCPClient();
|
|
188
|
+
if (!client.isConnectedToServer()) {
|
|
189
|
+
spinner.info('Not connected. Attempting auto-connect...');
|
|
190
|
+
const config = new CLIConfig();
|
|
191
|
+
const useRemote = !!config.get('token');
|
|
192
|
+
await client.connect({ useRemote });
|
|
193
|
+
}
|
|
194
|
+
let args = {};
|
|
195
|
+
if (options.args) {
|
|
196
|
+
try {
|
|
197
|
+
args = JSON.parse(options.args);
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
spinner.fail('Invalid JSON arguments');
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const result = await client.callTool(toolName, args);
|
|
205
|
+
spinner.succeed(`Tool ${toolName} executed successfully`);
|
|
206
|
+
console.log(chalk.cyan('\nđ¤ Tool Result:'));
|
|
207
|
+
console.log(JSON.stringify(result, null, 2));
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
spinner.fail(`Tool execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
211
|
+
process.exit(1);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// Memory-specific MCP commands
|
|
215
|
+
const memory = mcp.command('memory')
|
|
216
|
+
.description('Memory operations via MCP');
|
|
217
|
+
memory.command('create')
|
|
218
|
+
.description('Create memory via MCP')
|
|
219
|
+
.requiredOption('-t, --title <title>', 'Memory title')
|
|
220
|
+
.requiredOption('-c, --content <content>', 'Memory content')
|
|
221
|
+
.option('-T, --type <type>', 'Memory type', 'context')
|
|
222
|
+
.option('--tags <tags>', 'Comma-separated tags')
|
|
223
|
+
.action(async (options) => {
|
|
224
|
+
const spinner = ora('Creating memory via MCP...').start();
|
|
225
|
+
try {
|
|
226
|
+
const client = getMCPClient();
|
|
227
|
+
if (!client.isConnectedToServer()) {
|
|
228
|
+
spinner.info('Not connected. Attempting auto-connect...');
|
|
229
|
+
const config = new CLIConfig();
|
|
230
|
+
const useRemote = !!config.get('token');
|
|
231
|
+
await client.connect({ useRemote });
|
|
232
|
+
}
|
|
233
|
+
const result = await client.callTool('memory_create_memory', {
|
|
234
|
+
title: options.title,
|
|
235
|
+
content: options.content,
|
|
236
|
+
memory_type: options.type,
|
|
237
|
+
tags: options.tags ? options.tags.split(',').map((t) => t.trim()) : []
|
|
238
|
+
});
|
|
239
|
+
spinner.succeed('Memory created successfully');
|
|
240
|
+
console.log(chalk.green('\nâ Memory created'));
|
|
241
|
+
console.log(`ID: ${chalk.cyan(result.id)}`);
|
|
242
|
+
console.log(`Title: ${result.title}`);
|
|
243
|
+
console.log(`Type: ${result.memory_type}`);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
spinner.fail(`Failed to create memory: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
247
|
+
process.exit(1);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
memory.command('search')
|
|
251
|
+
.description('Search memories via MCP')
|
|
252
|
+
.argument('<query>', 'Search query')
|
|
253
|
+
.option('-l, --limit <number>', 'Maximum results', '10')
|
|
254
|
+
.option('-t, --threshold <number>', 'Similarity threshold (0-1)', '0.7')
|
|
255
|
+
.action(async (query, options) => {
|
|
256
|
+
const spinner = ora('Searching memories via MCP...').start();
|
|
257
|
+
try {
|
|
258
|
+
const client = getMCPClient();
|
|
259
|
+
if (!client.isConnectedToServer()) {
|
|
260
|
+
spinner.info('Not connected. Attempting auto-connect...');
|
|
261
|
+
const config = new CLIConfig();
|
|
262
|
+
const useRemote = !!config.get('token');
|
|
263
|
+
await client.connect({ useRemote });
|
|
264
|
+
}
|
|
265
|
+
const results = await client.callTool('memory_search_memories', {
|
|
266
|
+
query,
|
|
267
|
+
limit: parseInt(options.limit),
|
|
268
|
+
threshold: parseFloat(options.threshold)
|
|
269
|
+
});
|
|
270
|
+
spinner.succeed(`Found ${results.length} memories`);
|
|
271
|
+
if (results.length === 0) {
|
|
272
|
+
console.log(chalk.yellow('\nNo memories found matching your query'));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
console.log(chalk.cyan('\nđ Search Results:'));
|
|
276
|
+
results.forEach((memory, index) => {
|
|
277
|
+
console.log(`\n${chalk.bold(`${index + 1}. ${memory.title}`)}`);
|
|
278
|
+
console.log(` ID: ${chalk.gray(memory.id)}`);
|
|
279
|
+
console.log(` Type: ${chalk.blue(memory.memory_type)}`);
|
|
280
|
+
console.log(` Score: ${chalk.green((memory.relevance_score * 100).toFixed(1) + '%')}`);
|
|
281
|
+
console.log(` Content: ${memory.content.substring(0, 100)}...`);
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
spinner.fail(`Search failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
286
|
+
process.exit(1);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
// Configure MCP preferences
|
|
290
|
+
mcp.command('config')
|
|
291
|
+
.description('Configure MCP preferences')
|
|
292
|
+
.option('--prefer-remote', 'Prefer remote MCP server when available')
|
|
293
|
+
.option('--prefer-local', 'Prefer local MCP server')
|
|
294
|
+
.option('--auto', 'Auto-detect best connection mode')
|
|
295
|
+
.action(async (options) => {
|
|
296
|
+
const config = new CLIConfig();
|
|
297
|
+
if (options.preferRemote) {
|
|
298
|
+
config.set('mcpPreference', 'remote');
|
|
299
|
+
console.log(chalk.green('â Set MCP preference to remote'));
|
|
300
|
+
}
|
|
301
|
+
else if (options.preferLocal) {
|
|
302
|
+
config.set('mcpPreference', 'local');
|
|
303
|
+
console.log(chalk.green('â Set MCP preference to local'));
|
|
304
|
+
}
|
|
305
|
+
else if (options.auto) {
|
|
306
|
+
config.set('mcpPreference', 'auto');
|
|
307
|
+
console.log(chalk.green('â Set MCP preference to auto-detect'));
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const current = config.get('mcpPreference') || 'auto';
|
|
311
|
+
console.log(`Current MCP preference: ${chalk.cyan(current)}`);
|
|
312
|
+
console.log('\nOptions:');
|
|
313
|
+
console.log(' --prefer-remote : Use remote MCP server (api.lanonasis.com)');
|
|
314
|
+
console.log(' --prefer-local : Use local MCP server');
|
|
315
|
+
console.log(' --auto : Auto-detect based on authentication');
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
package/dist/commands/memory.js
CHANGED
|
@@ -6,6 +6,7 @@ import wrap from 'word-wrap';
|
|
|
6
6
|
import { format } from 'date-fns';
|
|
7
7
|
import { apiClient } from '../utils/api.js';
|
|
8
8
|
import { formatBytes, truncateText } from '../utils/formatting.js';
|
|
9
|
+
// Using GetMemoriesParams from api.ts
|
|
9
10
|
export function memoryCommands(program) {
|
|
10
11
|
// Create memory
|
|
11
12
|
program
|
|
@@ -80,7 +81,8 @@ export function memoryCommands(program) {
|
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
83
|
catch (error) {
|
|
83
|
-
|
|
84
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
85
|
+
console.error(chalk.red('â Failed to create memory:'), errorMessage);
|
|
84
86
|
process.exit(1);
|
|
85
87
|
}
|
|
86
88
|
});
|
|
@@ -100,25 +102,26 @@ export function memoryCommands(program) {
|
|
|
100
102
|
try {
|
|
101
103
|
const spinner = ora('Fetching memories...').start();
|
|
102
104
|
const params = {
|
|
103
|
-
|
|
104
|
-
limit: parseInt(options.limit),
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
offset: (parseInt(options.page || '1') - 1) * parseInt(options.limit || '20'),
|
|
106
|
+
limit: parseInt(options.limit || '20'),
|
|
107
|
+
sort_by: (options.sort || 'created_at'),
|
|
108
|
+
sort_order: (options.order || 'desc')
|
|
107
109
|
};
|
|
108
110
|
if (options.type)
|
|
109
111
|
params.memory_type = options.type;
|
|
110
112
|
if (options.tags)
|
|
111
|
-
params.tags = options.tags;
|
|
112
|
-
|
|
113
|
-
params.user_id = options.userId;
|
|
113
|
+
params.tags = options.tags.split(',').map(t => t.trim());
|
|
114
|
+
// Note: user_id filtering removed as it's handled by authentication
|
|
114
115
|
const result = await apiClient.getMemories(params);
|
|
115
116
|
spinner.stop();
|
|
116
|
-
if (result.
|
|
117
|
+
if (result.data.length === 0) {
|
|
117
118
|
console.log(chalk.yellow('No memories found'));
|
|
118
119
|
return;
|
|
119
120
|
}
|
|
120
121
|
console.log(chalk.blue.bold(`\nđ Memories (${result.pagination.total} total)`));
|
|
121
|
-
|
|
122
|
+
const currentPage = Math.floor(result.pagination.offset / result.pagination.limit) + 1;
|
|
123
|
+
const totalPages = Math.ceil(result.pagination.total / result.pagination.limit);
|
|
124
|
+
console.log(chalk.gray(`Page ${currentPage} of ${totalPages}`));
|
|
122
125
|
console.log();
|
|
123
126
|
const outputFormat = process.env.CLI_OUTPUT_FORMAT || 'table';
|
|
124
127
|
if (outputFormat === 'json') {
|
|
@@ -126,7 +129,7 @@ export function memoryCommands(program) {
|
|
|
126
129
|
}
|
|
127
130
|
else {
|
|
128
131
|
// Table format
|
|
129
|
-
const tableData = result.
|
|
132
|
+
const tableData = result.data.map((memory) => [
|
|
130
133
|
truncateText(memory.title, 30),
|
|
131
134
|
memory.memory_type,
|
|
132
135
|
memory.tags.slice(0, 3).join(', '),
|
|
@@ -134,7 +137,6 @@ export function memoryCommands(program) {
|
|
|
134
137
|
memory.access_count
|
|
135
138
|
]);
|
|
136
139
|
const tableConfig = {
|
|
137
|
-
header: ['Title', 'Type', 'Tags', 'Created', 'Access'],
|
|
138
140
|
columnDefault: {
|
|
139
141
|
width: 20,
|
|
140
142
|
wrapWord: true
|
|
@@ -147,15 +149,18 @@ export function memoryCommands(program) {
|
|
|
147
149
|
{ width: 8 }
|
|
148
150
|
]
|
|
149
151
|
};
|
|
150
|
-
|
|
152
|
+
const tableHeaders = ['Title', 'Type', 'Tags', 'Created', 'Access'];
|
|
153
|
+
console.log(table([tableHeaders, ...tableData], tableConfig));
|
|
151
154
|
// Pagination info
|
|
152
|
-
if (result.pagination.
|
|
153
|
-
|
|
155
|
+
if (result.pagination.has_more) {
|
|
156
|
+
const nextPage = currentPage + 1;
|
|
157
|
+
console.log(chalk.gray(`\nUse --page ${nextPage} for next page`));
|
|
154
158
|
}
|
|
155
159
|
}
|
|
156
160
|
}
|
|
157
161
|
catch (error) {
|
|
158
|
-
|
|
162
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
163
|
+
console.error(chalk.red('â Failed to list memories:'), errorMessage);
|
|
159
164
|
process.exit(1);
|
|
160
165
|
}
|
|
161
166
|
});
|
|
@@ -172,8 +177,8 @@ export function memoryCommands(program) {
|
|
|
172
177
|
try {
|
|
173
178
|
const spinner = ora(`Searching for "${query}"...`).start();
|
|
174
179
|
const searchOptions = {
|
|
175
|
-
limit: parseInt(options.limit),
|
|
176
|
-
threshold: parseFloat(options.threshold)
|
|
180
|
+
limit: parseInt(options.limit || '20'),
|
|
181
|
+
threshold: parseFloat(options.threshold || '0.7')
|
|
177
182
|
};
|
|
178
183
|
if (options.type) {
|
|
179
184
|
searchOptions.memory_types = options.type.split(',').map((t) => t.trim());
|
|
@@ -183,14 +188,14 @@ export function memoryCommands(program) {
|
|
|
183
188
|
}
|
|
184
189
|
const result = await apiClient.searchMemories(query, searchOptions);
|
|
185
190
|
spinner.stop();
|
|
186
|
-
if (result.
|
|
191
|
+
if (result.data.length === 0) {
|
|
187
192
|
console.log(chalk.yellow('No memories found matching your search'));
|
|
188
193
|
return;
|
|
189
194
|
}
|
|
190
|
-
console.log(chalk.blue.bold(`\nđ Search Results (${result.
|
|
191
|
-
console.log(chalk.gray(`Query: "${query}"
|
|
195
|
+
console.log(chalk.blue.bold(`\nđ Search Results (${result.pagination.total} found)`));
|
|
196
|
+
console.log(chalk.gray(`Query: "${query}"`));
|
|
192
197
|
console.log();
|
|
193
|
-
result.
|
|
198
|
+
result.data.forEach((memory, index) => {
|
|
194
199
|
const score = (memory.relevance_score * 100).toFixed(1);
|
|
195
200
|
console.log(chalk.green(`${index + 1}. ${memory.title}`) + chalk.gray(` (${score}% match)`));
|
|
196
201
|
console.log(chalk.white(` ${truncateText(memory.content, 100)}`));
|
|
@@ -202,7 +207,8 @@ export function memoryCommands(program) {
|
|
|
202
207
|
});
|
|
203
208
|
}
|
|
204
209
|
catch (error) {
|
|
205
|
-
|
|
210
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
211
|
+
console.error(chalk.red('â Search failed:'), errorMessage);
|
|
206
212
|
process.exit(1);
|
|
207
213
|
}
|
|
208
214
|
});
|
|
@@ -244,7 +250,8 @@ export function memoryCommands(program) {
|
|
|
244
250
|
}
|
|
245
251
|
}
|
|
246
252
|
catch (error) {
|
|
247
|
-
|
|
253
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
254
|
+
console.error(chalk.red('â Failed to get memory:'), errorMessage);
|
|
248
255
|
process.exit(1);
|
|
249
256
|
}
|
|
250
257
|
});
|
|
@@ -324,7 +331,8 @@ export function memoryCommands(program) {
|
|
|
324
331
|
console.log(` Title: ${memory.title}`);
|
|
325
332
|
}
|
|
326
333
|
catch (error) {
|
|
327
|
-
|
|
334
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
335
|
+
console.error(chalk.red('â Failed to update memory:'), errorMessage);
|
|
328
336
|
process.exit(1);
|
|
329
337
|
}
|
|
330
338
|
});
|
|
@@ -357,7 +365,8 @@ export function memoryCommands(program) {
|
|
|
357
365
|
spinner.succeed('Memory deleted successfully');
|
|
358
366
|
}
|
|
359
367
|
catch (error) {
|
|
360
|
-
|
|
368
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
369
|
+
console.error(chalk.red('â Failed to delete memory:'), errorMessage);
|
|
361
370
|
process.exit(1);
|
|
362
371
|
}
|
|
363
372
|
});
|
|
@@ -394,7 +403,8 @@ export function memoryCommands(program) {
|
|
|
394
403
|
}
|
|
395
404
|
}
|
|
396
405
|
catch (error) {
|
|
397
|
-
|
|
406
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
407
|
+
console.error(chalk.red('â Failed to get statistics:'), errorMessage);
|
|
398
408
|
process.exit(1);
|
|
399
409
|
}
|
|
400
410
|
});
|
package/dist/commands/topics.js
CHANGED
|
@@ -82,7 +82,8 @@ export function topicCommands(program) {
|
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
catch (error) {
|
|
85
|
-
|
|
85
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
86
|
+
console.error(chalk.red('â Failed to create topic:'), errorMessage);
|
|
86
87
|
process.exit(1);
|
|
87
88
|
}
|
|
88
89
|
});
|
|
@@ -116,7 +117,6 @@ export function topicCommands(program) {
|
|
|
116
117
|
topic.parent_topic_id ? 'â' : ''
|
|
117
118
|
]);
|
|
118
119
|
const tableConfig = {
|
|
119
|
-
header: ['Name', 'Description', 'Color', 'Created', 'Child'],
|
|
120
120
|
columnDefault: {
|
|
121
121
|
width: 20,
|
|
122
122
|
wrapWord: true
|
|
@@ -129,11 +129,13 @@ export function topicCommands(program) {
|
|
|
129
129
|
{ width: 8 }
|
|
130
130
|
]
|
|
131
131
|
};
|
|
132
|
-
|
|
132
|
+
const tableHeaders = ['Name', 'Description', 'System', 'Created'];
|
|
133
|
+
console.log(table([tableHeaders, ...tableData], tableConfig));
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
catch (error) {
|
|
136
|
-
|
|
137
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
138
|
+
console.error(chalk.red('â Failed to list topics:'), errorMessage);
|
|
137
139
|
process.exit(1);
|
|
138
140
|
}
|
|
139
141
|
});
|
|
@@ -174,7 +176,8 @@ export function topicCommands(program) {
|
|
|
174
176
|
}
|
|
175
177
|
}
|
|
176
178
|
catch (error) {
|
|
177
|
-
|
|
179
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
180
|
+
console.error(chalk.red('â Failed to get topic:'), errorMessage);
|
|
178
181
|
process.exit(1);
|
|
179
182
|
}
|
|
180
183
|
});
|
|
@@ -257,7 +260,8 @@ export function topicCommands(program) {
|
|
|
257
260
|
console.log(` Name: ${topic.name}`);
|
|
258
261
|
}
|
|
259
262
|
catch (error) {
|
|
260
|
-
|
|
263
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
264
|
+
console.error(chalk.red('â Failed to update topic:'), errorMessage);
|
|
261
265
|
process.exit(1);
|
|
262
266
|
}
|
|
263
267
|
});
|
|
@@ -290,7 +294,8 @@ export function topicCommands(program) {
|
|
|
290
294
|
spinner.succeed('Topic deleted successfully');
|
|
291
295
|
}
|
|
292
296
|
catch (error) {
|
|
293
|
-
|
|
297
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
298
|
+
console.error(chalk.red('â Failed to delete topic:'), errorMessage);
|
|
294
299
|
process.exit(1);
|
|
295
300
|
}
|
|
296
301
|
});
|
package/dist/index-simple.js
CHANGED
|
@@ -11,7 +11,7 @@ const packageJson = JSON.parse(readFileSync(packagePath, 'utf8'));
|
|
|
11
11
|
const program = new Command();
|
|
12
12
|
program
|
|
13
13
|
.name('lanonasis')
|
|
14
|
-
.description('Lanonasis Enterprise CLI - Memory as a Service
|
|
14
|
+
.description('Lanonasis Enterprise CLI - Memory as a Service with MCP Integration')
|
|
15
15
|
.version(packageJson.version);
|
|
16
16
|
program
|
|
17
17
|
.command('init')
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,9 @@ import { memoryCommands } from './commands/memory.js';
|
|
|
8
8
|
import { topicCommands } from './commands/topics.js';
|
|
9
9
|
import { configCommands } from './commands/config.js';
|
|
10
10
|
import { orgCommands } from './commands/organization.js';
|
|
11
|
+
import { mcpCommands } from './commands/mcp.js';
|
|
11
12
|
import { CLIConfig } from './utils/config.js';
|
|
13
|
+
import { getMCPClient } from './utils/mcp-client.js';
|
|
12
14
|
// Load environment variables
|
|
13
15
|
config();
|
|
14
16
|
const program = new Command();
|
|
@@ -17,12 +19,13 @@ const cliConfig = new CLIConfig();
|
|
|
17
19
|
program
|
|
18
20
|
.name('memory')
|
|
19
21
|
.alias('maas')
|
|
20
|
-
.description('Enterprise Memory as a Service (MaaS) CLI')
|
|
22
|
+
.description('Enterprise Memory as a Service (MaaS) CLI with MCP Integration')
|
|
21
23
|
.version('1.0.0')
|
|
22
24
|
.option('-v, --verbose', 'enable verbose logging')
|
|
23
25
|
.option('--api-url <url>', 'override API URL')
|
|
24
26
|
.option('--output <format>', 'output format (json, table, yaml)', 'table')
|
|
25
|
-
.
|
|
27
|
+
.option('--no-mcp', 'disable MCP and use direct API')
|
|
28
|
+
.hook('preAction', async (thisCommand, actionCommand) => {
|
|
26
29
|
const opts = thisCommand.opts();
|
|
27
30
|
if (opts.verbose) {
|
|
28
31
|
process.env.CLI_VERBOSE = 'true';
|
|
@@ -31,6 +34,24 @@ program
|
|
|
31
34
|
process.env.MEMORY_API_URL = opts.apiUrl;
|
|
32
35
|
}
|
|
33
36
|
process.env.CLI_OUTPUT_FORMAT = opts.output;
|
|
37
|
+
// Auto-initialize MCP unless disabled
|
|
38
|
+
if (opts.mcp !== false && !['init', 'auth', 'login', 'mcp'].includes(actionCommand.name())) {
|
|
39
|
+
try {
|
|
40
|
+
const client = getMCPClient();
|
|
41
|
+
if (!client.isConnectedToServer()) {
|
|
42
|
+
const useRemote = await cliConfig.isAuthenticated();
|
|
43
|
+
await client.connect({ useRemote });
|
|
44
|
+
if (process.env.CLI_VERBOSE === 'true') {
|
|
45
|
+
console.log(chalk.gray(`MCP connected (${useRemote ? 'remote' : 'local'})`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
if (process.env.CLI_VERBOSE === 'true') {
|
|
51
|
+
console.log(chalk.yellow('MCP auto-connect failed, using direct API'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
34
55
|
});
|
|
35
56
|
// Global error handler
|
|
36
57
|
process.on('uncaughtException', (error) => {
|
|
@@ -110,13 +131,16 @@ authCmd
|
|
|
110
131
|
console.log(chalk.yellow('Run:'), chalk.white('memory login'));
|
|
111
132
|
}
|
|
112
133
|
});
|
|
113
|
-
//
|
|
134
|
+
// MCP Commands (primary interface)
|
|
135
|
+
mcpCommands(program);
|
|
136
|
+
// Memory commands (require auth) - now MCP-powered by default
|
|
114
137
|
const memoryCmd = program
|
|
115
138
|
.command('memory')
|
|
116
139
|
.alias('mem')
|
|
117
140
|
.description('Memory management commands');
|
|
118
141
|
requireAuth(memoryCmd);
|
|
119
142
|
memoryCommands(memoryCmd);
|
|
143
|
+
// Note: Memory commands are now MCP-powered when available
|
|
120
144
|
// Topic commands (require auth)
|
|
121
145
|
const topicCmd = program
|
|
122
146
|
.command('topic')
|
|
@@ -174,8 +198,7 @@ program
|
|
|
174
198
|
// Help customization
|
|
175
199
|
program.configureHelp({
|
|
176
200
|
formatHelp: (cmd, helper) => {
|
|
177
|
-
|
|
178
|
-
const helpWidth = Math.min(term - 2, 80);
|
|
201
|
+
// Get terminal width for formatting (currently using default helper formatting)
|
|
179
202
|
let help = chalk.blue.bold('đ§ Memory as a Service CLI\n\n');
|
|
180
203
|
help += helper.commandUsage(cmd) + '\n\n';
|
|
181
204
|
if (cmd.description()) {
|