@memnexus-ai/cli 1.7.219 → 1.7.221
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/dist/commands/memories.d.ts.map +1 -1
- package/dist/commands/memories.js +185 -90
- package/dist/commands/memories.js.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/errors.d.ts +47 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +137 -48
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/spinner.d.ts +32 -2
- package/dist/lib/spinner.d.ts.map +1 -1
- package/dist/lib/spinner.js +40 -2
- package/dist/lib/spinner.js.map +1 -1
- package/hooks/capture-hooks.test.sh +465 -0
- package/hooks/capture-precompact.sh +11 -1
- package/hooks/capture-session-end.sh +101 -7
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ const mcp_1 = require("./commands/mcp");
|
|
|
69
69
|
const hook_1 = require("./commands/hook");
|
|
70
70
|
const commit_context_1 = require("./commands/commit-context");
|
|
71
71
|
const agent_help_1 = require("./lib/agent-help");
|
|
72
|
+
const errors_1 = require("./lib/errors");
|
|
72
73
|
// Check for updates (respects config)
|
|
73
74
|
const notifier = (0, update_notifier_1.default)({
|
|
74
75
|
pkg: package_json_1.default,
|
|
@@ -126,6 +127,18 @@ program
|
|
|
126
127
|
const fmt = opts.format === 'json' ? 'json' : 'markdown';
|
|
127
128
|
console.log((0, agent_help_1.getAgentHelp)(scope || null, fmt));
|
|
128
129
|
});
|
|
130
|
+
// Central failure funnel (v4.04 error honesty). Commander action handlers are
|
|
131
|
+
// async: a rejection that escapes an action's try/catch — or a throw from a
|
|
132
|
+
// callback outside one — used to unwind past program.parse() and leave the
|
|
133
|
+
// process to exit 0 with nothing on stdout, which is byte-identical to "no
|
|
134
|
+
// results". Route both through handleError so every escape is stderr + a
|
|
135
|
+
// non-zero exit code.
|
|
136
|
+
process.on('unhandledRejection', (reason) => {
|
|
137
|
+
(0, errors_1.handleError)(reason);
|
|
138
|
+
});
|
|
139
|
+
process.on('uncaughtException', (error) => {
|
|
140
|
+
(0, errors_1.handleError)(error);
|
|
141
|
+
});
|
|
129
142
|
program.parse(process.argv);
|
|
130
143
|
// Show help if no command provided
|
|
131
144
|
if (!process.argv.slice(2).length) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AACA;;;;;;;;;;;;;;;;;GAiBG;AACH,yCAAsC;AACtC,mEAA0C;AAC1C,oEAAoF;AAEpF,qFAAqF;AACrF,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;AACvC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAkC,EAAE,IAAkC,EAAE,EAAE;IAC5F,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,eAAM,CAAC,aAAa,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC;QAChE,MAAM,UAAU,GAAG;YACjB,UAAU,sBAAW,CAAC,OAAO,EAAE;YAC/B,MAAM,OAAO,CAAC,QAAQ,EAAE;YACxB,QAAQ,OAAO,CAAC,OAAO,EAAE;YACzB,SAAS,KAAK,EAAE;SACjB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC;IACD,6EAA6E;IAC7E,8CAA8C;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAA,8CAA+B,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QAC1F,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,yCAAoC;AACpC,sEAA6C;AAC7C,0CAAuD;AACvD,8CAA2D;AAC3D,kDAA+D;AAC/D,4DAAyE;AACzE,4CAAyD;AACzD,8CAA2D;AAC3D,kDAA+D;AAE/D,kDAA+D;AAC/D,kDAA+D;AAC/D,oDAAiE;AACjE,gDAA4D;AAC5D,8CAA2D;AAC3D,8CAA2D;AAC3D,sDAAmE;AACnE,4CAAyD;AACzD,wCAAqD;AACrD,0CAAuD;AACvD,8DAA0E;AAC1E,iDAAgD;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -3,5 +3,52 @@ export declare class CLIError extends Error {
|
|
|
3
3
|
details?: unknown | undefined;
|
|
4
4
|
constructor(message: string, exitCode?: number, details?: unknown | undefined);
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Exit-code vocabulary (shared with handleApiError below — do not add codes
|
|
8
|
+
* outside this map):
|
|
9
|
+
* 1 — generic failure / not found
|
|
10
|
+
* 2 — validation: bad or missing user input
|
|
11
|
+
* 3 — auth (401/403)
|
|
12
|
+
* 4 — network: could not reach the API
|
|
13
|
+
* 5 — server / infrastructure: 5xx, rate limit, unusable response body
|
|
14
|
+
*
|
|
15
|
+
* Error output is stderr-only. Fleet scripts treat non-empty stdout as "this
|
|
16
|
+
* command produced a result" and parse the first `{` on stdout as the result
|
|
17
|
+
* body, so a failure that writes to stdout is indistinguishable from a success
|
|
18
|
+
* (v4.04 error-honesty invariant).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* The request succeeded at the transport layer (2xx) but the response body is
|
|
22
|
+
* absent or unusable, so there is no data to render. This is an
|
|
23
|
+
* infrastructure-class failure, NOT an empty result: rendering it as "found 0"
|
|
24
|
+
* or "generated from 0 memories" tells the caller the store is empty when in
|
|
25
|
+
* fact the retrieval never happened.
|
|
26
|
+
*
|
|
27
|
+
* @param operation - Human-readable operation name, e.g. "Memory search"
|
|
28
|
+
* @param details - Optional debug payload (printed only under DEBUG)
|
|
29
|
+
*/
|
|
30
|
+
export declare function unusableResponseError(operation: string, details?: unknown): CLIError;
|
|
31
|
+
/**
|
|
32
|
+
* Invalid or missing user input. Exit 2, matching the API's 422 handling.
|
|
33
|
+
*/
|
|
34
|
+
export declare function validationError(message: string, details?: unknown): CLIError;
|
|
35
|
+
/**
|
|
36
|
+
* True only for a genuine "the resource does not exist" failure (HTTP 404).
|
|
37
|
+
* Anything else — 5xx, network, parse — is an error the caller must surface,
|
|
38
|
+
* not an empty result. Status lives on `status` (SDK), `statusCode`, or
|
|
39
|
+
* `response.status` (axios) depending on the client that threw.
|
|
40
|
+
*/
|
|
41
|
+
export declare function isNotFoundError(error: unknown): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Neutralize a server-supplied string before echoing it to the terminal.
|
|
44
|
+
*
|
|
45
|
+
* The API's error text is attacker-influenceable (it can quote user content,
|
|
46
|
+
* and a hostile or misconfigured apiUrl controls it outright). Printed raw it
|
|
47
|
+
* can carry ANSI escapes that rewrite the terminal, and — because agents read
|
|
48
|
+
* CLI stderr — instructions aimed at the agent. Strip C0/C1 control characters
|
|
49
|
+
* (which is what ANSI escapes are built from), collapse newlines, and bound the
|
|
50
|
+
* length.
|
|
51
|
+
*/
|
|
52
|
+
export declare function sanitizeServerText(value: unknown, maxLength?: number): string;
|
|
6
53
|
export declare function handleError(error: unknown): never;
|
|
7
54
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/lib/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAS,SAAQ,KAAK;IAGxB,QAAQ,EAAE,MAAM;IAChB,OAAO,CAAC,EAAE,OAAO;gBAFxB,OAAO,EAAE,MAAM,EACR,QAAQ,GAAE,MAAU,EACpB,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAUD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAS,SAAQ,KAAK;IAGxB,QAAQ,EAAE,MAAM;IAChB,OAAO,CAAC,EAAE,OAAO;gBAFxB,OAAO,EAAE,MAAM,EACR,QAAQ,GAAE,MAAU,EACpB,OAAO,CAAC,EAAE,OAAO,YAAA;CAK3B;AAED;;;;;;;;;;;;;GAaG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAQpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,CAE5E;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAIvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAM,GAAG,MAAM,CAkB1E;AAUD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CA6CjD"}
|
package/dist/lib/errors.js
CHANGED
|
@@ -4,6 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.CLIError = void 0;
|
|
7
|
+
exports.unusableResponseError = unusableResponseError;
|
|
8
|
+
exports.validationError = validationError;
|
|
9
|
+
exports.isNotFoundError = isNotFoundError;
|
|
10
|
+
exports.sanitizeServerText = sanitizeServerText;
|
|
7
11
|
exports.handleError = handleError;
|
|
8
12
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
13
|
class CLIError extends Error {
|
|
@@ -17,12 +21,92 @@ class CLIError extends Error {
|
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
exports.CLIError = CLIError;
|
|
24
|
+
/**
|
|
25
|
+
* Exit-code vocabulary (shared with handleApiError below — do not add codes
|
|
26
|
+
* outside this map):
|
|
27
|
+
* 1 — generic failure / not found
|
|
28
|
+
* 2 — validation: bad or missing user input
|
|
29
|
+
* 3 — auth (401/403)
|
|
30
|
+
* 4 — network: could not reach the API
|
|
31
|
+
* 5 — server / infrastructure: 5xx, rate limit, unusable response body
|
|
32
|
+
*
|
|
33
|
+
* Error output is stderr-only. Fleet scripts treat non-empty stdout as "this
|
|
34
|
+
* command produced a result" and parse the first `{` on stdout as the result
|
|
35
|
+
* body, so a failure that writes to stdout is indistinguishable from a success
|
|
36
|
+
* (v4.04 error-honesty invariant).
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* The request succeeded at the transport layer (2xx) but the response body is
|
|
40
|
+
* absent or unusable, so there is no data to render. This is an
|
|
41
|
+
* infrastructure-class failure, NOT an empty result: rendering it as "found 0"
|
|
42
|
+
* or "generated from 0 memories" tells the caller the store is empty when in
|
|
43
|
+
* fact the retrieval never happened.
|
|
44
|
+
*
|
|
45
|
+
* @param operation - Human-readable operation name, e.g. "Memory search"
|
|
46
|
+
* @param details - Optional debug payload (printed only under DEBUG)
|
|
47
|
+
*/
|
|
48
|
+
function unusableResponseError(operation, details) {
|
|
49
|
+
return new CLIError(`${operation} returned a successful status but the response body was missing or unusable. ` +
|
|
50
|
+
'No data was retrieved — this is a server-side failure, not an empty result. ' +
|
|
51
|
+
'Retry, and check API status with: mx system health', 5, details);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Invalid or missing user input. Exit 2, matching the API's 422 handling.
|
|
55
|
+
*/
|
|
56
|
+
function validationError(message, details) {
|
|
57
|
+
return new CLIError(message, 2, details);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* True only for a genuine "the resource does not exist" failure (HTTP 404).
|
|
61
|
+
* Anything else — 5xx, network, parse — is an error the caller must surface,
|
|
62
|
+
* not an empty result. Status lives on `status` (SDK), `statusCode`, or
|
|
63
|
+
* `response.status` (axios) depending on the client that threw.
|
|
64
|
+
*/
|
|
65
|
+
function isNotFoundError(error) {
|
|
66
|
+
const e = error;
|
|
67
|
+
const status = e?.status ?? e?.statusCode ?? e?.response?.status;
|
|
68
|
+
return status === 404;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Neutralize a server-supplied string before echoing it to the terminal.
|
|
72
|
+
*
|
|
73
|
+
* The API's error text is attacker-influenceable (it can quote user content,
|
|
74
|
+
* and a hostile or misconfigured apiUrl controls it outright). Printed raw it
|
|
75
|
+
* can carry ANSI escapes that rewrite the terminal, and — because agents read
|
|
76
|
+
* CLI stderr — instructions aimed at the agent. Strip C0/C1 control characters
|
|
77
|
+
* (which is what ANSI escapes are built from), collapse newlines, and bound the
|
|
78
|
+
* length.
|
|
79
|
+
*/
|
|
80
|
+
function sanitizeServerText(value, maxLength = 500) {
|
|
81
|
+
if (typeof value !== 'string')
|
|
82
|
+
return '';
|
|
83
|
+
return (value
|
|
84
|
+
// Full CSI sequences first (ESC [ ... final byte). Stripping the ESC byte
|
|
85
|
+
// alone would leave the literal "[31m" / "[0m" residue in the output.
|
|
86
|
+
// eslint-disable-next-line no-control-regex
|
|
87
|
+
.replace(/\u001B\[[0-9;?]*[ -/]*[@-~]/g, '')
|
|
88
|
+
// OSC sequences (ESC ] ... BEL or ST) — these can set the window title.
|
|
89
|
+
// eslint-disable-next-line no-control-regex
|
|
90
|
+
.replace(/\u001B\][^\u0007\u001B]*(?:\u0007|\u001B\\)?/g, '')
|
|
91
|
+
// Anything else in the C0/C1 control ranges, including a bare ESC.
|
|
92
|
+
// eslint-disable-next-line no-control-regex
|
|
93
|
+
.replace(/[\u0000-\u001F\u007F-\u009F]/g, ' ')
|
|
94
|
+
.replace(/\s+/g, ' ')
|
|
95
|
+
.trim()
|
|
96
|
+
.slice(0, maxLength));
|
|
97
|
+
}
|
|
20
98
|
function printSupportFooter() {
|
|
21
|
-
console.
|
|
99
|
+
console.error(chalk_1.default.dim('\n📬 Need help? https://discord.gg/memnexus · https://github.com/memnexus-ai/support/issues'));
|
|
22
100
|
}
|
|
23
101
|
function handleError(error) {
|
|
24
|
-
// Handle SDK errors (from generated SDK with throwOnError: true)
|
|
25
|
-
|
|
102
|
+
// Handle SDK errors (from generated SDK with throwOnError: true).
|
|
103
|
+
// The status must be a NUMBER: plenty of objects carry a string `status`
|
|
104
|
+
// (e.g. { status: 'pending' }) and classifying those as HTTP errors sent
|
|
105
|
+
// them down handleApiError's default branch with a meaningless code.
|
|
106
|
+
if (error &&
|
|
107
|
+
typeof error === 'object' &&
|
|
108
|
+
'status' in error &&
|
|
109
|
+
typeof error.status === 'number') {
|
|
26
110
|
const sdkError = error;
|
|
27
111
|
handleApiError({
|
|
28
112
|
isAxiosError: true,
|
|
@@ -74,11 +158,11 @@ function getStatusText(status) {
|
|
|
74
158
|
function handleApiError(error) {
|
|
75
159
|
if (!error.response) {
|
|
76
160
|
console.error(chalk_1.default.red('❌ Network Error: Unable to connect to API'));
|
|
77
|
-
console.
|
|
78
|
-
console.
|
|
79
|
-
console.
|
|
80
|
-
console.
|
|
81
|
-
console.
|
|
161
|
+
console.error(chalk_1.default.yellow('\n💡 Troubleshooting steps:'));
|
|
162
|
+
console.error(chalk_1.default.yellow(' 1. Check your internet connection'));
|
|
163
|
+
console.error(chalk_1.default.yellow(' 2. Verify API URL: mx config get apiUrl'));
|
|
164
|
+
console.error(chalk_1.default.yellow(' 3. Test API connectivity: curl <api-url>/health'));
|
|
165
|
+
console.error(chalk_1.default.yellow(' 4. Update API URL if needed: mx config set apiUrl <url>'));
|
|
82
166
|
printSupportFooter();
|
|
83
167
|
process.exit(4);
|
|
84
168
|
}
|
|
@@ -89,28 +173,28 @@ function handleApiError(error) {
|
|
|
89
173
|
switch (status) {
|
|
90
174
|
case 401:
|
|
91
175
|
console.error(chalk_1.default.red('❌ Authentication Error: Invalid or missing API key'));
|
|
92
|
-
console.
|
|
93
|
-
console.
|
|
94
|
-
console.
|
|
95
|
-
console.
|
|
176
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
177
|
+
console.error(chalk_1.default.yellow(' 1. Check auth status: mx auth status'));
|
|
178
|
+
console.error(chalk_1.default.yellow(' 2. Login with your API key: mx auth login --api-key <your-key>'));
|
|
179
|
+
console.error(chalk_1.default.yellow(' 3. Or use interactive mode: mx auth login --interactive'));
|
|
96
180
|
printSupportFooter();
|
|
97
181
|
process.exit(3);
|
|
98
182
|
// eslint-disable-next-line no-fallthrough
|
|
99
183
|
case 403:
|
|
100
184
|
console.error(chalk_1.default.red('❌ Authorization Error: Insufficient permissions'));
|
|
101
|
-
console.
|
|
102
|
-
console.
|
|
103
|
-
console.
|
|
104
|
-
console.
|
|
185
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
186
|
+
console.error(chalk_1.default.yellow(' 1. Verify your API key has the required permissions'));
|
|
187
|
+
console.error(chalk_1.default.yellow(' 2. Contact your administrator if you need additional access'));
|
|
188
|
+
console.error(chalk_1.default.yellow(' 3. Check your current auth status: mx auth status'));
|
|
105
189
|
printSupportFooter();
|
|
106
190
|
process.exit(3);
|
|
107
191
|
// eslint-disable-next-line no-fallthrough
|
|
108
192
|
case 404:
|
|
109
193
|
console.error(chalk_1.default.red('❌ Not Found: Resource does not exist'));
|
|
110
|
-
console.
|
|
111
|
-
console.
|
|
112
|
-
console.
|
|
113
|
-
console.
|
|
194
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
195
|
+
console.error(chalk_1.default.yellow(' 1. Verify the resource ID is correct'));
|
|
196
|
+
console.error(chalk_1.default.yellow(' 2. List available resources to find the correct ID'));
|
|
197
|
+
console.error(chalk_1.default.yellow(' 3. Check if the resource was deleted'));
|
|
114
198
|
printSupportFooter();
|
|
115
199
|
process.exit(1);
|
|
116
200
|
// eslint-disable-next-line no-fallthrough
|
|
@@ -121,12 +205,12 @@ function handleApiError(error) {
|
|
|
121
205
|
// responses used `message`. Without this the user only saw the generic
|
|
122
206
|
// "Invalid input" line and lost the reason (v3.84 D4).
|
|
123
207
|
if (data.error || data.message) {
|
|
124
|
-
console.error(chalk_1.default.yellow(`\n${data.error || data.message}`));
|
|
208
|
+
console.error(chalk_1.default.yellow(`\n${sanitizeServerText(data.error || data.message)}`));
|
|
125
209
|
}
|
|
126
|
-
console.
|
|
127
|
-
console.
|
|
128
|
-
console.
|
|
129
|
-
console.
|
|
210
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
211
|
+
console.error(chalk_1.default.yellow(' 1. Check the command syntax: mx <command> --help'));
|
|
212
|
+
console.error(chalk_1.default.yellow(' 2. Verify all required fields are provided'));
|
|
213
|
+
console.error(chalk_1.default.yellow(' 3. Use --interactive mode for guided input'));
|
|
130
214
|
printSupportFooter();
|
|
131
215
|
process.exit(2);
|
|
132
216
|
// eslint-disable-next-line no-fallthrough
|
|
@@ -138,52 +222,57 @@ function handleApiError(error) {
|
|
|
138
222
|
// (deleteRateLimit) also benefit. The API returns the reason on `error`;
|
|
139
223
|
// some responses use `message`.
|
|
140
224
|
if (data.error || data.message) {
|
|
141
|
-
console.error(chalk_1.default.yellow(`\n${data.error || data.message}`));
|
|
225
|
+
console.error(chalk_1.default.yellow(`\n${sanitizeServerText(data.error || data.message)}`));
|
|
142
226
|
}
|
|
143
227
|
if (data.code) {
|
|
144
|
-
console.error(chalk_1.default.gray(`Code: ${data.code}`));
|
|
228
|
+
console.error(chalk_1.default.gray(`Code: ${sanitizeServerText(data.code, 64)}`));
|
|
145
229
|
}
|
|
146
230
|
// Honor the server's Retry-After hint when present (seconds).
|
|
147
|
-
|
|
148
|
-
|
|
231
|
+
// `retryAfter` is typed as a number but arrives off the wire unvalidated:
|
|
232
|
+
// a string (or NaN/Infinity) would be interpolated verbatim into the
|
|
233
|
+
// line below. Print the hint only when it really is a finite number.
|
|
234
|
+
if (Number.isFinite(data.retryAfter)) {
|
|
235
|
+
console.error(chalk_1.default.yellow(`\n⏱ Retry after ${data.retryAfter}s.`));
|
|
149
236
|
}
|
|
150
|
-
console.
|
|
151
|
-
console.
|
|
152
|
-
console.
|
|
153
|
-
console.
|
|
237
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
238
|
+
console.error(chalk_1.default.yellow(' 1. Wait a few moments before retrying'));
|
|
239
|
+
console.error(chalk_1.default.yellow(' 2. Reduce the frequency of your requests'));
|
|
240
|
+
console.error(chalk_1.default.yellow(' 3. Contact support if you need a higher rate limit'));
|
|
154
241
|
printSupportFooter();
|
|
155
242
|
process.exit(5);
|
|
156
243
|
// eslint-disable-next-line no-fallthrough
|
|
157
244
|
case 500:
|
|
158
245
|
console.error(chalk_1.default.red('❌ Server Error: Internal server error'));
|
|
159
|
-
console.
|
|
160
|
-
console.
|
|
161
|
-
console.
|
|
162
|
-
console.
|
|
246
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
247
|
+
console.error(chalk_1.default.yellow(' 1. Try again in a few moments'));
|
|
248
|
+
console.error(chalk_1.default.yellow(' 2. Check API status: mx system health'));
|
|
249
|
+
console.error(chalk_1.default.yellow(' 3. Contact support if the issue persists'));
|
|
163
250
|
if (data.error || data.message) {
|
|
164
|
-
console.error(chalk_1.default.gray(`\nDetails: ${data.error || data.message}`));
|
|
251
|
+
console.error(chalk_1.default.gray(`\nDetails: ${sanitizeServerText(data.error || data.message)}`));
|
|
165
252
|
}
|
|
166
253
|
printSupportFooter();
|
|
167
254
|
process.exit(5);
|
|
168
255
|
// eslint-disable-next-line no-fallthrough
|
|
169
256
|
case 503:
|
|
170
257
|
console.error(chalk_1.default.red('❌ Service Unavailable: API is temporarily unavailable'));
|
|
171
|
-
console.
|
|
172
|
-
console.
|
|
173
|
-
console.
|
|
174
|
-
console.
|
|
258
|
+
console.error(chalk_1.default.yellow('\n💡 To fix this:'));
|
|
259
|
+
console.error(chalk_1.default.yellow(' 1. The service may be undergoing maintenance'));
|
|
260
|
+
console.error(chalk_1.default.yellow(' 2. Try again in a few minutes'));
|
|
261
|
+
console.error(chalk_1.default.yellow(' 3. Check API status: mx system health'));
|
|
175
262
|
printSupportFooter();
|
|
176
263
|
process.exit(5);
|
|
177
264
|
// eslint-disable-next-line no-fallthrough
|
|
178
265
|
default:
|
|
179
|
-
|
|
266
|
+
// statusText comes straight off the wire — sanitize like every other
|
|
267
|
+
// server-supplied string before it reaches the terminal.
|
|
268
|
+
console.error(chalk_1.default.red(`❌ API Error: ${status} ${sanitizeServerText(error.response.statusText, 64)}`));
|
|
180
269
|
if (data.error || data.message) {
|
|
181
|
-
console.error(chalk_1.default.yellow(`\n${data.error || data.message}`));
|
|
270
|
+
console.error(chalk_1.default.yellow(`\n${sanitizeServerText(data.error || data.message)}`));
|
|
182
271
|
}
|
|
183
|
-
console.
|
|
184
|
-
console.
|
|
185
|
-
console.
|
|
186
|
-
console.
|
|
272
|
+
console.error(chalk_1.default.yellow('\n💡 For help:'));
|
|
273
|
+
console.error(chalk_1.default.yellow(' 1. Run with DEBUG=1 for more details'));
|
|
274
|
+
console.error(chalk_1.default.yellow(' 2. Check command syntax: mx <command> --help'));
|
|
275
|
+
console.error(chalk_1.default.yellow(' 3. Contact support if the issue persists'));
|
|
187
276
|
printSupportFooter();
|
|
188
277
|
process.exit(5);
|
|
189
278
|
}
|
package/dist/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/spinner.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { OutputFormat } from '../types';
|
|
2
|
+
export interface SpinnerFailOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Process exit code to set. Defaults to 1. Pass `null` to leave
|
|
5
|
+
* `process.exitCode` untouched (the command is expected to exit 0 anyway).
|
|
6
|
+
*/
|
|
7
|
+
exitCode?: number | null;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
* Conditional spinner that only shows when output format is not JSON
|
|
4
11
|
* This prevents spinners from interfering with JSON output that may be piped to other tools
|
|
@@ -16,9 +23,32 @@ export declare class ConditionalSpinner {
|
|
|
16
23
|
*/
|
|
17
24
|
succeed(text?: string): this;
|
|
18
25
|
/**
|
|
19
|
-
* Stop the spinner and
|
|
26
|
+
* Stop the spinner and report a failure.
|
|
27
|
+
*
|
|
28
|
+
* The failure text always goes to STDERR — including in `--format json`
|
|
29
|
+
* mode, where the spinner itself is disabled and this used to be a complete
|
|
30
|
+
* no-op (the command then exited 0 with empty stdout, indistinguishable from
|
|
31
|
+
* an empty result). It also always sets `process.exitCode` (default 1), which
|
|
32
|
+
* ora never did, so the failure is visible to callers that only check the
|
|
33
|
+
* exit status.
|
|
34
|
+
*
|
|
35
|
+
* We stop the spinner and write the line ourselves rather than calling ora's
|
|
36
|
+
* fail(): ora writes to stderr too, but only when the spinner is enabled, so
|
|
37
|
+
* routing through it would keep json mode silent. Writing directly makes both
|
|
38
|
+
* modes behave identically.
|
|
39
|
+
*
|
|
40
|
+
* For failures the command deliberately continues past — a genuine not-found
|
|
41
|
+
* banner, a per-item warning in a batch — use `softFail()` instead.
|
|
42
|
+
*/
|
|
43
|
+
fail(text?: string, opts?: SpinnerFailOptions): this;
|
|
44
|
+
/**
|
|
45
|
+
* Stop the spinner and show ora's failure banner without setting an exit
|
|
46
|
+
* code — the legacy `fail()` behaviour, byte for byte. Reserved for outcomes
|
|
47
|
+
* that are NOT errors: a genuine not-found lookup, or a per-item warning in a
|
|
48
|
+
* batch that intentionally continues. Anything that means "the operation did
|
|
49
|
+
* not happen" must use `fail()`.
|
|
20
50
|
*/
|
|
21
|
-
|
|
51
|
+
softFail(text?: string): this;
|
|
22
52
|
/**
|
|
23
53
|
* Stop the spinner and show warning message
|
|
24
54
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,OAAO,CAAU;gBAEb,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM;IASxD;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAO5B;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,kBAAkB,GAAG,IAAI;IAgBpD;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAO7B;;OAEG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAIrB;IAED;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;CACF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,kBAAkB,CAE9F"}
|
package/dist/lib/spinner.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.ConditionalSpinner = void 0;
|
|
7
7
|
exports.createSpinner = createSpinner;
|
|
8
8
|
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
10
|
/**
|
|
10
11
|
* Conditional spinner that only shows when output format is not JSON
|
|
11
12
|
* This prevents spinners from interfering with JSON output that may be piped to other tools
|
|
@@ -39,9 +40,46 @@ class ConditionalSpinner {
|
|
|
39
40
|
return this;
|
|
40
41
|
}
|
|
41
42
|
/**
|
|
42
|
-
* Stop the spinner and
|
|
43
|
+
* Stop the spinner and report a failure.
|
|
44
|
+
*
|
|
45
|
+
* The failure text always goes to STDERR — including in `--format json`
|
|
46
|
+
* mode, where the spinner itself is disabled and this used to be a complete
|
|
47
|
+
* no-op (the command then exited 0 with empty stdout, indistinguishable from
|
|
48
|
+
* an empty result). It also always sets `process.exitCode` (default 1), which
|
|
49
|
+
* ora never did, so the failure is visible to callers that only check the
|
|
50
|
+
* exit status.
|
|
51
|
+
*
|
|
52
|
+
* We stop the spinner and write the line ourselves rather than calling ora's
|
|
53
|
+
* fail(): ora writes to stderr too, but only when the spinner is enabled, so
|
|
54
|
+
* routing through it would keep json mode silent. Writing directly makes both
|
|
55
|
+
* modes behave identically.
|
|
56
|
+
*
|
|
57
|
+
* For failures the command deliberately continues past — a genuine not-found
|
|
58
|
+
* banner, a per-item warning in a batch — use `softFail()` instead.
|
|
43
59
|
*/
|
|
44
|
-
fail(text) {
|
|
60
|
+
fail(text, opts) {
|
|
61
|
+
// Stop rather than ora.fail() so exactly one failure line is emitted,
|
|
62
|
+
// from here, in json and non-json mode alike.
|
|
63
|
+
if (this.enabled && this.spinner) {
|
|
64
|
+
this.spinner.stop();
|
|
65
|
+
}
|
|
66
|
+
if (text) {
|
|
67
|
+
console.error(chalk_1.default.red(`✖ ${text}`));
|
|
68
|
+
}
|
|
69
|
+
const code = opts && 'exitCode' in opts ? opts.exitCode : 1;
|
|
70
|
+
if (code !== null && code !== undefined) {
|
|
71
|
+
process.exitCode = code;
|
|
72
|
+
}
|
|
73
|
+
return this;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Stop the spinner and show ora's failure banner without setting an exit
|
|
77
|
+
* code — the legacy `fail()` behaviour, byte for byte. Reserved for outcomes
|
|
78
|
+
* that are NOT errors: a genuine not-found lookup, or a per-item warning in a
|
|
79
|
+
* batch that intentionally continues. Anything that means "the operation did
|
|
80
|
+
* not happen" must use `fail()`.
|
|
81
|
+
*/
|
|
82
|
+
softFail(text) {
|
|
45
83
|
if (this.enabled && this.spinner) {
|
|
46
84
|
this.spinner.fail(text);
|
|
47
85
|
}
|
package/dist/lib/spinner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"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"}
|