@memnexus-ai/cli 0.1.1 → 0.1.2

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.
Files changed (60) hide show
  1. package/package.json +8 -1
  2. package/.env.example +0 -13
  3. package/.eslintrc.js +0 -24
  4. package/.github/ISSUE_TEMPLATE/phase-1-foundation.md +0 -1078
  5. package/.github/workflows/publish.yml +0 -277
  6. package/.github/workflows/test-app-token.yml +0 -54
  7. package/.npmrc.backup +0 -3
  8. package/.npmrc.example +0 -6
  9. package/.prettierignore +0 -4
  10. package/.prettierrc +0 -8
  11. package/PLATFORM_TESTING.md +0 -243
  12. package/RELEASE.md +0 -428
  13. package/RELEASE_READINESS.md +0 -253
  14. package/docs/README.md +0 -219
  15. package/docs/code-generation-strategy.md +0 -560
  16. package/docs/prd.md +0 -748
  17. package/docs/sync-strategy.md +0 -533
  18. package/jest.config.js +0 -30
  19. package/scripts/install-deps.sh +0 -38
  20. package/src/commands/apikeys.ts +0 -144
  21. package/src/commands/artifacts.ts +0 -296
  22. package/src/commands/auth.ts +0 -122
  23. package/src/commands/communities.ts +0 -153
  24. package/src/commands/config.ts +0 -144
  25. package/src/commands/conversations.ts +0 -176
  26. package/src/commands/facts.ts +0 -320
  27. package/src/commands/graphrag.ts +0 -149
  28. package/src/commands/memories.ts +0 -332
  29. package/src/commands/patterns.ts +0 -251
  30. package/src/commands/system.ts +0 -102
  31. package/src/commands/topics.ts +0 -354
  32. package/src/index.ts +0 -43
  33. package/src/lib/api-client.ts +0 -68
  34. package/src/lib/auth.ts +0 -42
  35. package/src/lib/config.ts +0 -68
  36. package/src/lib/errors.ts +0 -143
  37. package/src/lib/formatters.ts +0 -123
  38. package/src/lib/spinner.ts +0 -113
  39. package/src/lib/validators.ts +0 -302
  40. package/src/types/index.ts +0 -17
  41. package/tests/__mocks__/chalk.ts +0 -16
  42. package/tests/__mocks__/cli-table3.ts +0 -37
  43. package/tests/__mocks__/configstore.ts +0 -38
  44. package/tests/commands/apikeys.test.ts +0 -179
  45. package/tests/commands/artifacts.test.ts +0 -194
  46. package/tests/commands/auth.test.ts +0 -120
  47. package/tests/commands/communities.test.ts +0 -154
  48. package/tests/commands/config.test.ts +0 -154
  49. package/tests/commands/conversations.test.ts +0 -136
  50. package/tests/commands/facts.test.ts +0 -210
  51. package/tests/commands/graphrag.test.ts +0 -194
  52. package/tests/commands/memories.test.ts +0 -215
  53. package/tests/commands/patterns.test.ts +0 -201
  54. package/tests/commands/system.test.ts +0 -172
  55. package/tests/commands/topics.test.ts +0 -274
  56. package/tests/lib/auth.test.ts +0 -77
  57. package/tests/lib/config.test.ts +0 -50
  58. package/tests/lib/errors.test.ts +0 -126
  59. package/tests/lib/formatters.test.ts +0 -87
  60. package/tsconfig.json +0 -20
