@lanonasis/cli 1.0.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 +217 -0
- package/dist/commands/auth.d.ts +1 -0
- package/dist/commands/auth.js +130 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +122 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +52 -0
- package/dist/commands/memory.d.ts +2 -0
- package/dist/commands/memory.js +401 -0
- package/dist/commands/organization.d.ts +2 -0
- package/dist/commands/organization.js +41 -0
- package/dist/commands/topics.d.ts +2 -0
- package/dist/commands/topics.js +297 -0
- package/dist/index-simple.d.ts +2 -0
- package/dist/index-simple.js +215 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +228 -0
- package/dist/utils/api.d.ts +24 -0
- package/dist/utils/api.js +141 -0
- package/dist/utils/config.d.ts +26 -0
- package/dist/utils/config.js +104 -0
- package/dist/utils/formatting.d.ts +4 -0
- package/dist/utils/formatting.js +34 -0
- package/package.json +51 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { table } from 'table';
|
|
5
|
+
import wrap from 'word-wrap';
|
|
6
|
+
import { format } from 'date-fns';
|
|
7
|
+
import { apiClient } from '../utils/api.js';
|
|
8
|
+
import { formatBytes, truncateText } from '../utils/formatting.js';
|
|
9
|
+
export function memoryCommands(program) {
|
|
10
|
+
// Create memory
|
|
11
|
+
program
|
|
12
|
+
.command('create')
|
|
13
|
+
.alias('add')
|
|
14
|
+
.description('Create a new memory entry')
|
|
15
|
+
.option('-t, --title <title>', 'memory title')
|
|
16
|
+
.option('-c, --content <content>', 'memory content')
|
|
17
|
+
.option('--type <type>', 'memory type (conversation, knowledge, project, context, reference)', 'context')
|
|
18
|
+
.option('--tags <tags>', 'comma-separated tags')
|
|
19
|
+
.option('--topic-id <id>', 'topic ID')
|
|
20
|
+
.option('-i, --interactive', 'interactive mode')
|
|
21
|
+
.action(async (options) => {
|
|
22
|
+
try {
|
|
23
|
+
let { title, content, type, tags, topicId, interactive } = options;
|
|
24
|
+
if (interactive || (!title || !content)) {
|
|
25
|
+
const answers = await inquirer.prompt([
|
|
26
|
+
{
|
|
27
|
+
type: 'input',
|
|
28
|
+
name: 'title',
|
|
29
|
+
message: 'Memory title:',
|
|
30
|
+
default: title,
|
|
31
|
+
validate: (input) => input.length > 0 || 'Title is required'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'editor',
|
|
35
|
+
name: 'content',
|
|
36
|
+
message: 'Memory content:',
|
|
37
|
+
default: content,
|
|
38
|
+
validate: (input) => input.length > 0 || 'Content is required'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'list',
|
|
42
|
+
name: 'type',
|
|
43
|
+
message: 'Memory type:',
|
|
44
|
+
choices: ['conversation', 'knowledge', 'project', 'context', 'reference'],
|
|
45
|
+
default: type || 'context'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'tags',
|
|
50
|
+
message: 'Tags (comma-separated):',
|
|
51
|
+
default: tags || ''
|
|
52
|
+
}
|
|
53
|
+
]);
|
|
54
|
+
title = answers.title;
|
|
55
|
+
content = answers.content;
|
|
56
|
+
type = answers.type;
|
|
57
|
+
tags = answers.tags;
|
|
58
|
+
}
|
|
59
|
+
const spinner = ora('Creating memory...').start();
|
|
60
|
+
const memoryData = {
|
|
61
|
+
title,
|
|
62
|
+
content,
|
|
63
|
+
memory_type: type
|
|
64
|
+
};
|
|
65
|
+
if (tags) {
|
|
66
|
+
memoryData.tags = tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
67
|
+
}
|
|
68
|
+
if (topicId) {
|
|
69
|
+
memoryData.topic_id = topicId;
|
|
70
|
+
}
|
|
71
|
+
const memory = await apiClient.createMemory(memoryData);
|
|
72
|
+
spinner.succeed('Memory created successfully');
|
|
73
|
+
console.log();
|
|
74
|
+
console.log(chalk.green('✓ Memory created:'));
|
|
75
|
+
console.log(` ID: ${chalk.cyan(memory.id)}`);
|
|
76
|
+
console.log(` Title: ${memory.title}`);
|
|
77
|
+
console.log(` Type: ${memory.memory_type}`);
|
|
78
|
+
if (memory.tags && memory.tags.length > 0) {
|
|
79
|
+
console.log(` Tags: ${memory.tags.join(', ')}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.error(chalk.red('✖ Failed to create memory:'), error.message);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
// List memories
|
|
88
|
+
program
|
|
89
|
+
.command('list')
|
|
90
|
+
.alias('ls')
|
|
91
|
+
.description('List memory entries')
|
|
92
|
+
.option('-p, --page <page>', 'page number', '1')
|
|
93
|
+
.option('-l, --limit <limit>', 'number of entries per page', '20')
|
|
94
|
+
.option('--type <type>', 'filter by memory type')
|
|
95
|
+
.option('--tags <tags>', 'filter by tags (comma-separated)')
|
|
96
|
+
.option('--user-id <id>', 'filter by user ID (admin only)')
|
|
97
|
+
.option('--sort <field>', 'sort by field (created_at, updated_at, title, last_accessed)', 'created_at')
|
|
98
|
+
.option('--order <order>', 'sort order (asc, desc)', 'desc')
|
|
99
|
+
.action(async (options) => {
|
|
100
|
+
try {
|
|
101
|
+
const spinner = ora('Fetching memories...').start();
|
|
102
|
+
const params = {
|
|
103
|
+
page: parseInt(options.page),
|
|
104
|
+
limit: parseInt(options.limit),
|
|
105
|
+
sort: options.sort,
|
|
106
|
+
order: options.order
|
|
107
|
+
};
|
|
108
|
+
if (options.type)
|
|
109
|
+
params.memory_type = options.type;
|
|
110
|
+
if (options.tags)
|
|
111
|
+
params.tags = options.tags;
|
|
112
|
+
if (options.userId)
|
|
113
|
+
params.user_id = options.userId;
|
|
114
|
+
const result = await apiClient.getMemories(params);
|
|
115
|
+
spinner.stop();
|
|
116
|
+
if (result.memories.length === 0) {
|
|
117
|
+
console.log(chalk.yellow('No memories found'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
console.log(chalk.blue.bold(`\n📚 Memories (${result.pagination.total} total)`));
|
|
121
|
+
console.log(chalk.gray(`Page ${result.pagination.page} of ${result.pagination.pages}`));
|
|
122
|
+
console.log();
|
|
123
|
+
const outputFormat = process.env.CLI_OUTPUT_FORMAT || 'table';
|
|
124
|
+
if (outputFormat === 'json') {
|
|
125
|
+
console.log(JSON.stringify(result, null, 2));
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// Table format
|
|
129
|
+
const tableData = result.memories.map((memory) => [
|
|
130
|
+
truncateText(memory.title, 30),
|
|
131
|
+
memory.memory_type,
|
|
132
|
+
memory.tags.slice(0, 3).join(', '),
|
|
133
|
+
format(new Date(memory.created_at), 'MMM dd, yyyy'),
|
|
134
|
+
memory.access_count
|
|
135
|
+
]);
|
|
136
|
+
const tableConfig = {
|
|
137
|
+
header: ['Title', 'Type', 'Tags', 'Created', 'Access'],
|
|
138
|
+
columnDefault: {
|
|
139
|
+
width: 20,
|
|
140
|
+
wrapWord: true
|
|
141
|
+
},
|
|
142
|
+
columns: [
|
|
143
|
+
{ width: 30 },
|
|
144
|
+
{ width: 12 },
|
|
145
|
+
{ width: 20 },
|
|
146
|
+
{ width: 12 },
|
|
147
|
+
{ width: 8 }
|
|
148
|
+
]
|
|
149
|
+
};
|
|
150
|
+
console.log(table([tableConfig.header, ...tableData], tableConfig));
|
|
151
|
+
// Pagination info
|
|
152
|
+
if (result.pagination.pages > 1) {
|
|
153
|
+
console.log(chalk.gray(`\nUse --page ${result.pagination.page + 1} for next page`));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(chalk.red('✖ Failed to list memories:'), error.message);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
// Search memories
|
|
163
|
+
program
|
|
164
|
+
.command('search')
|
|
165
|
+
.description('Search memories using semantic search')
|
|
166
|
+
.argument('<query>', 'search query')
|
|
167
|
+
.option('-l, --limit <limit>', 'number of results', '20')
|
|
168
|
+
.option('--threshold <threshold>', 'similarity threshold (0-1)', '0.7')
|
|
169
|
+
.option('--type <types>', 'filter by memory types (comma-separated)')
|
|
170
|
+
.option('--tags <tags>', 'filter by tags (comma-separated)')
|
|
171
|
+
.action(async (query, options) => {
|
|
172
|
+
try {
|
|
173
|
+
const spinner = ora(`Searching for "${query}"...`).start();
|
|
174
|
+
const searchOptions = {
|
|
175
|
+
limit: parseInt(options.limit),
|
|
176
|
+
threshold: parseFloat(options.threshold)
|
|
177
|
+
};
|
|
178
|
+
if (options.type) {
|
|
179
|
+
searchOptions.memory_types = options.type.split(',').map((t) => t.trim());
|
|
180
|
+
}
|
|
181
|
+
if (options.tags) {
|
|
182
|
+
searchOptions.tags = options.tags.split(',').map((t) => t.trim());
|
|
183
|
+
}
|
|
184
|
+
const result = await apiClient.searchMemories(query, searchOptions);
|
|
185
|
+
spinner.stop();
|
|
186
|
+
if (result.results.length === 0) {
|
|
187
|
+
console.log(chalk.yellow('No memories found matching your search'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
console.log(chalk.blue.bold(`\n🔍 Search Results (${result.total_results} found)`));
|
|
191
|
+
console.log(chalk.gray(`Query: "${query}" | Search time: ${result.search_time_ms}ms`));
|
|
192
|
+
console.log();
|
|
193
|
+
result.results.forEach((memory, index) => {
|
|
194
|
+
const score = (memory.relevance_score * 100).toFixed(1);
|
|
195
|
+
console.log(chalk.green(`${index + 1}. ${memory.title}`) + chalk.gray(` (${score}% match)`));
|
|
196
|
+
console.log(chalk.white(` ${truncateText(memory.content, 100)}`));
|
|
197
|
+
console.log(chalk.cyan(` ID: ${memory.id}`) + chalk.gray(` | Type: ${memory.memory_type}`));
|
|
198
|
+
if (memory.tags.length > 0) {
|
|
199
|
+
console.log(chalk.yellow(` Tags: ${memory.tags.join(', ')}`));
|
|
200
|
+
}
|
|
201
|
+
console.log();
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.error(chalk.red('✖ Search failed:'), error.message);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
// Get memory details
|
|
210
|
+
program
|
|
211
|
+
.command('get')
|
|
212
|
+
.alias('show')
|
|
213
|
+
.description('Get detailed information about a memory')
|
|
214
|
+
.argument('<id>', 'memory ID')
|
|
215
|
+
.action(async (id) => {
|
|
216
|
+
try {
|
|
217
|
+
const spinner = ora('Fetching memory...').start();
|
|
218
|
+
const memory = await apiClient.getMemory(id);
|
|
219
|
+
spinner.stop();
|
|
220
|
+
console.log(chalk.blue.bold('\n📄 Memory Details'));
|
|
221
|
+
console.log();
|
|
222
|
+
console.log(chalk.green('Title:'), memory.title);
|
|
223
|
+
console.log(chalk.green('ID:'), chalk.cyan(memory.id));
|
|
224
|
+
console.log(chalk.green('Type:'), memory.memory_type);
|
|
225
|
+
console.log(chalk.green('Created:'), format(new Date(memory.created_at), 'PPpp'));
|
|
226
|
+
console.log(chalk.green('Updated:'), format(new Date(memory.updated_at), 'PPpp'));
|
|
227
|
+
if (memory.last_accessed) {
|
|
228
|
+
console.log(chalk.green('Last Accessed:'), format(new Date(memory.last_accessed), 'PPpp'));
|
|
229
|
+
}
|
|
230
|
+
console.log(chalk.green('Access Count:'), memory.access_count);
|
|
231
|
+
if (memory.tags && memory.tags.length > 0) {
|
|
232
|
+
console.log(chalk.green('Tags:'), memory.tags.join(', '));
|
|
233
|
+
}
|
|
234
|
+
if (memory.topic_id) {
|
|
235
|
+
console.log(chalk.green('Topic ID:'), memory.topic_id);
|
|
236
|
+
}
|
|
237
|
+
console.log();
|
|
238
|
+
console.log(chalk.green('Content:'));
|
|
239
|
+
console.log(wrap(memory.content, { width: 80, indent: ' ' }));
|
|
240
|
+
if (memory.metadata && Object.keys(memory.metadata).length > 0) {
|
|
241
|
+
console.log();
|
|
242
|
+
console.log(chalk.green('Metadata:'));
|
|
243
|
+
console.log(JSON.stringify(memory.metadata, null, 2));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
console.error(chalk.red('✖ Failed to get memory:'), error.message);
|
|
248
|
+
process.exit(1);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
// Update memory
|
|
252
|
+
program
|
|
253
|
+
.command('update')
|
|
254
|
+
.description('Update a memory entry')
|
|
255
|
+
.argument('<id>', 'memory ID')
|
|
256
|
+
.option('-t, --title <title>', 'new title')
|
|
257
|
+
.option('-c, --content <content>', 'new content')
|
|
258
|
+
.option('--type <type>', 'new memory type')
|
|
259
|
+
.option('--tags <tags>', 'new tags (comma-separated)')
|
|
260
|
+
.option('-i, --interactive', 'interactive mode')
|
|
261
|
+
.action(async (id, options) => {
|
|
262
|
+
try {
|
|
263
|
+
let updateData = {};
|
|
264
|
+
if (options.interactive) {
|
|
265
|
+
// First, get current memory data
|
|
266
|
+
const spinner = ora('Fetching current memory...').start();
|
|
267
|
+
const currentMemory = await apiClient.getMemory(id);
|
|
268
|
+
spinner.stop();
|
|
269
|
+
const answers = await inquirer.prompt([
|
|
270
|
+
{
|
|
271
|
+
type: 'input',
|
|
272
|
+
name: 'title',
|
|
273
|
+
message: 'Title:',
|
|
274
|
+
default: currentMemory.title
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
type: 'editor',
|
|
278
|
+
name: 'content',
|
|
279
|
+
message: 'Content:',
|
|
280
|
+
default: currentMemory.content
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
type: 'list',
|
|
284
|
+
name: 'type',
|
|
285
|
+
message: 'Memory type:',
|
|
286
|
+
choices: ['conversation', 'knowledge', 'project', 'context', 'reference'],
|
|
287
|
+
default: currentMemory.memory_type
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
type: 'input',
|
|
291
|
+
name: 'tags',
|
|
292
|
+
message: 'Tags (comma-separated):',
|
|
293
|
+
default: currentMemory.tags.join(', ')
|
|
294
|
+
}
|
|
295
|
+
]);
|
|
296
|
+
updateData = {
|
|
297
|
+
title: answers.title,
|
|
298
|
+
content: answers.content,
|
|
299
|
+
memory_type: answers.type,
|
|
300
|
+
tags: answers.tags.split(',').map((tag) => tag.trim()).filter(Boolean)
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
if (options.title)
|
|
305
|
+
updateData.title = options.title;
|
|
306
|
+
if (options.content)
|
|
307
|
+
updateData.content = options.content;
|
|
308
|
+
if (options.type)
|
|
309
|
+
updateData.memory_type = options.type;
|
|
310
|
+
if (options.tags) {
|
|
311
|
+
updateData.tags = options.tags.split(',').map((tag) => tag.trim()).filter(Boolean);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (Object.keys(updateData).length === 0) {
|
|
315
|
+
console.log(chalk.yellow('No updates specified'));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const spinner = ora('Updating memory...').start();
|
|
319
|
+
const memory = await apiClient.updateMemory(id, updateData);
|
|
320
|
+
spinner.succeed('Memory updated successfully');
|
|
321
|
+
console.log();
|
|
322
|
+
console.log(chalk.green('✓ Memory updated:'));
|
|
323
|
+
console.log(` ID: ${chalk.cyan(memory.id)}`);
|
|
324
|
+
console.log(` Title: ${memory.title}`);
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
console.error(chalk.red('✖ Failed to update memory:'), error.message);
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
// Delete memory
|
|
332
|
+
program
|
|
333
|
+
.command('delete')
|
|
334
|
+
.alias('rm')
|
|
335
|
+
.description('Delete a memory entry')
|
|
336
|
+
.argument('<id>', 'memory ID')
|
|
337
|
+
.option('-f, --force', 'skip confirmation')
|
|
338
|
+
.action(async (id, options) => {
|
|
339
|
+
try {
|
|
340
|
+
if (!options.force) {
|
|
341
|
+
const memory = await apiClient.getMemory(id);
|
|
342
|
+
const answer = await inquirer.prompt([
|
|
343
|
+
{
|
|
344
|
+
type: 'confirm',
|
|
345
|
+
name: 'confirm',
|
|
346
|
+
message: `Are you sure you want to delete "${memory.title}"?`,
|
|
347
|
+
default: false
|
|
348
|
+
}
|
|
349
|
+
]);
|
|
350
|
+
if (!answer.confirm) {
|
|
351
|
+
console.log(chalk.yellow('Deletion cancelled'));
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const spinner = ora('Deleting memory...').start();
|
|
356
|
+
await apiClient.deleteMemory(id);
|
|
357
|
+
spinner.succeed('Memory deleted successfully');
|
|
358
|
+
}
|
|
359
|
+
catch (error) {
|
|
360
|
+
console.error(chalk.red('✖ Failed to delete memory:'), error.message);
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
// Memory statistics
|
|
365
|
+
program
|
|
366
|
+
.command('stats')
|
|
367
|
+
.description('Show memory statistics (admin only)')
|
|
368
|
+
.action(async () => {
|
|
369
|
+
try {
|
|
370
|
+
const spinner = ora('Fetching statistics...').start();
|
|
371
|
+
const stats = await apiClient.getMemoryStats();
|
|
372
|
+
spinner.stop();
|
|
373
|
+
console.log(chalk.blue.bold('\n📊 Memory Statistics'));
|
|
374
|
+
console.log();
|
|
375
|
+
console.log(chalk.green('Total Memories:'), stats.total_memories.toLocaleString());
|
|
376
|
+
console.log(chalk.green('Total Size:'), formatBytes(stats.total_size_bytes));
|
|
377
|
+
console.log(chalk.green('Average Access Count:'), stats.avg_access_count);
|
|
378
|
+
console.log();
|
|
379
|
+
console.log(chalk.yellow('Memories by Type:'));
|
|
380
|
+
Object.entries(stats.memories_by_type).forEach(([type, count]) => {
|
|
381
|
+
console.log(` ${type}: ${count}`);
|
|
382
|
+
});
|
|
383
|
+
if (stats.most_accessed_memory) {
|
|
384
|
+
console.log();
|
|
385
|
+
console.log(chalk.yellow('Most Accessed Memory:'));
|
|
386
|
+
console.log(` ${stats.most_accessed_memory.title} (${stats.most_accessed_memory.access_count} times)`);
|
|
387
|
+
}
|
|
388
|
+
if (stats.recent_memories.length > 0) {
|
|
389
|
+
console.log();
|
|
390
|
+
console.log(chalk.yellow('Recent Memories:'));
|
|
391
|
+
stats.recent_memories.forEach((memory, index) => {
|
|
392
|
+
console.log(` ${index + 1}. ${truncateText(memory.title, 50)}`);
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
console.error(chalk.red('✖ Failed to get statistics:'), error.message);
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { CLIConfig } from '../utils/config.js';
|
|
3
|
+
export function orgCommands(program) {
|
|
4
|
+
// Show organization info
|
|
5
|
+
program
|
|
6
|
+
.command('info')
|
|
7
|
+
.description('Show organization information')
|
|
8
|
+
.action(async () => {
|
|
9
|
+
const config = new CLIConfig();
|
|
10
|
+
await config.init();
|
|
11
|
+
const user = await config.getCurrentUser();
|
|
12
|
+
if (!user) {
|
|
13
|
+
console.error(chalk.red('✖ Not authenticated'));
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk.blue.bold('🏢 Organization Information'));
|
|
17
|
+
console.log();
|
|
18
|
+
console.log(chalk.green('Organization ID:'), user.organization_id);
|
|
19
|
+
console.log(chalk.green('Your Role:'), user.role);
|
|
20
|
+
console.log(chalk.green('Plan:'), user.plan);
|
|
21
|
+
console.log(chalk.green('Email:'), user.email);
|
|
22
|
+
// In a full implementation, you'd fetch more org details from the API
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(chalk.gray('Note: Use the web dashboard for full organization management'));
|
|
25
|
+
});
|
|
26
|
+
// Placeholder for future org management commands
|
|
27
|
+
program
|
|
28
|
+
.command('members')
|
|
29
|
+
.description('List organization members (admin only)')
|
|
30
|
+
.action(async () => {
|
|
31
|
+
console.log(chalk.yellow('⚠️ This feature is not yet implemented'));
|
|
32
|
+
console.log(chalk.gray('Use the web dashboard to manage organization members'));
|
|
33
|
+
});
|
|
34
|
+
program
|
|
35
|
+
.command('usage')
|
|
36
|
+
.description('Show organization usage statistics')
|
|
37
|
+
.action(async () => {
|
|
38
|
+
console.log(chalk.yellow('⚠️ This feature is not yet implemented'));
|
|
39
|
+
console.log(chalk.gray('Use the web dashboard to view usage statistics'));
|
|
40
|
+
});
|
|
41
|
+
}
|