@orchagent/cli 0.3.8 → 0.3.11
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/call.js +42 -0
- package/dist/commands/env.js +7 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/install.js +7 -7
- package/dist/commands/list.js +28 -0
- package/dist/commands/publish.js +15 -1
- package/dist/commands/run.js +5 -0
- package/dist/commands/skill.js +7 -8
- package/dist/lib/bundle.js +4 -1
- package/dist/lib/config.js +1 -2
- package/dist/lib/errors.js +22 -0
- package/package.json +1 -1
package/dist/commands/call.js
CHANGED
|
@@ -13,6 +13,41 @@ const output_1 = require("../lib/output");
|
|
|
13
13
|
const llm_1 = require("../lib/llm");
|
|
14
14
|
const analytics_1 = require("../lib/analytics");
|
|
15
15
|
const DEFAULT_VERSION = 'latest';
|
|
16
|
+
// Keys that might indicate local file path references in JSON payloads
|
|
17
|
+
const LOCAL_PATH_KEYS = ['path', 'directory', 'file', 'filepath', 'dir', 'folder', 'local'];
|
|
18
|
+
/**
|
|
19
|
+
* Check if a parsed JSON object contains keys that might reference local filesystem paths.
|
|
20
|
+
* Returns the first matching key found, or undefined if none found.
|
|
21
|
+
*/
|
|
22
|
+
function findLocalPathKey(obj) {
|
|
23
|
+
if (typeof obj !== 'object' || obj === null) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
const keys = Object.keys(obj);
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
if (LOCAL_PATH_KEYS.includes(key.toLowerCase())) {
|
|
29
|
+
return key;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Emit a warning to stderr if the payload contains local path references.
|
|
36
|
+
*/
|
|
37
|
+
function warnIfLocalPathReference(jsonBody) {
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(jsonBody);
|
|
40
|
+
const pathKey = findLocalPathKey(parsed);
|
|
41
|
+
if (pathKey) {
|
|
42
|
+
process.stderr.write(`Warning: Your payload contains a local path reference ('${pathKey}').\n` +
|
|
43
|
+
`Remote agents cannot access your local filesystem. The path will be interpreted\n` +
|
|
44
|
+
`by the server, not your local machine. Use --help for more information.\n\n`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// If parsing fails, skip the warning (the actual error will be thrown later)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
16
51
|
function parseAgentRef(value) {
|
|
17
52
|
const [ref, versionPart] = value.split('@');
|
|
18
53
|
const version = versionPart?.trim() || DEFAULT_VERSION;
|
|
@@ -118,6 +153,11 @@ Examples:
|
|
|
118
153
|
orch call acme/image-processor photo.jpg --output result.png
|
|
119
154
|
|
|
120
155
|
Note: Use 'call' for server-side execution (requires login), 'run' for local execution.
|
|
156
|
+
|
|
157
|
+
Important: Remote agents cannot access your local filesystem. If your --data payload
|
|
158
|
+
contains keys like 'path', 'directory', 'file', etc., those values will be interpreted
|
|
159
|
+
by the server, not your local machine. To send local files, use the positional file
|
|
160
|
+
argument or --file option instead.
|
|
121
161
|
`)
|
|
122
162
|
.action(async (agentRef, file, options) => {
|
|
123
163
|
// Merge --input alias into --data
|
|
@@ -194,6 +234,8 @@ Note: Use 'call' for server-side execution (requires login), 'run' for local exe
|
|
|
194
234
|
}
|
|
195
235
|
// Parse JSON and inject llm_credentials if available
|
|
196
236
|
const resolvedBody = await resolveJsonBody(options.data);
|
|
237
|
+
// Warn if payload contains local path references
|
|
238
|
+
warnIfLocalPathReference(resolvedBody);
|
|
197
239
|
if (llmCredentials) {
|
|
198
240
|
const bodyObj = JSON.parse(resolvedBody);
|
|
199
241
|
bodyObj.llm_credentials = llmCredentials;
|
package/dist/commands/env.js
CHANGED
|
@@ -52,6 +52,13 @@ async function resolveWorkspaceId(config, slug) {
|
|
|
52
52
|
const org = await (0, api_1.getOrg)(config);
|
|
53
53
|
return org.id;
|
|
54
54
|
}
|
|
55
|
+
// First check if the target slug matches the user's own org
|
|
56
|
+
// This avoids calling /workspaces which requires Clerk user identity
|
|
57
|
+
const org = await (0, api_1.getOrg)(config);
|
|
58
|
+
if (org.slug === targetSlug) {
|
|
59
|
+
return org.id;
|
|
60
|
+
}
|
|
61
|
+
// Only call /workspaces if accessing a different team workspace
|
|
55
62
|
const response = await (0, api_1.request)(config, 'GET', '/workspaces');
|
|
56
63
|
const workspace = response.workspaces.find((w) => w.slug === targetSlug);
|
|
57
64
|
if (!workspace) {
|
package/dist/commands/index.js
CHANGED
|
@@ -26,6 +26,7 @@ const install_1 = require("./install");
|
|
|
26
26
|
const formats_1 = require("./formats");
|
|
27
27
|
const update_1 = require("./update");
|
|
28
28
|
const env_1 = require("./env");
|
|
29
|
+
const list_1 = require("./list");
|
|
29
30
|
function registerCommands(program) {
|
|
30
31
|
(0, login_1.registerLoginCommand)(program);
|
|
31
32
|
(0, whoami_1.registerWhoamiCommand)(program);
|
|
@@ -52,4 +53,5 @@ function registerCommands(program) {
|
|
|
52
53
|
(0, formats_1.registerFormatsCommand)(program);
|
|
53
54
|
(0, update_1.registerUpdateCommand)(program);
|
|
54
55
|
(0, env_1.registerEnvCommand)(program);
|
|
56
|
+
(0, list_1.registerListCommand)(program);
|
|
55
57
|
}
|
package/dist/commands/install.js
CHANGED
|
@@ -14,7 +14,7 @@ const analytics_1 = require("../lib/analytics");
|
|
|
14
14
|
const adapters_1 = require("../adapters");
|
|
15
15
|
const installed_1 = require("../lib/installed");
|
|
16
16
|
const agents_md_utils_1 = require("../lib/agents-md-utils");
|
|
17
|
-
const DEFAULT_VERSION = '
|
|
17
|
+
const DEFAULT_VERSION = 'latest';
|
|
18
18
|
function parseAgentRef(value) {
|
|
19
19
|
const [ref, versionPart] = value.split('@');
|
|
20
20
|
const version = versionPart?.trim() || DEFAULT_VERSION;
|
|
@@ -95,7 +95,7 @@ function registerInstallCommand(program) {
|
|
|
95
95
|
if (jsonMode) {
|
|
96
96
|
result.errors.push('Missing org. Use org/agent format or set default org.');
|
|
97
97
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
98
|
-
process.exit(
|
|
98
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
99
99
|
}
|
|
100
100
|
throw new errors_1.CliError('Missing org. Use org/agent format or set default org.');
|
|
101
101
|
}
|
|
@@ -111,7 +111,7 @@ function registerInstallCommand(program) {
|
|
|
111
111
|
if (jsonMode) {
|
|
112
112
|
result.errors.push(errMsg);
|
|
113
113
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
114
|
-
process.exit(
|
|
114
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
115
115
|
}
|
|
116
116
|
throw new errors_1.CliError(errMsg);
|
|
117
117
|
}
|
|
@@ -134,7 +134,7 @@ function registerInstallCommand(program) {
|
|
|
134
134
|
if (jsonMode) {
|
|
135
135
|
result.errors.push(errMsg);
|
|
136
136
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
137
|
-
process.exit(
|
|
137
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
138
138
|
}
|
|
139
139
|
throw new errors_1.CliError(errMsg);
|
|
140
140
|
}
|
|
@@ -149,7 +149,7 @@ function registerInstallCommand(program) {
|
|
|
149
149
|
if (jsonMode) {
|
|
150
150
|
result.errors.push(err instanceof Error ? err.message : String(err));
|
|
151
151
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
152
|
-
process.exit(
|
|
152
|
+
process.exit(errors_1.ExitCodes.NOT_FOUND);
|
|
153
153
|
}
|
|
154
154
|
throw err;
|
|
155
155
|
}
|
|
@@ -262,11 +262,11 @@ function registerInstallCommand(program) {
|
|
|
262
262
|
if (jsonMode) {
|
|
263
263
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
264
264
|
if (!result.success) {
|
|
265
|
-
process.exit(
|
|
265
|
+
process.exit(errors_1.ExitCodes.GENERAL_ERROR);
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
else if (!result.success && !options.dryRun) {
|
|
269
|
-
process.exit(
|
|
269
|
+
process.exit(errors_1.ExitCodes.GENERAL_ERROR);
|
|
270
270
|
}
|
|
271
271
|
});
|
|
272
272
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerListCommand = registerListCommand;
|
|
4
|
+
const installed_1 = require("../lib/installed");
|
|
5
|
+
const output_1 = require("../lib/output");
|
|
6
|
+
function registerListCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('list')
|
|
9
|
+
.alias('ls')
|
|
10
|
+
.description('List installed agents')
|
|
11
|
+
.option('--json', 'Output as JSON')
|
|
12
|
+
.action(async (options) => {
|
|
13
|
+
const installed = await (0, installed_1.getInstalled)();
|
|
14
|
+
if (options.json) {
|
|
15
|
+
(0, output_1.printJson)(installed);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (installed.length === 0) {
|
|
19
|
+
process.stdout.write('No agents installed.\n');
|
|
20
|
+
process.stdout.write('Install agents with: orch install <agent>\n');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
process.stdout.write('Installed agents:\n\n');
|
|
24
|
+
for (const agent of installed) {
|
|
25
|
+
process.stdout.write(` ${agent.agent}@${agent.version}\n`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
package/dist/commands/publish.js
CHANGED
|
@@ -161,6 +161,7 @@ function registerPublishCommand(program) {
|
|
|
161
161
|
.option('--dry-run', 'Show what would be published without making changes')
|
|
162
162
|
.option('--skills <skills>', 'Default skills (comma-separated, e.g., org/skill@v1,org/other@v1)')
|
|
163
163
|
.option('--skills-locked', 'Lock default skills (callers cannot override via headers)')
|
|
164
|
+
.option('--docker', 'Include Dockerfile for custom environment (builds E2B template)')
|
|
164
165
|
.action(async (options) => {
|
|
165
166
|
if (options.private) {
|
|
166
167
|
process.stderr.write('Warning: --private is deprecated (private is now the default). You can safely remove it.\n');
|
|
@@ -449,10 +450,23 @@ function registerPublishCommand(program) {
|
|
|
449
450
|
const tempDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'orchagent-bundle-'));
|
|
450
451
|
const bundlePath = path_1.default.join(tempDir, 'bundle.zip');
|
|
451
452
|
try {
|
|
453
|
+
// Build include patterns - add Dockerfile if --docker flag is set
|
|
454
|
+
const includePatterns = [...(manifest.bundle?.include || [])];
|
|
455
|
+
if (options.docker) {
|
|
456
|
+
const dockerfilePath = path_1.default.join(cwd, 'Dockerfile');
|
|
457
|
+
try {
|
|
458
|
+
await promises_1.default.access(dockerfilePath);
|
|
459
|
+
includePatterns.push('Dockerfile');
|
|
460
|
+
process.stdout.write(` Including Dockerfile for custom environment\n`);
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
throw new errors_1.CliError('--docker flag specified but no Dockerfile found in project directory');
|
|
464
|
+
}
|
|
465
|
+
}
|
|
452
466
|
const bundleResult = await (0, bundle_1.createCodeBundle)(cwd, bundlePath, {
|
|
453
467
|
entrypoint: manifest.entrypoint,
|
|
454
468
|
exclude: manifest.bundle?.exclude,
|
|
455
|
-
include:
|
|
469
|
+
include: includePatterns.length > 0 ? includePatterns : undefined,
|
|
456
470
|
});
|
|
457
471
|
process.stdout.write(` Created bundle: ${bundleResult.fileCount} files, ${(bundleResult.sizeBytes / 1024).toFixed(1)}KB\n`);
|
|
458
472
|
// Validate bundle size
|
package/dist/commands/run.js
CHANGED
|
@@ -153,6 +153,11 @@ async function checkDependencies(config, dependencies) {
|
|
|
153
153
|
return results;
|
|
154
154
|
}
|
|
155
155
|
async function promptUserForDeps(depStatuses) {
|
|
156
|
+
// In non-interactive mode (CI, piped input), exit gracefully with helpful message
|
|
157
|
+
if (!process.stdin.isTTY) {
|
|
158
|
+
process.stderr.write('Non-interactive mode detected. Use --with-deps to include dependencies or --no-deps to skip them.\n');
|
|
159
|
+
return 'cancel';
|
|
160
|
+
}
|
|
156
161
|
const readline = await Promise.resolve().then(() => __importStar(require('readline')));
|
|
157
162
|
const rl = readline.createInterface({
|
|
158
163
|
input: process.stdin,
|
package/dist/commands/skill.js
CHANGED
|
@@ -12,7 +12,7 @@ const api_1 = require("../lib/api");
|
|
|
12
12
|
const errors_1 = require("../lib/errors");
|
|
13
13
|
const analytics_1 = require("../lib/analytics");
|
|
14
14
|
const package_json_1 = __importDefault(require("../../package.json"));
|
|
15
|
-
const DEFAULT_VERSION = '
|
|
15
|
+
const DEFAULT_VERSION = 'latest';
|
|
16
16
|
/**
|
|
17
17
|
* AI tool skill directories.
|
|
18
18
|
*
|
|
@@ -21,7 +21,7 @@ const DEFAULT_VERSION = 'v1';
|
|
|
21
21
|
*
|
|
22
22
|
* TODO: Research and add more AI tool directories as the ecosystem evolves.
|
|
23
23
|
* Known tools to research: Gemini CLI, Aider, OpenCode, Amp, Windsurf, Cline,
|
|
24
|
-
* GitHub Copilot CLI,
|
|
24
|
+
* GitHub Copilot CLI, Qwen Code, Kimi Code, etc.
|
|
25
25
|
*
|
|
26
26
|
* References:
|
|
27
27
|
* - https://github.com/gotalab/skillport
|
|
@@ -31,7 +31,6 @@ const DEFAULT_VERSION = 'v1';
|
|
|
31
31
|
const AI_TOOL_SKILL_DIRS = [
|
|
32
32
|
{ name: 'Claude Code', projectPath: '.claude/skills', userPath: '.claude/skills' },
|
|
33
33
|
{ name: 'Cursor', projectPath: '.cursor/skills', userPath: '.cursor/skills' },
|
|
34
|
-
{ name: 'Codex', projectPath: '.codex/skills', userPath: '.codex/skills' },
|
|
35
34
|
{ name: 'Amp', projectPath: '.agents/skills', userPath: '.agents/skills' },
|
|
36
35
|
{ name: 'OpenCode', projectPath: '.opencode/skill', userPath: '.opencode/skill' },
|
|
37
36
|
{ name: 'Antigravity', projectPath: '.agent/skills', userPath: '.agent/skills' },
|
|
@@ -194,7 +193,7 @@ Instructions and guidance for AI agents...
|
|
|
194
193
|
if (jsonMode) {
|
|
195
194
|
result.errors.push(errMsg);
|
|
196
195
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
197
|
-
process.exit(
|
|
196
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
198
197
|
}
|
|
199
198
|
throw new errors_1.CliError(errMsg);
|
|
200
199
|
}
|
|
@@ -223,7 +222,7 @@ Instructions and guidance for AI agents...
|
|
|
223
222
|
if (jsonMode) {
|
|
224
223
|
result.errors.push(errMsg);
|
|
225
224
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
226
|
-
process.exit(
|
|
225
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
227
226
|
}
|
|
228
227
|
throw new errors_1.CliError(errMsg);
|
|
229
228
|
}
|
|
@@ -238,7 +237,7 @@ Instructions and guidance for AI agents...
|
|
|
238
237
|
if (jsonMode) {
|
|
239
238
|
result.errors.push(err instanceof Error ? err.message : String(err));
|
|
240
239
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
241
|
-
process.exit(
|
|
240
|
+
process.exit(errors_1.ExitCodes.NOT_FOUND);
|
|
242
241
|
}
|
|
243
242
|
throw err;
|
|
244
243
|
}
|
|
@@ -247,7 +246,7 @@ Instructions and guidance for AI agents...
|
|
|
247
246
|
if (jsonMode) {
|
|
248
247
|
result.errors.push(errMsg);
|
|
249
248
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
250
|
-
process.exit(
|
|
249
|
+
process.exit(errors_1.ExitCodes.INVALID_INPUT);
|
|
251
250
|
}
|
|
252
251
|
throw new errors_1.CliError('Skill has no content.\n\n' +
|
|
253
252
|
'The skill exists but has an empty prompt. This may be a publishing issue.\n' +
|
|
@@ -309,7 +308,7 @@ ${skillData.prompt}
|
|
|
309
308
|
if (jsonMode) {
|
|
310
309
|
result.errors.push(errMsg);
|
|
311
310
|
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
312
|
-
process.exit(
|
|
311
|
+
process.exit(errors_1.ExitCodes.GENERAL_ERROR);
|
|
313
312
|
}
|
|
314
313
|
throw new errors_1.CliError(errMsg);
|
|
315
314
|
}
|
package/dist/lib/bundle.js
CHANGED
|
@@ -110,7 +110,10 @@ const DEFAULT_EXCLUDES = [
|
|
|
110
110
|
* @returns Promise that resolves with bundle metadata
|
|
111
111
|
*/
|
|
112
112
|
async function createCodeBundle(sourceDir, outputPath, options = {}) {
|
|
113
|
-
|
|
113
|
+
// Build exclude patterns, but remove any that are in the include list
|
|
114
|
+
const includeSet = new Set(options.include || []);
|
|
115
|
+
const excludePatterns = [...DEFAULT_EXCLUDES, ...(options.exclude || [])]
|
|
116
|
+
.filter(pattern => !includeSet.has(pattern));
|
|
114
117
|
// Verify source directory exists
|
|
115
118
|
const stat = await promises_1.default.stat(sourceDir);
|
|
116
119
|
if (!stat.isDirectory()) {
|
package/dist/lib/config.js
CHANGED
|
@@ -50,12 +50,11 @@ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.orchagent');
|
|
|
50
50
|
const CONFIG_PATH = path_1.default.join(CONFIG_DIR, 'config.json');
|
|
51
51
|
const DEFAULT_API_URL = 'https://api.orchagent.io';
|
|
52
52
|
// Valid format IDs for multi-format agent export
|
|
53
|
-
exports.VALID_FORMAT_IDS = ['claude-code', 'cursor', '
|
|
53
|
+
exports.VALID_FORMAT_IDS = ['claude-code', 'cursor', 'amp', 'opencode', 'antigravity'];
|
|
54
54
|
// Map format IDs to skill directories (used by skill install and agent install)
|
|
55
55
|
exports.FORMAT_SKILL_DIRS = {
|
|
56
56
|
'claude-code': { name: 'Claude Code', projectPath: '.claude/skills', userPath: '.claude/skills' },
|
|
57
57
|
'cursor': { name: 'Cursor', projectPath: '.cursor/skills', userPath: '.cursor/skills' },
|
|
58
|
-
'codex': { name: 'Codex', projectPath: '.codex/skills', userPath: '.codex/skills' },
|
|
59
58
|
'amp': { name: 'Amp', projectPath: '.agents/skills', userPath: '.agents/skills' },
|
|
60
59
|
'opencode': { name: 'OpenCode', projectPath: '.opencode/skill', userPath: '.opencode/skill' },
|
|
61
60
|
'antigravity': { name: 'Antigravity', projectPath: '.agent/skills', userPath: '.agent/skills' },
|
package/dist/lib/errors.js
CHANGED
|
@@ -36,9 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.NetworkError = exports.ExitCodes = exports.CliError = void 0;
|
|
37
37
|
exports.formatError = formatError;
|
|
38
38
|
exports.exitWithError = exitWithError;
|
|
39
|
+
exports.mapHttpStatusToExitCode = mapHttpStatusToExitCode;
|
|
39
40
|
exports.jsonInputError = jsonInputError;
|
|
40
41
|
const Sentry = __importStar(require("@sentry/node"));
|
|
41
42
|
const analytics_1 = require("./analytics");
|
|
43
|
+
const api_1 = require("./api");
|
|
42
44
|
class CliError extends Error {
|
|
43
45
|
exitCode;
|
|
44
46
|
cause;
|
|
@@ -73,6 +75,10 @@ async function exitWithError(err) {
|
|
|
73
75
|
if (err instanceof CliError) {
|
|
74
76
|
process.exit(err.exitCode);
|
|
75
77
|
}
|
|
78
|
+
// Handle API errors with proper exit codes
|
|
79
|
+
if (err instanceof api_1.ApiError) {
|
|
80
|
+
process.exit(mapHttpStatusToExitCode(err.status));
|
|
81
|
+
}
|
|
76
82
|
process.exit(1);
|
|
77
83
|
}
|
|
78
84
|
exports.ExitCodes = {
|
|
@@ -87,6 +93,22 @@ exports.ExitCodes = {
|
|
|
87
93
|
SERVER_ERROR: 8,
|
|
88
94
|
NETWORK_ERROR: 9,
|
|
89
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Map HTTP status codes to CLI exit codes.
|
|
98
|
+
*/
|
|
99
|
+
function mapHttpStatusToExitCode(status) {
|
|
100
|
+
if (status === 401)
|
|
101
|
+
return exports.ExitCodes.AUTH_ERROR;
|
|
102
|
+
if (status === 403)
|
|
103
|
+
return exports.ExitCodes.PERMISSION_DENIED;
|
|
104
|
+
if (status === 404)
|
|
105
|
+
return exports.ExitCodes.NOT_FOUND;
|
|
106
|
+
if (status === 429)
|
|
107
|
+
return exports.ExitCodes.RATE_LIMITED;
|
|
108
|
+
if (status >= 500 && status <= 599)
|
|
109
|
+
return exports.ExitCodes.SERVER_ERROR;
|
|
110
|
+
return exports.ExitCodes.GENERAL_ERROR;
|
|
111
|
+
}
|
|
90
112
|
class NetworkError extends CliError {
|
|
91
113
|
constructor(url, cause) {
|
|
92
114
|
const host = new URL(url).host;
|