@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,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation result type
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationResult {
|
|
5
|
+
valid: boolean;
|
|
6
|
+
error?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Validate URL format
|
|
10
|
+
* @param url - URL string to validate
|
|
11
|
+
* @returns Validation result with helpful error message
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateUrl(url: string): ValidationResult;
|
|
14
|
+
/**
|
|
15
|
+
* Validate number within range
|
|
16
|
+
* @param value - Value to validate
|
|
17
|
+
* @param min - Minimum value (inclusive)
|
|
18
|
+
* @param max - Maximum value (inclusive)
|
|
19
|
+
* @param fieldName - Name of the field for error messages
|
|
20
|
+
* @returns Validation result with helpful error message
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateNumber(value: any, min?: number, max?: number, fieldName?: string): ValidationResult;
|
|
23
|
+
/**
|
|
24
|
+
* Validate integer within range
|
|
25
|
+
* @param value - Value to validate
|
|
26
|
+
* @param min - Minimum value (inclusive)
|
|
27
|
+
* @param max - Maximum value (inclusive)
|
|
28
|
+
* @param fieldName - Name of the field for error messages
|
|
29
|
+
* @returns Validation result with helpful error message
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateInteger(value: any, min?: number, max?: number, fieldName?: string): ValidationResult;
|
|
32
|
+
/**
|
|
33
|
+
* Validate confidence score (0-1)
|
|
34
|
+
* @param value - Confidence score to validate
|
|
35
|
+
* @returns Validation result with helpful error message
|
|
36
|
+
*/
|
|
37
|
+
export declare function validateConfidence(value: any): ValidationResult;
|
|
38
|
+
/**
|
|
39
|
+
* Validate JSON string
|
|
40
|
+
* @param jsonString - JSON string to validate
|
|
41
|
+
* @param fieldName - Name of the field for error messages
|
|
42
|
+
* @returns Validation result with helpful error message and parsed object
|
|
43
|
+
*/
|
|
44
|
+
export declare function validateJson(jsonString: string, fieldName?: string): ValidationResult & {
|
|
45
|
+
parsed?: any;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Validate output format
|
|
49
|
+
* @param format - Output format to validate
|
|
50
|
+
* @returns Validation result with helpful error message
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateOutputFormat(format: string): ValidationResult;
|
|
53
|
+
/**
|
|
54
|
+
* Validate page number
|
|
55
|
+
* @param page - Page number to validate
|
|
56
|
+
* @returns Validation result with helpful error message
|
|
57
|
+
*/
|
|
58
|
+
export declare function validatePage(page: any): ValidationResult;
|
|
59
|
+
/**
|
|
60
|
+
* Validate limit/page size
|
|
61
|
+
* @param limit - Limit to validate
|
|
62
|
+
* @returns Validation result with helpful error message
|
|
63
|
+
*/
|
|
64
|
+
export declare function validateLimit(limit: any): ValidationResult;
|
|
65
|
+
/**
|
|
66
|
+
* Validate required string field
|
|
67
|
+
* @param value - Value to validate
|
|
68
|
+
* @param fieldName - Name of the field for error messages
|
|
69
|
+
* @param minLength - Minimum length (default: 1)
|
|
70
|
+
* @returns Validation result with helpful error message
|
|
71
|
+
*/
|
|
72
|
+
export declare function validateRequiredString(value: any, fieldName: string, minLength?: number): ValidationResult;
|
|
73
|
+
/**
|
|
74
|
+
* Validate enum value
|
|
75
|
+
* @param value - Value to validate
|
|
76
|
+
* @param allowedValues - Array of allowed values
|
|
77
|
+
* @param fieldName - Name of the field for error messages
|
|
78
|
+
* @returns Validation result with helpful error message
|
|
79
|
+
*/
|
|
80
|
+
export declare function validateEnum(value: any, allowedValues: string[], fieldName: string): ValidationResult;
|
|
81
|
+
/**
|
|
82
|
+
* Print validation error with formatting
|
|
83
|
+
* @param error - Error message to print
|
|
84
|
+
*/
|
|
85
|
+
export declare function printValidationError(error: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Validate and throw if invalid
|
|
88
|
+
* @param result - Validation result
|
|
89
|
+
* @throws Error if validation fails
|
|
90
|
+
*/
|
|
91
|
+
export declare function assertValid(result: ValidationResult): void;
|
|
92
|
+
//# sourceMappingURL=validators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/lib/validators.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CA0BzD;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,GAAG,EACV,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,GAAE,MAAgB,GAC1B,gBAAgB,CAyBlB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,GAAG,EACV,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,GAAE,MAAgB,GAC1B,gBAAgB,CAyBlB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,GAAG,GAAG,gBAAgB,CAW/D;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAe,GACzB,gBAAgB,GAAG;IAAE,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,CAkBrC;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAoBrE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,gBAAgB,CAExD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,gBAAgB,CAE1D;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,GAAG,EACV,SAAS,EAAE,MAAM,EACjB,SAAS,GAAE,MAAU,GACpB,gBAAgB,CAyBlB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,GAAG,EACV,aAAa,EAAE,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAgBlB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAK1D"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateUrl = validateUrl;
|
|
7
|
+
exports.validateNumber = validateNumber;
|
|
8
|
+
exports.validateInteger = validateInteger;
|
|
9
|
+
exports.validateConfidence = validateConfidence;
|
|
10
|
+
exports.validateJson = validateJson;
|
|
11
|
+
exports.validateOutputFormat = validateOutputFormat;
|
|
12
|
+
exports.validatePage = validatePage;
|
|
13
|
+
exports.validateLimit = validateLimit;
|
|
14
|
+
exports.validateRequiredString = validateRequiredString;
|
|
15
|
+
exports.validateEnum = validateEnum;
|
|
16
|
+
exports.printValidationError = printValidationError;
|
|
17
|
+
exports.assertValid = assertValid;
|
|
18
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
19
|
+
/**
|
|
20
|
+
* Validate URL format
|
|
21
|
+
* @param url - URL string to validate
|
|
22
|
+
* @returns Validation result with helpful error message
|
|
23
|
+
*/
|
|
24
|
+
function validateUrl(url) {
|
|
25
|
+
if (!url || url.trim().length === 0) {
|
|
26
|
+
return {
|
|
27
|
+
valid: false,
|
|
28
|
+
error: 'URL cannot be empty',
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const urlObj = new URL(url);
|
|
33
|
+
// Check for valid protocol
|
|
34
|
+
if (!['http:', 'https:'].includes(urlObj.protocol)) {
|
|
35
|
+
return {
|
|
36
|
+
valid: false,
|
|
37
|
+
error: `Invalid protocol "${urlObj.protocol}". Must be http: or https:\nExample: https://api.memnexus.ai`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return { valid: true };
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
return {
|
|
44
|
+
valid: false,
|
|
45
|
+
error: `Invalid URL format\nExample: https://api.memnexus.ai\nProvided: ${url}`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Validate number within range
|
|
51
|
+
* @param value - Value to validate
|
|
52
|
+
* @param min - Minimum value (inclusive)
|
|
53
|
+
* @param max - Maximum value (inclusive)
|
|
54
|
+
* @param fieldName - Name of the field for error messages
|
|
55
|
+
* @returns Validation result with helpful error message
|
|
56
|
+
*/
|
|
57
|
+
function validateNumber(value, min, max, fieldName = 'Value') {
|
|
58
|
+
const num = typeof value === 'string' ? parseFloat(value) : value;
|
|
59
|
+
if (isNaN(num)) {
|
|
60
|
+
return {
|
|
61
|
+
valid: false,
|
|
62
|
+
error: `${fieldName} must be a valid number\nProvided: ${value}`,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (min !== undefined && num < min) {
|
|
66
|
+
return {
|
|
67
|
+
valid: false,
|
|
68
|
+
error: `${fieldName} must be at least ${min}\nProvided: ${num}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (max !== undefined && num > max) {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
error: `${fieldName} must be at most ${max}\nProvided: ${num}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return { valid: true };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate integer within range
|
|
81
|
+
* @param value - Value to validate
|
|
82
|
+
* @param min - Minimum value (inclusive)
|
|
83
|
+
* @param max - Maximum value (inclusive)
|
|
84
|
+
* @param fieldName - Name of the field for error messages
|
|
85
|
+
* @returns Validation result with helpful error message
|
|
86
|
+
*/
|
|
87
|
+
function validateInteger(value, min, max, fieldName = 'Value') {
|
|
88
|
+
const num = typeof value === 'string' ? parseInt(value, 10) : value;
|
|
89
|
+
if (isNaN(num) || !Number.isInteger(num)) {
|
|
90
|
+
return {
|
|
91
|
+
valid: false,
|
|
92
|
+
error: `${fieldName} must be a valid integer\nProvided: ${value}`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (min !== undefined && num < min) {
|
|
96
|
+
return {
|
|
97
|
+
valid: false,
|
|
98
|
+
error: `${fieldName} must be at least ${min}\nProvided: ${num}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (max !== undefined && num > max) {
|
|
102
|
+
return {
|
|
103
|
+
valid: false,
|
|
104
|
+
error: `${fieldName} must be at most ${max}\nProvided: ${num}`,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return { valid: true };
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Validate confidence score (0-1)
|
|
111
|
+
* @param value - Confidence score to validate
|
|
112
|
+
* @returns Validation result with helpful error message
|
|
113
|
+
*/
|
|
114
|
+
function validateConfidence(value) {
|
|
115
|
+
const result = validateNumber(value, 0, 1, 'Confidence score');
|
|
116
|
+
if (!result.valid) {
|
|
117
|
+
return {
|
|
118
|
+
valid: false,
|
|
119
|
+
error: `${result.error}\nConfidence must be between 0 and 1 (e.g., 0.85 for 85% confidence)`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
return { valid: true };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Validate JSON string
|
|
126
|
+
* @param jsonString - JSON string to validate
|
|
127
|
+
* @param fieldName - Name of the field for error messages
|
|
128
|
+
* @returns Validation result with helpful error message and parsed object
|
|
129
|
+
*/
|
|
130
|
+
function validateJson(jsonString, fieldName = 'JSON') {
|
|
131
|
+
if (!jsonString || jsonString.trim().length === 0) {
|
|
132
|
+
return {
|
|
133
|
+
valid: false,
|
|
134
|
+
error: `${fieldName} cannot be empty`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const parsed = JSON.parse(jsonString);
|
|
139
|
+
return { valid: true, parsed };
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
143
|
+
return {
|
|
144
|
+
valid: false,
|
|
145
|
+
error: `Invalid ${fieldName} format: ${errorMessage}\nExample: {"key": "value"}`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate output format
|
|
151
|
+
* @param format - Output format to validate
|
|
152
|
+
* @returns Validation result with helpful error message
|
|
153
|
+
*/
|
|
154
|
+
function validateOutputFormat(format) {
|
|
155
|
+
const validFormats = ['json', 'table', 'yaml'];
|
|
156
|
+
if (!format || format.trim().length === 0) {
|
|
157
|
+
return {
|
|
158
|
+
valid: false,
|
|
159
|
+
error: 'Output format cannot be empty',
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
const normalizedFormat = format.toLowerCase();
|
|
163
|
+
if (!validFormats.includes(normalizedFormat)) {
|
|
164
|
+
return {
|
|
165
|
+
valid: false,
|
|
166
|
+
error: `Invalid output format: ${format}\nValid formats: ${validFormats.join(', ')}`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
return { valid: true };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Validate page number
|
|
173
|
+
* @param page - Page number to validate
|
|
174
|
+
* @returns Validation result with helpful error message
|
|
175
|
+
*/
|
|
176
|
+
function validatePage(page) {
|
|
177
|
+
return validateInteger(page, 0, undefined, 'Page number');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Validate limit/page size
|
|
181
|
+
* @param limit - Limit to validate
|
|
182
|
+
* @returns Validation result with helpful error message
|
|
183
|
+
*/
|
|
184
|
+
function validateLimit(limit) {
|
|
185
|
+
return validateInteger(limit, 1, 1000, 'Limit');
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Validate required string field
|
|
189
|
+
* @param value - Value to validate
|
|
190
|
+
* @param fieldName - Name of the field for error messages
|
|
191
|
+
* @param minLength - Minimum length (default: 1)
|
|
192
|
+
* @returns Validation result with helpful error message
|
|
193
|
+
*/
|
|
194
|
+
function validateRequiredString(value, fieldName, minLength = 1) {
|
|
195
|
+
if (value === undefined || value === null) {
|
|
196
|
+
return {
|
|
197
|
+
valid: false,
|
|
198
|
+
error: `${fieldName} is required`,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const str = String(value).trim();
|
|
202
|
+
if (str.length === 0) {
|
|
203
|
+
return {
|
|
204
|
+
valid: false,
|
|
205
|
+
error: `${fieldName} cannot be empty`,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
if (str.length < minLength) {
|
|
209
|
+
return {
|
|
210
|
+
valid: false,
|
|
211
|
+
error: `${fieldName} must be at least ${minLength} characters\nProvided: ${str.length} characters`,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return { valid: true };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Validate enum value
|
|
218
|
+
* @param value - Value to validate
|
|
219
|
+
* @param allowedValues - Array of allowed values
|
|
220
|
+
* @param fieldName - Name of the field for error messages
|
|
221
|
+
* @returns Validation result with helpful error message
|
|
222
|
+
*/
|
|
223
|
+
function validateEnum(value, allowedValues, fieldName) {
|
|
224
|
+
if (!value || value.trim().length === 0) {
|
|
225
|
+
return {
|
|
226
|
+
valid: false,
|
|
227
|
+
error: `${fieldName} is required\nAllowed values: ${allowedValues.join(', ')}`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
if (!allowedValues.includes(value)) {
|
|
231
|
+
return {
|
|
232
|
+
valid: false,
|
|
233
|
+
error: `Invalid ${fieldName}: ${value}\nAllowed values: ${allowedValues.join(', ')}`,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
return { valid: true };
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Print validation error with formatting
|
|
240
|
+
* @param error - Error message to print
|
|
241
|
+
*/
|
|
242
|
+
function printValidationError(error) {
|
|
243
|
+
console.log(chalk_1.default.red('❌ Validation Error:'));
|
|
244
|
+
console.log(chalk_1.default.yellow(error));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Validate and throw if invalid
|
|
248
|
+
* @param result - Validation result
|
|
249
|
+
* @throws Error if validation fails
|
|
250
|
+
*/
|
|
251
|
+
function assertValid(result) {
|
|
252
|
+
if (!result.valid && result.error) {
|
|
253
|
+
printValidationError(result.error);
|
|
254
|
+
process.exit(1);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=validators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validators.js","sourceRoot":"","sources":["../../src/lib/validators.ts"],"names":[],"mappings":";;;;;AAeA,kCA0BC;AAUD,wCA8BC;AAUD,0CA8BC;AAOD,gDAWC;AAQD,oCAqBC;AAOD,oDAoBC;AAOD,oCAEC;AAOD,sCAEC;AASD,wDA6BC;AASD,oCAoBC;AAMD,oDAGC;AAOD,kCAKC;AA7SD,kDAA0B;AAU1B;;;;GAIG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,qBAAqB;SAC7B,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAE5B,2BAA2B;QAC3B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,qBAAqB,MAAM,CAAC,QAAQ,8DAA8D;aAC1G,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,mEAAmE,GAAG,EAAE;SAChF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,KAAU,EACV,GAAY,EACZ,GAAY,EACZ,YAAoB,OAAO;IAE3B,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAElE,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACf,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,sCAAsC,KAAK,EAAE;SACjE,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,qBAAqB,GAAG,eAAe,GAAG,EAAE;SAChE,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,oBAAoB,GAAG,eAAe,GAAG,EAAE;SAC/D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe,CAC7B,KAAU,EACV,GAAY,EACZ,GAAY,EACZ,YAAoB,OAAO;IAE3B,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEpE,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,uCAAuC,KAAK,EAAE;SAClE,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,qBAAqB,GAAG,eAAe,GAAG,EAAE;SAChE,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,oBAAoB,GAAG,eAAe,GAAG,EAAE;SAC/D,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,KAAU;IAC3C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAE/D,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,sEAAsE;SAC7F,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,YAAY,CAC1B,UAAkB,EAClB,YAAoB,MAAM;IAE1B,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,kBAAkB;SACtC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACtC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QAC9E,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,WAAW,SAAS,YAAY,YAAY,6BAA6B;SACjF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,MAAc;IACjD,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAE/C,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,+BAA+B;SACvC,CAAC;IACJ,CAAC;IAED,MAAM,gBAAgB,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC7C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,0BAA0B,MAAM,oBAAoB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACrF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAAC,IAAS;IACpC,OAAO,eAAe,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC;AAC5D,CAAC;AAED;;;;GAIG;AACH,SAAgB,aAAa,CAAC,KAAU;IACtC,OAAO,eAAe,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,sBAAsB,CACpC,KAAU,EACV,SAAiB,EACjB,YAAoB,CAAC;IAErB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,cAAc;SAClC,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAEjC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,kBAAkB;SACtC,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,qBAAqB,SAAS,0BAA0B,GAAG,CAAC,MAAM,aAAa;SACnG,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,YAAY,CAC1B,KAAU,EACV,aAAuB,EACvB,SAAiB;IAEjB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,GAAG,SAAS,iCAAiC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC/E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,WAAW,SAAS,KAAK,KAAK,qBAAqB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACrF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,SAAgB,oBAAoB,CAAC,KAAa;IAChD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,SAAgB,WAAW,CAAC,MAAwB;IAClD,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAClC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type * from '@memnexus-ai/mx-typescript-sdk';
|
|
2
|
+
export interface CLIConfig {
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
defaultFormat: 'json' | 'table' | 'yaml';
|
|
6
|
+
defaultPageSize: number;
|
|
7
|
+
}
|
|
8
|
+
export interface CommandOptions {
|
|
9
|
+
format?: 'json' | 'table' | 'yaml';
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export type OutputFormat = 'json' | 'table' | 'yaml';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,mBAAmB,gCAAgC,CAAC;AAGpD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACzC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":""}
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# MemNexus CLI Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the mx-cli documentation! This directory contains comprehensive planning and strategy documents for building and maintaining the CLI.
|
|
4
|
+
|
|
5
|
+
## Core Documents
|
|
6
|
+
|
|
7
|
+
### 📋 [Product Requirements Document (PRD)](./prd.md)
|
|
8
|
+
**Complete specification for the CLI project**
|
|
9
|
+
|
|
10
|
+
What's inside:
|
|
11
|
+
- Technology stack and dependencies
|
|
12
|
+
- Architecture and system design
|
|
13
|
+
- All CLI commands and features
|
|
14
|
+
- Development roadmap (4-week plan)
|
|
15
|
+
- Testing strategy
|
|
16
|
+
- Distribution via GitHub Packages
|
|
17
|
+
|
|
18
|
+
**Start here** if you want to understand what the CLI does and how it's built.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### 🔄 [CLI-API Sync Strategy](./sync-strategy.md)
|
|
23
|
+
**How to keep CLI in sync with API changes**
|
|
24
|
+
|
|
25
|
+
What's inside:
|
|
26
|
+
- OpenAPI as single source of truth
|
|
27
|
+
- Automated SDK generation workflow
|
|
28
|
+
- Contract testing with Dredd/Prism
|
|
29
|
+
- Version management (SemVer)
|
|
30
|
+
- CI/CD integration
|
|
31
|
+
- Breaking change detection
|
|
32
|
+
|
|
33
|
+
**Read this** to understand how type safety and API compatibility is maintained.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### 🤖 [Code Generation Strategy](./code-generation-strategy.md)
|
|
38
|
+
**How CLI commands are created when APIs change**
|
|
39
|
+
|
|
40
|
+
What's inside:
|
|
41
|
+
- Why full auto-generation doesn't work for CLIs
|
|
42
|
+
- Hybrid approach: scaffolding + manual implementation
|
|
43
|
+
- Coverage detection to catch missing commands
|
|
44
|
+
- Command scaffold generator (future)
|
|
45
|
+
- Metadata-driven commands via OpenAPI extensions
|
|
46
|
+
|
|
47
|
+
**Read this** to understand why CLI commands are manual in v1.0 and the roadmap for semi-automation.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Quick Reference
|
|
52
|
+
|
|
53
|
+
### The Three-Layer Architecture
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
┌─────────────────────────────────┐
|
|
57
|
+
│ OpenAPI Specification │ Single source of truth
|
|
58
|
+
└────────────┬────────────────────┘
|
|
59
|
+
│ generates
|
|
60
|
+
▼
|
|
61
|
+
┌─────────────────────────────────┐
|
|
62
|
+
│ @memnexus-ai/contracts │ TypeScript SDK
|
|
63
|
+
│ - Auto-generated types │ (Auto-sync)
|
|
64
|
+
│ - API client methods │
|
|
65
|
+
└────────────┬────────────────────┘
|
|
66
|
+
│ dependency
|
|
67
|
+
▼
|
|
68
|
+
┌─────────────────────────────────┐
|
|
69
|
+
│ @memnexus-ai/cli │ CLI tool
|
|
70
|
+
│ - Commands (manual) │ (Manual for v1.0)
|
|
71
|
+
│ - Business logic │
|
|
72
|
+
└─────────────────────────────────┘
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### What's Automated vs. Manual
|
|
76
|
+
|
|
77
|
+
| Aspect | Status | Tool/Process |
|
|
78
|
+
|--------|--------|-------------|
|
|
79
|
+
| **TypeScript types** | ✅ Automated | `openapi-typescript` |
|
|
80
|
+
| **API client methods** | ✅ Automated | `@memnexus-ai/contracts` build |
|
|
81
|
+
| **Breaking change detection** | ✅ Automated | `oasdiff` (future) |
|
|
82
|
+
| **Dependency updates** | ✅ Automated | Dependabot (future) |
|
|
83
|
+
| **Contract testing** | ✅ Automated | Dredd/Prism (future) |
|
|
84
|
+
| **CLI command structure** | ❌ Manual | Developer writes code |
|
|
85
|
+
| **Business logic** | ❌ Manual | Developer writes code |
|
|
86
|
+
| **Help text** | ❌ Manual | Developer writes code |
|
|
87
|
+
| **Output formatting** | ❌ Manual | Developer writes code |
|
|
88
|
+
|
|
89
|
+
### Key Decisions
|
|
90
|
+
|
|
91
|
+
1. **TypeScript + Node.js** - Leverage existing codebase and contracts package
|
|
92
|
+
2. **Via API Gateway** - All requests go through Kong (production/staging)
|
|
93
|
+
3. **Exact version pinning** - Pin `@memnexus-ai/contracts` version in v1.0 for stability
|
|
94
|
+
4. **Manual commands for v1.0** - Build scaffolding generator after patterns stabilize
|
|
95
|
+
5. **GitHub Packages** - Primary distribution method
|
|
96
|
+
|
|
97
|
+
### Development Workflow
|
|
98
|
+
|
|
99
|
+
**When an API endpoint is added/changed:**
|
|
100
|
+
|
|
101
|
+
```mermaid
|
|
102
|
+
graph LR
|
|
103
|
+
A[Change API] --> B[Update OpenAPI]
|
|
104
|
+
B --> C[Publish contracts]
|
|
105
|
+
C --> D[Update CLI dependency]
|
|
106
|
+
D --> E[Implement command]
|
|
107
|
+
E --> F[Test & publish CLI]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Detailed steps**:
|
|
111
|
+
1. Developer changes mx-core-api code
|
|
112
|
+
2. Developer updates OpenAPI spec (`contracts/openapi.yaml`)
|
|
113
|
+
3. Contracts package auto-generates types and publishes
|
|
114
|
+
4. CLI updates `@memnexus-ai/contracts` dependency
|
|
115
|
+
5. **Developer manually implements CLI command** (for v1.0)
|
|
116
|
+
6. CLI is tested and published via GitHub Actions
|
|
117
|
+
|
|
118
|
+
### Phased Automation Plan
|
|
119
|
+
|
|
120
|
+
#### Phase 1: Manual (Weeks 1-4) ✅ Current
|
|
121
|
+
- Use contracts for types
|
|
122
|
+
- Write commands manually
|
|
123
|
+
- Establish patterns
|
|
124
|
+
|
|
125
|
+
#### Phase 2: Detection (Weeks 5-6) 🎯 Next
|
|
126
|
+
- Build coverage checker
|
|
127
|
+
- Alert on missing commands
|
|
128
|
+
- CI/CD integration
|
|
129
|
+
|
|
130
|
+
#### Phase 3: Scaffolding (Month 2) ⏸️ Future
|
|
131
|
+
- Build command generator
|
|
132
|
+
- Auto-create skeletons
|
|
133
|
+
- Developer fills in logic
|
|
134
|
+
|
|
135
|
+
#### Phase 4: Metadata-Driven (Month 3+) ⏸️ Future
|
|
136
|
+
- OpenAPI extensions for CLI
|
|
137
|
+
- Auto-generate help text
|
|
138
|
+
- Near-automatic updates
|
|
139
|
+
|
|
140
|
+
## Common Questions
|
|
141
|
+
|
|
142
|
+
### Q: Do types update automatically when the API changes?
|
|
143
|
+
**A**: Yes! When `@memnexus-ai/contracts` is updated, you get new TypeScript types automatically.
|
|
144
|
+
|
|
145
|
+
### Q: Do CLI commands update automatically?
|
|
146
|
+
**A**: No (for v1.0). Developers must manually implement new commands. However:
|
|
147
|
+
- Coverage detection will alert when commands are missing (Phase 2)
|
|
148
|
+
- Scaffolding generator will create boilerplate (Phase 3)
|
|
149
|
+
- Metadata-driven approach will minimize manual work (Phase 4)
|
|
150
|
+
|
|
151
|
+
### Q: Why not fully auto-generate CLI commands?
|
|
152
|
+
**A**:
|
|
153
|
+
- No mature tools for TypeScript/Commander.js generation
|
|
154
|
+
- Generated code loses flexibility and polish
|
|
155
|
+
- Help text, examples, and UX require human touch
|
|
156
|
+
- Business logic is unique per endpoint
|
|
157
|
+
|
|
158
|
+
See [Code Generation Strategy](./code-generation-strategy.md#evaluated-solutions) for detailed analysis.
|
|
159
|
+
|
|
160
|
+
### Q: How do I know if the CLI is out of sync with the API?
|
|
161
|
+
**A**:
|
|
162
|
+
- **v1.0**: Manual tracking
|
|
163
|
+
- **Phase 2+**: Automated coverage checks in CI/CD
|
|
164
|
+
- **Future**: GitHub bot creates PRs when endpoints are added
|
|
165
|
+
|
|
166
|
+
### Q: What happens when there's a breaking API change?
|
|
167
|
+
**A**:
|
|
168
|
+
1. `oasdiff` detects breaking change in CI/CD
|
|
169
|
+
2. Contracts package bumps MAJOR version (e.g., 1.0.0 → 2.0.0)
|
|
170
|
+
3. CLI must update code to handle new contract
|
|
171
|
+
4. CLI bumps MAJOR version too
|
|
172
|
+
5. Migration guide documents changes
|
|
173
|
+
|
|
174
|
+
See [Sync Strategy - Breaking Changes](./sync-strategy.md#detecting-breaking-changes).
|
|
175
|
+
|
|
176
|
+
### Q: Can I point the CLI directly at mx-core-api instead of the gateway?
|
|
177
|
+
**A**: Yes! For local development:
|
|
178
|
+
```bash
|
|
179
|
+
export MX_API_URL=http://localhost:3000
|
|
180
|
+
mx memories list
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Default is API Gateway (`https://api.memnexus.io` in production).
|
|
184
|
+
|
|
185
|
+
## Next Steps
|
|
186
|
+
|
|
187
|
+
### For Contributors
|
|
188
|
+
1. Read [PRD](./prd.md) to understand the project
|
|
189
|
+
2. Check [Development Plan](./prd.md#development-plan) for current priorities
|
|
190
|
+
3. See [Sync Strategy](./sync-strategy.md) for workflow details
|
|
191
|
+
|
|
192
|
+
### For Maintainers
|
|
193
|
+
1. Implement Phase 2 coverage detection after v1.0
|
|
194
|
+
2. Monitor contracts package updates
|
|
195
|
+
3. Keep documentation in sync with implementation
|
|
196
|
+
|
|
197
|
+
### For Users
|
|
198
|
+
- Installation and usage docs will be in `../README.md` (root of mx-cli)
|
|
199
|
+
- API reference will be in `../docs/api-reference.md` (future)
|
|
200
|
+
- Examples will be in `../examples/` (future)
|
|
201
|
+
|
|
202
|
+
## Document Status
|
|
203
|
+
|
|
204
|
+
| Document | Version | Last Updated | Status |
|
|
205
|
+
|----------|---------|--------------|--------|
|
|
206
|
+
| [prd.md](./prd.md) | 1.0 | 2025-11-13 | ✅ Complete |
|
|
207
|
+
| [sync-strategy.md](./sync-strategy.md) | 1.0 | 2025-11-13 | ✅ Complete |
|
|
208
|
+
| [code-generation-strategy.md](./code-generation-strategy.md) | 1.0 | 2025-11-13 | ✅ Complete |
|
|
209
|
+
|
|
210
|
+
## Contributing
|
|
211
|
+
|
|
212
|
+
Found an issue or have a suggestion? Please:
|
|
213
|
+
1. Open an issue in the GitHub repository
|
|
214
|
+
2. Reference the relevant document
|
|
215
|
+
3. Propose specific changes
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
**Questions?** Open an issue or reach out to the MemNexus team.
|