@memnexus-ai/cli 0.1.0 → 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 +9 -2
  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,37 +0,0 @@
1
- // Mock cli-table3 for Jest tests
2
- interface TableOptions {
3
- head?: string[];
4
- colWidths?: number[];
5
- wordWrap?: boolean;
6
- }
7
-
8
- class MockTable {
9
- private rows: unknown[][] = [];
10
- private headers: string[] = [];
11
-
12
- constructor(options?: TableOptions) {
13
- if (options?.head) {
14
- this.headers = options.head;
15
- }
16
- }
17
-
18
- push(row: unknown[]): void {
19
- this.rows.push(row);
20
- }
21
-
22
- toString(): string {
23
- const lines: string[] = [];
24
-
25
- // Add header row if present
26
- if (this.headers.length > 0) {
27
- lines.push(this.headers.join(' | '));
28
- }
29
-
30
- // Add data rows
31
- lines.push(...this.rows.map((row) => row.join(' | ')));
32
-
33
- return lines.join('\n');
34
- }
35
- }
36
-
37
- export default MockTable;
@@ -1,38 +0,0 @@
1
- // Mock Configstore for Jest tests
2
- class MockConfigstore {
3
- private store: Record<string, unknown> = {};
4
- private defaults: Record<string, unknown> = {};
5
-
6
- constructor(_name: string, defaults?: Record<string, unknown>) {
7
- if (defaults) {
8
- this.defaults = { ...defaults };
9
- this.store = { ...defaults };
10
- }
11
- }
12
-
13
- get all() {
14
- return this.store;
15
- }
16
-
17
- set all(value: Record<string, unknown>) {
18
- this.store = { ...value };
19
- }
20
-
21
- get(key: string): unknown {
22
- return this.store[key];
23
- }
24
-
25
- set(key: string, value: unknown): void {
26
- this.store[key] = value;
27
- }
28
-
29
- delete(key: string): void {
30
- delete this.store[key];
31
- }
32
-
33
- clear(): void {
34
- this.store = {};
35
- }
36
- }
37
-
38
- export default MockConfigstore;
@@ -1,179 +0,0 @@
1
- import { getApiClient } from '../../src/lib/api-client';
2
-
3
- // Mock the API client
4
- jest.mock('../../src/lib/api-client');
5
-
6
- // Mock chalk
7
- jest.mock('chalk', () => ({
8
- default: {
9
- green: (str: string) => str,
10
- red: (str: string) => str,
11
- yellow: (str: string) => str,
12
- cyan: (str: string) => str,
13
- gray: (str: string) => str,
14
- },
15
- green: (str: string) => str,
16
- red: (str: string) => str,
17
- yellow: (str: string) => str,
18
- cyan: (str: string) => str,
19
- gray: (str: string) => str,
20
- }));
21
-
22
- // Mock ora
23
- jest.mock('ora', () => {
24
- return jest.fn(() => ({
25
- start: jest.fn(function() { return this; }),
26
- succeed: jest.fn(function() { return this; }),
27
- fail: jest.fn(function() { return this; }),
28
- }));
29
- });
30
-
31
- describe('API Keys Commands', () => {
32
- let mockClient: any;
33
-
34
- beforeEach(() => {
35
- jest.clearAllMocks();
36
-
37
- mockClient = {
38
- apikeys: {
39
- list: jest.fn(),
40
- get: jest.fn(),
41
- create: jest.fn(),
42
- delete: jest.fn(),
43
- },
44
- };
45
-
46
- (getApiClient as jest.Mock).mockReturnValue(mockClient);
47
- });
48
-
49
- describe('apikeys list', () => {
50
- it('should list API keys with metadata only', async () => {
51
- const mockResponse = {
52
- data: [
53
- {
54
- id: 'key_1',
55
- name: 'Production Key',
56
- status: 'active',
57
- createdAt: '2024-01-01T00:00:00Z',
58
- lastUsed: '2024-01-10T00:00:00Z',
59
- },
60
- ],
61
- pagination: {
62
- limit: 20,
63
- offset: 0,
64
- count: 1,
65
- },
66
- };
67
-
68
- mockClient.apikeys.list.mockResolvedValue(mockResponse);
69
-
70
- const result = await mockClient.apikeys.list({ limit: 20, offset: 0 });
71
-
72
- expect(mockClient.apikeys.list).toHaveBeenCalledWith({ limit: 20, offset: 0 });
73
- expect(result.data).toHaveLength(1);
74
- expect(result.data[0].name).toBe('Production Key');
75
- });
76
- });
77
-
78
- describe('apikeys get', () => {
79
- it('should get API key metadata without value', async () => {
80
- const mockKey = {
81
- id: 'key_1',
82
- name: 'Production Key',
83
- status: 'active',
84
- createdAt: '2024-01-01T00:00:00Z',
85
- value: 'sk_live_secret_key_value', // Should not be returned
86
- };
87
-
88
- mockClient.apikeys.get.mockResolvedValue(mockKey);
89
-
90
- const result = await mockClient.apikeys.get('key_1');
91
-
92
- expect(mockClient.apikeys.get).toHaveBeenCalledWith('key_1');
93
- expect(result.id).toBe('key_1');
94
- expect(result.name).toBe('Production Key');
95
- // Value should be present in mock but should be filtered in actual command
96
- expect(result.value).toBeDefined();
97
- });
98
- });
99
-
100
- describe('apikeys create', () => {
101
- it('should create API key and show value once', async () => {
102
- const mockResult = {
103
- id: 'key_1',
104
- name: 'New Key',
105
- value: 'sk_live_new_secret_key_value',
106
- status: 'active',
107
- createdAt: '2024-01-01T00:00:00Z',
108
- scopes: ['read', 'write'],
109
- };
110
-
111
- mockClient.apikeys.create.mockResolvedValue(mockResult);
112
-
113
- const result = await mockClient.apikeys.create({
114
- name: 'New Key',
115
- scopes: ['read', 'write'],
116
- });
117
-
118
- expect(mockClient.apikeys.create).toHaveBeenCalledWith({
119
- name: 'New Key',
120
- scopes: ['read', 'write'],
121
- });
122
- expect(result.id).toBe('key_1');
123
- expect(result.value).toBe('sk_live_new_secret_key_value');
124
- });
125
-
126
- it('should create API key with expiration', async () => {
127
- const mockResult = {
128
- id: 'key_1',
129
- name: 'Temporary Key',
130
- value: 'sk_live_temp_key_value',
131
- expiresAt: '2024-02-01T00:00:00Z',
132
- };
133
-
134
- mockClient.apikeys.create.mockResolvedValue(mockResult);
135
-
136
- const result = await mockClient.apikeys.create({
137
- name: 'Temporary Key',
138
- expiresIn: 30,
139
- });
140
-
141
- expect(mockClient.apikeys.create).toHaveBeenCalledWith({
142
- name: 'Temporary Key',
143
- expiresIn: 30,
144
- });
145
- expect(result.expiresAt).toBeDefined();
146
- });
147
- });
148
-
149
- describe('apikeys delete', () => {
150
- it('should delete API key', async () => {
151
- mockClient.apikeys.delete.mockResolvedValue({ success: true });
152
-
153
- const result = await mockClient.apikeys.delete('key_1');
154
-
155
- expect(mockClient.apikeys.delete).toHaveBeenCalledWith('key_1');
156
- expect(result.success).toBe(true);
157
- });
158
- });
159
-
160
- describe('security considerations', () => {
161
- it('should never store or log key values', async () => {
162
- const mockKey = {
163
- id: 'key_1',
164
- name: 'Secure Key',
165
- value: 'sk_live_secret_value',
166
- };
167
-
168
- mockClient.apikeys.get.mockResolvedValue(mockKey);
169
-
170
- const result = await mockClient.apikeys.get('key_1');
171
-
172
- // The actual command should filter out the value
173
- // This test verifies the mock returns it, but the command filters it
174
- expect(result.value).toBeDefined();
175
- expect(result.id).toBe('key_1');
176
- });
177
- });
178
- });
179
-
@@ -1,194 +0,0 @@
1
- import { getApiClient } from '../../src/lib/api-client';
2
-
3
- // Mock the API client
4
- jest.mock('../../src/lib/api-client');
5
-
6
- // Mock chalk
7
- jest.mock('chalk', () => ({
8
- default: {
9
- green: (str: string) => str,
10
- red: (str: string) => str,
11
- yellow: (str: string) => str,
12
- cyan: (str: string) => str,
13
- gray: (str: string) => str,
14
- },
15
- green: (str: string) => str,
16
- red: (str: string) => str,
17
- yellow: (str: string) => str,
18
- cyan: (str: string) => str,
19
- gray: (str: string) => str,
20
- }));
21
-
22
- // Mock ora
23
- jest.mock('ora', () => {
24
- return jest.fn(() => ({
25
- start: jest.fn(function() { return this; }),
26
- succeed: jest.fn(function() { return this; }),
27
- fail: jest.fn(function() { return this; }),
28
- }));
29
- });
30
-
31
- describe('Artifacts Commands', () => {
32
- let mockClient: any;
33
-
34
- beforeEach(() => {
35
- jest.clearAllMocks();
36
-
37
- mockClient = {
38
- artifacts: {
39
- list: jest.fn(),
40
- get: jest.fn(),
41
- create: jest.fn(),
42
- update: jest.fn(),
43
- delete: jest.fn(),
44
- },
45
- };
46
-
47
- (getApiClient as jest.Mock).mockReturnValue(mockClient);
48
- });
49
-
50
- describe('artifacts list', () => {
51
- it('should list artifacts with default pagination', async () => {
52
- const mockResponse = {
53
- data: [
54
- {
55
- id: 'art_1',
56
- name: 'Artifact 1',
57
- type: 'document',
58
- size: 1024,
59
- createdAt: '2024-01-01T00:00:00Z',
60
- },
61
- ],
62
- pagination: {
63
- limit: 20,
64
- offset: 0,
65
- count: 1,
66
- },
67
- };
68
-
69
- mockClient.artifacts.list.mockResolvedValue(mockResponse);
70
-
71
- const result = await mockClient.artifacts.list({ limit: 20, offset: 0 });
72
-
73
- expect(mockClient.artifacts.list).toHaveBeenCalledWith({ limit: 20, offset: 0 });
74
- expect(result.data).toHaveLength(1);
75
- });
76
-
77
- it('should filter by type', async () => {
78
- const mockResponse = {
79
- data: [],
80
- pagination: { limit: 20, offset: 0, count: 0 },
81
- };
82
-
83
- mockClient.artifacts.list.mockResolvedValue(mockResponse);
84
-
85
- await mockClient.artifacts.list({ limit: 20, offset: 0, type: 'document' });
86
-
87
- expect(mockClient.artifacts.list).toHaveBeenCalledWith({
88
- limit: 20,
89
- offset: 0,
90
- type: 'document',
91
- });
92
- });
93
- });
94
-
95
- describe('artifacts get', () => {
96
- it('should get artifact details', async () => {
97
- const mockArtifact = {
98
- id: 'art_1',
99
- name: 'Artifact 1',
100
- type: 'document',
101
- size: 1024,
102
- createdAt: '2024-01-01T00:00:00Z',
103
- };
104
-
105
- mockClient.artifacts.get.mockResolvedValue(mockArtifact);
106
-
107
- const result = await mockClient.artifacts.get('art_1');
108
-
109
- expect(mockClient.artifacts.get).toHaveBeenCalledWith('art_1');
110
- expect(result.id).toBe('art_1');
111
- });
112
- });
113
-
114
- describe('artifacts create', () => {
115
- it('should create artifact', async () => {
116
- const mockResult = {
117
- id: 'art_1',
118
- name: 'New Artifact',
119
- type: 'document',
120
- createdAt: '2024-01-01T00:00:00Z',
121
- };
122
-
123
- mockClient.artifacts.create.mockResolvedValue(mockResult);
124
-
125
- const result = await mockClient.artifacts.create({
126
- name: 'New Artifact',
127
- type: 'document',
128
- });
129
-
130
- expect(mockClient.artifacts.create).toHaveBeenCalledWith({
131
- name: 'New Artifact',
132
- type: 'document',
133
- });
134
- expect(result.id).toBe('art_1');
135
- });
136
-
137
- it('should create artifact with metadata', async () => {
138
- const mockResult = {
139
- id: 'art_1',
140
- name: 'New Artifact',
141
- type: 'document',
142
- metadata: { key: 'value' },
143
- };
144
-
145
- mockClient.artifacts.create.mockResolvedValue(mockResult);
146
-
147
- const result = await mockClient.artifacts.create({
148
- name: 'New Artifact',
149
- type: 'document',
150
- metadata: { key: 'value' },
151
- });
152
-
153
- expect(mockClient.artifacts.create).toHaveBeenCalledWith({
154
- name: 'New Artifact',
155
- type: 'document',
156
- metadata: { key: 'value' },
157
- });
158
- expect(result.metadata).toEqual({ key: 'value' });
159
- });
160
- });
161
-
162
- describe('artifacts update', () => {
163
- it('should update artifact', async () => {
164
- const mockResult = {
165
- id: 'art_1',
166
- name: 'Updated Artifact',
167
- type: 'document',
168
- };
169
-
170
- mockClient.artifacts.update.mockResolvedValue(mockResult);
171
-
172
- const result = await mockClient.artifacts.update('art_1', {
173
- name: 'Updated Artifact',
174
- });
175
-
176
- expect(mockClient.artifacts.update).toHaveBeenCalledWith('art_1', {
177
- name: 'Updated Artifact',
178
- });
179
- expect(result.name).toBe('Updated Artifact');
180
- });
181
- });
182
-
183
- describe('artifacts delete', () => {
184
- it('should delete artifact', async () => {
185
- mockClient.artifacts.delete.mockResolvedValue({ success: true });
186
-
187
- const result = await mockClient.artifacts.delete('art_1');
188
-
189
- expect(mockClient.artifacts.delete).toHaveBeenCalledWith('art_1');
190
- expect(result.success).toBe(true);
191
- });
192
- });
193
- });
194
-
@@ -1,120 +0,0 @@
1
- import { storeApiKey, removeApiKey, getApiKeyStatus } from '../../src/lib/auth';
2
- import { config } from '../../src/lib/config';
3
-
4
- // Mock the config module
5
- jest.mock('../../src/lib/config', () => ({
6
- config: {
7
- setApiKey: jest.fn(),
8
- delete: jest.fn(),
9
- get: jest.fn(),
10
- },
11
- }));
12
-
13
- // Mock chalk to avoid color codes in tests
14
- jest.mock('chalk', () => ({
15
- default: {
16
- green: (str: string) => str,
17
- red: (str: string) => str,
18
- yellow: (str: string) => str,
19
- cyan: (str: string) => str,
20
- gray: (str: string) => str,
21
- },
22
- green: (str: string) => str,
23
- red: (str: string) => str,
24
- yellow: (str: string) => str,
25
- cyan: (str: string) => str,
26
- gray: (str: string) => str,
27
- }));
28
-
29
- describe('Auth Commands', () => {
30
- beforeEach(() => {
31
- jest.clearAllMocks();
32
- // Clear environment variables
33
- delete process.env.MX_API_KEY;
34
- });
35
-
36
- describe('storeApiKey', () => {
37
- it('should store a valid API key', () => {
38
- const apiKey = 'test_api_key_12345';
39
- const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
40
-
41
- storeApiKey(apiKey);
42
-
43
- expect(config.setApiKey).toHaveBeenCalledWith(apiKey);
44
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('API key saved successfully'));
45
-
46
- consoleSpy.mockRestore();
47
- });
48
-
49
- it('should throw error for empty API key', () => {
50
- expect(() => storeApiKey('')).toThrow('API key cannot be empty');
51
- expect(config.setApiKey).not.toHaveBeenCalled();
52
- });
53
-
54
- it('should throw error for whitespace-only API key', () => {
55
- expect(() => storeApiKey(' ')).toThrow('API key cannot be empty');
56
- expect(config.setApiKey).not.toHaveBeenCalled();
57
- });
58
- });
59
-
60
- describe('removeApiKey', () => {
61
- it('should remove stored API key', () => {
62
- const consoleSpy = jest.spyOn(console, 'log').mockImplementation();
63
-
64
- removeApiKey();
65
-
66
- expect(config.delete).toHaveBeenCalledWith('apiKey');
67
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('API key removed'));
68
-
69
- consoleSpy.mockRestore();
70
- });
71
- });
72
-
73
- describe('getApiKeyStatus', () => {
74
- it('should return env source when API key is in environment', () => {
75
- process.env.MX_API_KEY = 'env_api_key';
76
-
77
- const status = getApiKeyStatus();
78
-
79
- expect(status).toEqual({
80
- configured: true,
81
- source: 'env',
82
- });
83
- });
84
-
85
- it('should return config source when API key is in config file', () => {
86
- (config.get as jest.Mock).mockReturnValue('config_api_key');
87
-
88
- const status = getApiKeyStatus();
89
-
90
- expect(status).toEqual({
91
- configured: true,
92
- source: 'config',
93
- });
94
- });
95
-
96
- it('should return none when no API key is configured', () => {
97
- (config.get as jest.Mock).mockReturnValue(undefined);
98
-
99
- const status = getApiKeyStatus();
100
-
101
- expect(status).toEqual({
102
- configured: false,
103
- source: 'none',
104
- });
105
- });
106
-
107
- it('should prioritize environment variable over config file', () => {
108
- process.env.MX_API_KEY = 'env_api_key';
109
- (config.get as jest.Mock).mockReturnValue('config_api_key');
110
-
111
- const status = getApiKeyStatus();
112
-
113
- expect(status).toEqual({
114
- configured: true,
115
- source: 'env',
116
- });
117
- });
118
- });
119
- });
120
-