@memnexus-ai/cli 0.1.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/.env.example +13 -0
- package/.eslintrc.js +24 -0
- package/.github/ISSUE_TEMPLATE/phase-1-foundation.md +1078 -0
- package/.github/workflows/publish.yml +277 -0
- package/.github/workflows/test-app-token.yml +54 -0
- package/.npmrc.backup +3 -0
- package/.npmrc.example +6 -0
- package/.prettierignore +4 -0
- package/.prettierrc +8 -0
- package/CHANGELOG.md +138 -0
- package/PLATFORM_TESTING.md +243 -0
- package/README.md +986 -0
- package/RELEASE.md +428 -0
- package/RELEASE_READINESS.md +253 -0
- package/USAGE.md +1373 -0
- package/bin/mx.js +2 -0
- package/dist/commands/apikeys.d.ts +7 -0
- package/dist/commands/apikeys.d.ts.map +1 -0
- package/dist/commands/apikeys.js +133 -0
- package/dist/commands/apikeys.js.map +1 -0
- package/dist/commands/artifacts.d.ts +7 -0
- package/dist/commands/artifacts.d.ts.map +1 -0
- package/dist/commands/artifacts.js +277 -0
- package/dist/commands/artifacts.js.map +1 -0
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +119 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/communities.d.ts +7 -0
- package/dist/commands/communities.d.ts.map +1 -0
- package/dist/commands/communities.js +137 -0
- package/dist/commands/communities.js.map +1 -0
- package/dist/commands/config.d.ts +7 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +138 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/conversations.d.ts +7 -0
- package/dist/commands/conversations.d.ts.map +1 -0
- package/dist/commands/conversations.js +160 -0
- package/dist/commands/conversations.js.map +1 -0
- package/dist/commands/facts.d.ts +7 -0
- package/dist/commands/facts.d.ts.map +1 -0
- package/dist/commands/facts.js +298 -0
- package/dist/commands/facts.js.map +1 -0
- package/dist/commands/graphrag.d.ts +7 -0
- package/dist/commands/graphrag.d.ts.map +1 -0
- package/dist/commands/graphrag.js +139 -0
- package/dist/commands/graphrag.js.map +1 -0
- package/dist/commands/memories.d.ts +7 -0
- package/dist/commands/memories.d.ts.map +1 -0
- package/dist/commands/memories.js +304 -0
- package/dist/commands/memories.js.map +1 -0
- package/dist/commands/patterns.d.ts +7 -0
- package/dist/commands/patterns.d.ts.map +1 -0
- package/dist/commands/patterns.js +227 -0
- package/dist/commands/patterns.js.map +1 -0
- package/dist/commands/system.d.ts +7 -0
- package/dist/commands/system.d.ts.map +1 -0
- package/dist/commands/system.js +97 -0
- package/dist/commands/system.js.map +1 -0
- package/dist/commands/topics.d.ts +7 -0
- package/dist/commands/topics.d.ts.map +1 -0
- package/dist/commands/topics.js +314 -0
- package/dist/commands/topics.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +29 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +64 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth.d.ts +10 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +47 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +19 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +59 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/errors.d.ts +7 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +133 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/formatters.d.ts +12 -0
- package/dist/lib/formatters.d.ts.map +1 -0
- package/dist/lib/formatters.js +103 -0
- package/dist/lib/formatters.js.map +1 -0
- package/dist/lib/spinner.d.ts +54 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +108 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/validators.d.ts +92 -0
- package/dist/lib/validators.d.ts.map +1 -0
- package/dist/lib/validators.js +257 -0
- package/dist/lib/validators.js.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/docs/README.md +219 -0
- package/docs/code-generation-strategy.md +560 -0
- package/docs/prd.md +748 -0
- package/docs/sync-strategy.md +533 -0
- package/jest.config.js +30 -0
- package/package.json +67 -0
- package/scripts/install-deps.sh +38 -0
- package/src/commands/apikeys.ts +144 -0
- package/src/commands/artifacts.ts +296 -0
- package/src/commands/auth.ts +122 -0
- package/src/commands/communities.ts +153 -0
- package/src/commands/config.ts +144 -0
- package/src/commands/conversations.ts +176 -0
- package/src/commands/facts.ts +320 -0
- package/src/commands/graphrag.ts +149 -0
- package/src/commands/memories.ts +332 -0
- package/src/commands/patterns.ts +251 -0
- package/src/commands/system.ts +102 -0
- package/src/commands/topics.ts +354 -0
- package/src/index.ts +43 -0
- package/src/lib/api-client.ts +68 -0
- package/src/lib/auth.ts +42 -0
- package/src/lib/config.ts +68 -0
- package/src/lib/errors.ts +143 -0
- package/src/lib/formatters.ts +123 -0
- package/src/lib/spinner.ts +113 -0
- package/src/lib/validators.ts +302 -0
- package/src/types/index.ts +17 -0
- package/tests/__mocks__/chalk.ts +16 -0
- package/tests/__mocks__/cli-table3.ts +37 -0
- package/tests/__mocks__/configstore.ts +38 -0
- package/tests/commands/apikeys.test.ts +179 -0
- package/tests/commands/artifacts.test.ts +194 -0
- package/tests/commands/auth.test.ts +120 -0
- package/tests/commands/communities.test.ts +154 -0
- package/tests/commands/config.test.ts +154 -0
- package/tests/commands/conversations.test.ts +136 -0
- package/tests/commands/facts.test.ts +210 -0
- package/tests/commands/graphrag.test.ts +194 -0
- package/tests/commands/memories.test.ts +215 -0
- package/tests/commands/patterns.test.ts +201 -0
- package/tests/commands/system.test.ts +172 -0
- package/tests/commands/topics.test.ts +274 -0
- package/tests/lib/auth.test.ts +77 -0
- package/tests/lib/config.test.ts +50 -0
- package/tests/lib/errors.test.ts +126 -0
- package/tests/lib/formatters.test.ts +87 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import {
|
|
6
|
+
listCommunities,
|
|
7
|
+
getCommunityById,
|
|
8
|
+
mergeCommunities,
|
|
9
|
+
} from '@memnexus-ai/mx-typescript-sdk';
|
|
10
|
+
import { getApiOptions } from '../lib/api-client';
|
|
11
|
+
import { handleError } from '../lib/errors';
|
|
12
|
+
import { printOutput } from '../lib/formatters';
|
|
13
|
+
import { OutputFormat } from '../types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register community management commands
|
|
17
|
+
* @param program - Commander program instance
|
|
18
|
+
*/
|
|
19
|
+
export function registerCommunitiesCommands(program: Command): void {
|
|
20
|
+
const communities = program.command('communities').description('Manage topic communities');
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* mx communities list [options]
|
|
24
|
+
* List communities with pagination
|
|
25
|
+
*/
|
|
26
|
+
communities
|
|
27
|
+
.command('list')
|
|
28
|
+
.description('List communities')
|
|
29
|
+
.option('--page <number>', 'Page number', '0')
|
|
30
|
+
.option('--limit <number>', 'Results per page', '20')
|
|
31
|
+
.option('--context-id <id>', 'Filter by context')
|
|
32
|
+
.option('--min-size <number>', 'Minimum community size')
|
|
33
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
try {
|
|
36
|
+
const page = parseInt(options.page, 10);
|
|
37
|
+
const limit = parseInt(options.limit, 10);
|
|
38
|
+
const offset = page * limit;
|
|
39
|
+
|
|
40
|
+
const result = await listCommunities({
|
|
41
|
+
...getApiOptions(),
|
|
42
|
+
query: {
|
|
43
|
+
limit,
|
|
44
|
+
offset,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const responseData = result.data as any;
|
|
49
|
+
|
|
50
|
+
if (options.format === 'table' || !options.format) {
|
|
51
|
+
const tableData = (responseData?.data || []).map((c: any) => ({
|
|
52
|
+
id: c.id,
|
|
53
|
+
name: c.name || 'N/A',
|
|
54
|
+
memberCount: c.memberCount || 0,
|
|
55
|
+
topicCount: c.topicCount || 0,
|
|
56
|
+
createdAt: new Date(c.createdAt).toLocaleDateString(),
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
printOutput(tableData, options.format as OutputFormat, {
|
|
60
|
+
columns: ['id', 'name', 'memberCount', 'topicCount', 'createdAt'],
|
|
61
|
+
maxColumnWidth: 20,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const pagination = responseData?.pagination;
|
|
65
|
+
if (pagination) {
|
|
66
|
+
console.log(
|
|
67
|
+
chalk.gray(
|
|
68
|
+
`\nShowing ${pagination.offset + 1}-${
|
|
69
|
+
pagination.offset + (responseData?.data?.length || 0)
|
|
70
|
+
} (Page ${page + 1})`
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
printOutput(responseData, options.format as OutputFormat);
|
|
76
|
+
}
|
|
77
|
+
} catch (error) {
|
|
78
|
+
handleError(error);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* mx communities get <id>
|
|
84
|
+
* Get a specific community by ID
|
|
85
|
+
*/
|
|
86
|
+
communities
|
|
87
|
+
.command('get <id>')
|
|
88
|
+
.description('Get community details')
|
|
89
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
90
|
+
.action(async (id: string, options) => {
|
|
91
|
+
try {
|
|
92
|
+
const result = await getCommunityById({
|
|
93
|
+
...getApiOptions(),
|
|
94
|
+
path: { id },
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
handleError(error);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* mx communities merge [options]
|
|
105
|
+
* Merge two communities
|
|
106
|
+
*/
|
|
107
|
+
communities
|
|
108
|
+
.command('merge')
|
|
109
|
+
.description('Merge two communities')
|
|
110
|
+
.option('--source-id <id>', 'Source community ID')
|
|
111
|
+
.option('--target-id <id>', 'Target community ID')
|
|
112
|
+
.option('--force', 'Skip confirmation')
|
|
113
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
114
|
+
.action(async (options) => {
|
|
115
|
+
try {
|
|
116
|
+
if (!options.sourceId || !options.targetId) {
|
|
117
|
+
console.log(chalk.red('Error: --source-id and --target-id are required'));
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (!options.force) {
|
|
122
|
+
const answer = await inquirer.prompt([
|
|
123
|
+
{
|
|
124
|
+
type: 'confirm',
|
|
125
|
+
name: 'confirm',
|
|
126
|
+
message: `Merge community ${options.sourceId} into ${options.targetId}?`,
|
|
127
|
+
default: false,
|
|
128
|
+
},
|
|
129
|
+
]);
|
|
130
|
+
|
|
131
|
+
if (!answer.confirm) {
|
|
132
|
+
console.log(chalk.gray('Merge cancelled'));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const spinner = ora('Merging communities...').start();
|
|
138
|
+
|
|
139
|
+
const result = await mergeCommunities({
|
|
140
|
+
...getApiOptions(),
|
|
141
|
+
body: {
|
|
142
|
+
sourceCommunityId: options.sourceId,
|
|
143
|
+
targetCommunityId: options.targetId,
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
spinner.succeed('Communities merged successfully');
|
|
148
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
handleError(error);
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import Table from 'cli-table3';
|
|
4
|
+
import { config } from '../lib/config';
|
|
5
|
+
import { handleError, CLIError } from '../lib/errors';
|
|
6
|
+
import { CLIConfig } from '../types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Register configuration commands
|
|
10
|
+
* @param program - Commander program instance
|
|
11
|
+
*/
|
|
12
|
+
export function registerConfigCommands(program: Command): void {
|
|
13
|
+
const configCmd = program.command('config').description('Manage CLI configuration');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* mx config get <key>
|
|
17
|
+
* Get a specific configuration value
|
|
18
|
+
*/
|
|
19
|
+
configCmd
|
|
20
|
+
.command('get <key>')
|
|
21
|
+
.description('Get a configuration value')
|
|
22
|
+
.action(async (key: string) => {
|
|
23
|
+
try {
|
|
24
|
+
const validKeys: (keyof CLIConfig)[] = ['apiUrl', 'defaultFormat', 'defaultPageSize'];
|
|
25
|
+
|
|
26
|
+
if (!validKeys.includes(key as keyof CLIConfig)) {
|
|
27
|
+
throw new CLIError(`Invalid config key: ${key}. Valid keys are: ${validKeys.join(', ')}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const value = config.get(key as keyof CLIConfig);
|
|
31
|
+
|
|
32
|
+
if (value === undefined) {
|
|
33
|
+
console.log(chalk.gray('(not set)'));
|
|
34
|
+
} else {
|
|
35
|
+
console.log(value);
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
handleError(error);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* mx config set <key> <value>
|
|
44
|
+
* Set a configuration value
|
|
45
|
+
*/
|
|
46
|
+
configCmd
|
|
47
|
+
.command('set <key> <value>')
|
|
48
|
+
.description('Set a configuration value')
|
|
49
|
+
.action(async (key: string, value: string) => {
|
|
50
|
+
try {
|
|
51
|
+
// Validate key
|
|
52
|
+
const validKeys: (keyof CLIConfig)[] = ['apiUrl', 'defaultFormat', 'defaultPageSize'];
|
|
53
|
+
|
|
54
|
+
if (!validKeys.includes(key as keyof CLIConfig)) {
|
|
55
|
+
throw new CLIError(`Invalid config key: ${key}. Valid keys are: ${validKeys.join(', ')}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Validate value based on key
|
|
59
|
+
if (key === 'apiUrl') {
|
|
60
|
+
try {
|
|
61
|
+
new URL(value);
|
|
62
|
+
} catch {
|
|
63
|
+
throw new CLIError('Invalid URL format');
|
|
64
|
+
}
|
|
65
|
+
} else if (key === 'defaultFormat') {
|
|
66
|
+
if (!['json', 'table', 'yaml'].includes(value)) {
|
|
67
|
+
throw new CLIError('Invalid format. Must be one of: json, table, yaml');
|
|
68
|
+
}
|
|
69
|
+
} else if (key === 'defaultPageSize') {
|
|
70
|
+
const num = parseInt(value, 10);
|
|
71
|
+
if (isNaN(num) || num < 1 || num > 100) {
|
|
72
|
+
throw new CLIError('Invalid page size. Must be a number between 1 and 100');
|
|
73
|
+
}
|
|
74
|
+
config.set(key, num);
|
|
75
|
+
console.log(chalk.green(`✓ ${key} set to ${num}`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
config.set(key as keyof CLIConfig, value);
|
|
80
|
+
console.log(chalk.green(`✓ ${key} set to ${value}`));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
handleError(error);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* mx config list
|
|
88
|
+
* List all configuration values
|
|
89
|
+
*/
|
|
90
|
+
configCmd
|
|
91
|
+
.command('list')
|
|
92
|
+
.description('List all configuration values')
|
|
93
|
+
.action(async () => {
|
|
94
|
+
try {
|
|
95
|
+
const allConfig = config.get() as CLIConfig;
|
|
96
|
+
|
|
97
|
+
const table = new Table({
|
|
98
|
+
head: [chalk.cyan('Key'), chalk.cyan('Value'), chalk.cyan('Source')],
|
|
99
|
+
colWidths: [25, 40, 20],
|
|
100
|
+
wordWrap: true,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Check for environment variable overrides
|
|
104
|
+
const envOverrides = {
|
|
105
|
+
apiUrl: process.env.MX_API_URL,
|
|
106
|
+
defaultFormat: process.env.MX_OUTPUT_FORMAT,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
table.push(
|
|
110
|
+
[
|
|
111
|
+
'apiUrl',
|
|
112
|
+
envOverrides.apiUrl || allConfig.apiUrl,
|
|
113
|
+
envOverrides.apiUrl ? chalk.yellow('env') : 'config',
|
|
114
|
+
],
|
|
115
|
+
[
|
|
116
|
+
'defaultFormat',
|
|
117
|
+
envOverrides.defaultFormat || allConfig.defaultFormat,
|
|
118
|
+
envOverrides.defaultFormat ? chalk.yellow('env') : 'config',
|
|
119
|
+
],
|
|
120
|
+
['defaultPageSize', String(allConfig.defaultPageSize), 'config']
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
console.log(table.toString());
|
|
124
|
+
} catch (error) {
|
|
125
|
+
handleError(error);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* mx config reset
|
|
131
|
+
* Reset configuration to defaults
|
|
132
|
+
*/
|
|
133
|
+
configCmd
|
|
134
|
+
.command('reset')
|
|
135
|
+
.description('Reset configuration to defaults')
|
|
136
|
+
.action(async () => {
|
|
137
|
+
try {
|
|
138
|
+
config.reset();
|
|
139
|
+
console.log(chalk.green('✓ Configuration reset to defaults'));
|
|
140
|
+
} catch (error) {
|
|
141
|
+
handleError(error);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import {
|
|
4
|
+
listConversations,
|
|
5
|
+
searchConversations,
|
|
6
|
+
getConversationSummary,
|
|
7
|
+
getConversationTimeline,
|
|
8
|
+
findConversationsByTopic,
|
|
9
|
+
} from '@memnexus-ai/mx-typescript-sdk';
|
|
10
|
+
import { getApiOptions } from '../lib/api-client';
|
|
11
|
+
import { handleError } from '../lib/errors';
|
|
12
|
+
import { printOutput } from '../lib/formatters';
|
|
13
|
+
import { OutputFormat } from '../types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register conversation query commands
|
|
17
|
+
* @param program - Commander program instance
|
|
18
|
+
*/
|
|
19
|
+
export function registerConversationsCommands(program: Command): void {
|
|
20
|
+
const conversations = program
|
|
21
|
+
.command('conversations')
|
|
22
|
+
.description('Query and manage conversations');
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* mx conversations list [options]
|
|
26
|
+
* List conversations with pagination
|
|
27
|
+
*/
|
|
28
|
+
conversations
|
|
29
|
+
.command('list')
|
|
30
|
+
.description('List conversations')
|
|
31
|
+
.option('--page <number>', 'Page number', '0')
|
|
32
|
+
.option('--limit <number>', 'Results per page', '20')
|
|
33
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
34
|
+
.action(async (options) => {
|
|
35
|
+
try {
|
|
36
|
+
const page = parseInt(options.page, 10);
|
|
37
|
+
const limit = parseInt(options.limit, 10);
|
|
38
|
+
const offset = page * limit;
|
|
39
|
+
|
|
40
|
+
const result = await listConversations({
|
|
41
|
+
...getApiOptions(),
|
|
42
|
+
query: { limit, offset },
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const responseData = result.data as any;
|
|
46
|
+
|
|
47
|
+
// Format for table display
|
|
48
|
+
if (options.format === 'table' || !options.format) {
|
|
49
|
+
const tableData = (responseData?.data || []).map((c: any) => ({
|
|
50
|
+
id: c.id,
|
|
51
|
+
title: c.title || c.id,
|
|
52
|
+
messageCount: c.messageCount || 0,
|
|
53
|
+
createdAt: new Date(c.createdAt).toLocaleDateString(),
|
|
54
|
+
}));
|
|
55
|
+
|
|
56
|
+
printOutput(tableData, options.format as OutputFormat, {
|
|
57
|
+
columns: ['id', 'title', 'messageCount', 'createdAt'],
|
|
58
|
+
maxColumnWidth: 30,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const pagination = responseData?.pagination;
|
|
62
|
+
if (pagination) {
|
|
63
|
+
console.log(
|
|
64
|
+
chalk.gray(
|
|
65
|
+
`\nShowing ${pagination.offset + 1}-${
|
|
66
|
+
pagination.offset + (responseData?.data?.length || 0)
|
|
67
|
+
} (Page ${page + 1})`
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
} else {
|
|
72
|
+
printOutput(responseData, options.format as OutputFormat);
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
handleError(error);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* mx conversations summary <id>
|
|
81
|
+
* Get conversation summary
|
|
82
|
+
*/
|
|
83
|
+
conversations
|
|
84
|
+
.command('summary <id>')
|
|
85
|
+
.description('Get conversation summary')
|
|
86
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
87
|
+
.action(async (id: string, options) => {
|
|
88
|
+
try {
|
|
89
|
+
const result = await getConversationSummary({
|
|
90
|
+
...getApiOptions(),
|
|
91
|
+
path: { conversationId: id },
|
|
92
|
+
});
|
|
93
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
handleError(error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* mx conversations timeline <id>
|
|
101
|
+
* Get conversation timeline (chronological messages)
|
|
102
|
+
*/
|
|
103
|
+
conversations
|
|
104
|
+
.command('timeline <id>')
|
|
105
|
+
.description('Get conversation timeline')
|
|
106
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
107
|
+
.action(async (id: string, options) => {
|
|
108
|
+
try {
|
|
109
|
+
const result = await getConversationTimeline({
|
|
110
|
+
...getApiOptions(),
|
|
111
|
+
path: { conversationId: id },
|
|
112
|
+
});
|
|
113
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
114
|
+
} catch (error) {
|
|
115
|
+
handleError(error);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* mx conversations search [options]
|
|
121
|
+
* Search conversations
|
|
122
|
+
*/
|
|
123
|
+
conversations
|
|
124
|
+
.command('search')
|
|
125
|
+
.description('Search conversations')
|
|
126
|
+
.option('--query <text>', 'Search query')
|
|
127
|
+
.option('--limit <number>', 'Maximum results', '20')
|
|
128
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
129
|
+
.action(async (options) => {
|
|
130
|
+
try {
|
|
131
|
+
if (!options.query) {
|
|
132
|
+
console.log(chalk.red('Error: --query is required'));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const result = await searchConversations({
|
|
137
|
+
...getApiOptions(),
|
|
138
|
+
body: {
|
|
139
|
+
query: options.query,
|
|
140
|
+
limit: parseInt(options.limit, 10),
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
handleError(error);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* mx conversations by-topic [options]
|
|
152
|
+
* Find conversations by topic
|
|
153
|
+
*/
|
|
154
|
+
conversations
|
|
155
|
+
.command('by-topic')
|
|
156
|
+
.description('Find conversations by topic')
|
|
157
|
+
.option('--topic-id <id>', 'Topic ID')
|
|
158
|
+
.option('--format <format>', 'Output format (json|table|yaml)')
|
|
159
|
+
.action(async (options) => {
|
|
160
|
+
try {
|
|
161
|
+
if (!options.topicId) {
|
|
162
|
+
console.log(chalk.red('Error: --topic-id is required'));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const result = await findConversationsByTopic({
|
|
167
|
+
...getApiOptions(),
|
|
168
|
+
body: { topicId: options.topicId },
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
printOutput(result.data, options.format as OutputFormat);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
handleError(error);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
}
|