@@ -1,320 +0,0 @@
1
- import { Command } from 'commander';
2
- import inquirer from 'inquirer';
3
- import chalk from 'chalk';
4
- import {
5
- listFacts,
6
- getFactById,
7
- createFact,
8
- updateFact,
9
- deleteFact,
10
- searchFacts,
11
- } from '@memnexus-ai/mx-typescript-sdk';
12
- import { getApiOptions } from '../lib/api-client';
13
- import { handleError } from '../lib/errors';
14
- import { printOutput } from '../lib/formatters';
15
- import { OutputFormat } from '../types';
16
-
17
- /**
18
- * Register semantic facts management commands
19
- * @param program - Commander program instance
20
- */
21
- export function registerFactsCommands(program: Command): void {
22
- const facts = program.command('facts').description('Manage semantic facts');
23
-
24
- /**
25
- * mx facts list [options]
26
- * List facts with pagination
27
- */
28
- facts
29
- .command('list')
30
- .description('List facts')
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 listFacts({
41
- ...getApiOptions(),
42
- query: { limit, offset },
43
- });
44
-
45
- // Format for table display
46
- if (options.format === 'table' || !options.format) {
47
- const tableData = (result.data?.data || []).map((f: any) => ({
48
- id: f.id,
49
- subject: f.subject?.substring(0, 20) + (f.subject?.length > 20 ? '...' : ''),
50
- predicate: f.predicate,
51
- object: f.object?.substring(0, 20) + (f.object?.length > 20 ? '...' : ''),
52
- confidence: f.confidence?.toFixed(2) || 'N/A',
53
- }));
54
-
55
- printOutput(tableData, options.format as OutputFormat, {
56
- columns: ['id', 'subject', 'predicate', 'object', 'confidence'],
57
- maxColumnWidth: 25,
58
- });
59
-
60
- console.log(
61
- chalk.gray(
62
- `\nShowing ${offset + 1}-${offset + (result.data?.data?.length || 0)} of ${
63
- result.data?.count || 0
64
- } (Page ${page + 1})`
65
- )
66
- );
67
- } else {
68
- printOutput(result.data, options.format as OutputFormat);
69
- }
70
- } catch (error) {
71
- handleError(error);
72
- }
73
- });
74
-
75
- /**
76
- * mx facts get <id>
77
- * Get a specific fact by ID
78
- */
79
- facts
80
- .command('get <id>')
81
- .description('Get a specific fact')
82
- .option('--format <format>', 'Output format (json|table|yaml)')
83
- .action(async (id: string, options) => {
84
- try {
85
- const result = await getFactById({
86
- ...getApiOptions(),
87
- path: { id },
88
- });
89
- printOutput(result.data?.data, options.format as OutputFormat);
90
- } catch (error) {
91
- handleError(error);
92
- }
93
- });
94
-
95
- /**
96
- * mx facts create [options]
97
- * Create a new fact
98
- */
99
- facts
100
- .command('create')
101
- .description('Create a new fact')
102
- .option('--subject <text>', 'Fact subject (entity name)')
103
- .option('--predicate <text>', 'Relationship type')
104
- .option('--object <text>', 'Fact object (related entity)')
105
- .option('--confidence <number>', 'Confidence score (0-1)', '1.0')
106
- .option('--memory-id <id>', 'Associated memory ID')
107
- .option('--interactive', 'Interactive mode')
108
- .option('--format <format>', 'Output format (json|table|yaml)')
109
- .action(async (options) => {
110
- try {
111
- let factData: any = {};
112
-
113
- if (options.interactive || !options.subject || !options.predicate || !options.object) {
114
- // Interactive mode
115
- const answers = await inquirer.prompt([
116
- {
117
- type: 'input',
118
- name: 'subject',
119
- message: 'Subject (entity name):',
120
- default: options.subject,
121
- validate: (input: string) => input.trim().length > 0 || 'Subject is required',
122
- },
123
- {
124
- type: 'input',
125
- name: 'predicate',
126
- message: 'Predicate (relationship):',
127
- default: options.predicate,
128
- validate: (input: string) => input.trim().length > 0 || 'Predicate is required',
129
- },
130
- {
131
- type: 'input',
132
- name: 'object',
133
- message: 'Object (related entity):',
134
- default: options.object,
135
- validate: (input: string) => input.trim().length > 0 || 'Object is required',
136
- },
137
- {
138
- type: 'number',
139
- name: 'confidence',
140
- message: 'Confidence (0-1):',
141
- default: parseFloat(options.confidence) || 1.0,
142
- validate: (input: number) => {
143
- if (input < 0 || input > 1) return 'Confidence must be between 0 and 1';
144
- return true;
145
- },
146
- },
147
- {
148
- type: 'input',
149
- name: 'memoryId',
150
- message: 'Memory ID (optional):',
151
- default: options.memoryId,
152
- },
153
- ]);
154
-
155
- factData = {
156
- subject: answers.subject,
157
- predicate: answers.predicate,
158
- object: answers.object,
159
- confidence: answers.confidence,
160
- memoryId: answers.memoryId || undefined,
161
- };
162
- } else {
163
- // Direct mode
164
- factData = {
165
- subject: options.subject,
166
- predicate: options.predicate,
167
- object: options.object,
168
- confidence: parseFloat(options.confidence),
169
- memoryId: options.memoryId,
170
- };
171
- }
172
-
173
- const result = await createFact({
174
- ...getApiOptions(),
175
- body: factData,
176
- });
177
-
178
- const fact = result.data?.data;
179
- console.log(chalk.green(`✓ Fact created with ID: ${fact?.id}`));
180
- printOutput(fact, options.format as OutputFormat);
181
- } catch (error) {
182
- handleError(error);
183
- }
184
- });
185
-
186
- /**
187
- * mx facts update <id> [options]
188
- * Update an existing fact
189
- */
190
- facts
191
- .command('update <id>')
192
- .description('Update an existing fact')
193
- .option('--subject <text>', 'Updated subject')
194
- .option('--predicate <text>', 'Updated predicate')
195
- .option('--object <text>', 'Updated object')
196
- .option('--confidence <number>', 'Updated confidence (0-1)')
197
- .option('--format <format>', 'Output format (json|table|yaml)')
198
- .action(async (id: string, options) => {
199
- try {
200
- const updates: any = {};
201
-
202
- if (options.subject) updates.subject = options.subject;
203
- if (options.predicate) updates.predicate = options.predicate;
204
- if (options.object) updates.object = options.object;
205
- if (options.confidence) {
206
- const conf = parseFloat(options.confidence);
207
- if (conf < 0 || conf > 1) {
208
- console.log(chalk.red('Error: Confidence must be between 0 and 1'));
209
- return;
210
- }
211
- updates.confidence = conf;
212
- }
213
-
214
- if (Object.keys(updates).length === 0) {
215
- console.log(chalk.yellow('No updates provided. Use --help to see available options.'));
216
- return;
217
- }
218
-
219
- const result = await updateFact({
220
- ...getApiOptions(),
221
- path: { id },
222
- body: updates,
223
- });
224
-
225
- const fact = result.data?.data;
226
- console.log(chalk.green(`✓ Fact ${id} updated successfully`));
227
- printOutput(fact, options.format as OutputFormat);
228
- } catch (error) {
229
- handleError(error);
230
- }
231
- });
232
-
233
- /**
234
- * mx facts delete <id>
235
- * Delete a fact
236
- */
237
- facts
238
- .command('delete <id>')
239
- .description('Delete a fact')
240
- .option('--force', 'Skip confirmation prompt')
241
- .action(async (id: string, options) => {
242
- try {
243
- if (!options.force) {
244
- const answers = await inquirer.prompt([
245
- {
246
- type: 'confirm',
247
- name: 'confirm',
248
- message: `Are you sure you want to delete fact ${id}?`,
249
- default: false,
250
- },
251
- ]);
252
-
253
- if (!answers.confirm) {
254
- console.log(chalk.yellow('Delete cancelled'));
255
- return;
256
- }
257
- }
258
-
259
- await deleteFact({
260
- ...getApiOptions(),
261
- path: { id },
262
- });
263
-
264
- console.log(chalk.green(`✓ Fact ${id} deleted successfully`));
265
- } catch (error) {
266
- handleError(error);
267
- }
268
- });
269
-
270
- /**
271
- * mx facts search [options]
272
- * Search facts
273
- */
274
- facts
275
- .command('search')
276
- .description('Search facts')
277
- .option('--query <text>', 'Search query')
278
- .option('--limit <number>', 'Maximum results', '20')
279
- .option('--format <format>', 'Output format (json|table|yaml)')
280
- .action(async (options) => {
281
- try {
282
- if (!options.query) {
283
- console.log(chalk.red('Error: --query is required'));
284
- return;
285
- }
286
-
287
- const result = await searchFacts({
288
- ...getApiOptions(),
289
- body: {
290
- query: options.query,
291
- limit: parseInt(options.limit, 10),
292
- },
293
- });
294
-
295
- const searchData = result.data;
296
-
297
- // Format for table display
298
- if (options.format === 'table' || !options.format) {
299
- const tableData = (searchData?.data || []).map((f: any) => ({
300
- id: f.id || 'N/A',
301
- subject: f.subject?.substring(0, 20) + (f.subject?.length > 20 ? '...' : ''),
302
- predicate: f.predicate,
303
- object: f.object?.substring(0, 20) + (f.object?.length > 20 ? '...' : ''),
304
- confidence: f.confidence?.toFixed(2) || 'N/A',
305
- }));
306
-
307
- printOutput(tableData, options.format as OutputFormat, {
308
- columns: ['id', 'subject', 'predicate', 'object', 'confidence'],
309
- maxColumnWidth: 25,
310
- });
311
-
312
- console.log(chalk.gray(`\nFound ${searchData?.count || 0} results`));
313
- } else {
314
- printOutput(searchData, options.format as OutputFormat);
315
- }
316
- } catch (error) {
317
- handleError(error);
318
- }
319
- });
320
- }
@@ -1,149 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import ora from 'ora';
4
- import {
5
- executeGraphRagQuery,
6
- explainGraphRagQuery,
7
- queryCommunities,
8
- } from '@memnexus-ai/mx-typescript-sdk';
9
- import { getApiOptions } from '../lib/api-client';
10
- import { handleError } from '../lib/errors';
11
- import { printOutput } from '../lib/formatters';
12
- import { OutputFormat } from '../types';
13
-
14
- /**
15
- * Register GraphRAG query commands
16
- * @param program - Commander program instance
17
- */
18
- export function registerGraphragCommands(program: Command): void {
19
- const graphrag = program.command('graphrag').description('Execute GraphRAG queries');
20
-
21
- /**
22
- * mx graphrag query [options]
23
- * Execute a GraphRAG query
24
- */
25
- graphrag
26
- .command('query')
27
- .description('Execute GraphRAG query')
28
- .option('--query <text>', 'Query text (required)')
29
- .option('--context-id <id>', 'Context ID')
30
- .option('--mode <mode>', 'Query mode (local|global|hybrid)', 'hybrid')
31
- .option('--max-depth <number>', 'Graph traversal depth', '3')
32
- .option('--limit <number>', 'Max results', '20')
33
- .option('--format <format>', 'Output format (json|table|yaml)')
34
- .action(async (options) => {
35
- try {
36
- if (!options.query) {
37
- console.log(chalk.red('Error: --query is required'));
38
- return;
39
- }
40
-
41
- const spinner = ora('Executing GraphRAG query...').start();
42
-
43
- const result = await executeGraphRagQuery({
44
- ...getApiOptions(),
45
- body: {
46
- query: options.query,
47
- maxDepth: parseInt(options.maxDepth, 10),
48
- limit: parseInt(options.limit, 10),
49
- },
50
- });
51
-
52
- spinner.succeed('Query executed successfully');
53
-
54
- const responseData = result.data as any;
55
- if (options.format === 'table' || !options.format) {
56
- const tableData = (responseData?.data || []).map((r: any) => ({
57
- id: r.id,
58
- answer: r.answer?.substring(0, 50) + (r.answer?.length > 50 ? '...' : ''),
59
- sources: r.sources?.length || 0,
60
- confidence: r.confidence || 0,
61
- }));
62
-
63
- printOutput(tableData, options.format as OutputFormat, {
64
- columns: ['id', 'answer', 'sources', 'confidence'],
65
- maxColumnWidth: 25,
66
- });
67
- } else {
68
- printOutput(responseData, options.format as OutputFormat);
69
- }
70
- } catch (error) {
71
- handleError(error);
72
- }
73
- });
74
-
75
- /**
76
- * mx graphrag explain <result-id>
77
- * Explain a query result
78
- */
79
- graphrag
80
- .command('explain <result-id>')
81
- .description('Explain query result')
82
- .option('--format <format>', 'Output format (json|table|yaml)')
83
- .action(async (resultId: string, options) => {
84
- try {
85
- const spinner = ora('Generating explanation...').start();
86
-
87
- const result = await explainGraphRagQuery({
88
- ...getApiOptions(),
89
- query: { queryId: resultId },
90
- });
91
-
92
- spinner.succeed('Explanation generated');
93
- printOutput(result.data, options.format as OutputFormat);
94
- } catch (error) {
95
- handleError(error);
96
- }
97
- });
98
-
99
- /**
100
- * mx graphrag query-communities [options]
101
- * Query at community level
102
- */
103
- graphrag
104
- .command('query-communities')
105
- .description('Query communities')
106
- .option('--query <text>', 'Query text (required)')
107
- .option('--context-id <id>', 'Context ID')
108
- .option('--limit <number>', 'Max communities', '10')
109
- .option('--format <format>', 'Output format (json|table|yaml)')
110
- .action(async (options) => {
111
- try {
112
- if (!options.query) {
113
- console.log(chalk.red('Error: --query is required'));
114
- return;
115
- }
116
-
117
- const spinner = ora('Querying communities...').start();
118
-
119
- const result = await queryCommunities({
120
- ...getApiOptions(),
121
- body: {
122
- query: options.query,
123
- limit: parseInt(options.limit, 10),
124
- },
125
- });
126
-
127
- spinner.succeed('Community query completed');
128
-
129
- const responseData = result.data as any;
130
- if (options.format === 'table' || !options.format) {
131
- const tableData = (responseData?.data || []).map((c: any) => ({
132
- communityId: c.communityId,
133
- communityName: c.communityName || 'N/A',
134
- answer: c.answer?.substring(0, 40) + (c.answer?.length > 40 ? '...' : ''),
135
- confidence: c.confidence || 0,
136
- }));
137
-
138
- printOutput(tableData, options.format as OutputFormat, {
139
- columns: ['communityId', 'communityName', 'answer', 'confidence'],
140
- maxColumnWidth: 20,
141
- });
142
- } else {
143
- printOutput(responseData, options.format as OutputFormat);
144
- }
145
- } catch (error) {
146
- handleError(error);
147
- }
148
- });
149
- }