@samanhappy/mcphub 1.0.0 → 1.0.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.
- package/README.fr.md +6 -4
- package/README.md +24 -4
- package/README.zh.md +25 -4
- package/bin/cli.js +64 -50
- package/dist/betterAuth.js +21 -0
- package/dist/betterAuth.js.map +1 -1
- package/dist/cli/call-arguments.js +81 -0
- package/dist/cli/call-arguments.js.map +1 -0
- package/dist/cli/commands/call.js +75 -0
- package/dist/cli/commands/call.js.map +1 -0
- package/dist/cli/commands/config.js +132 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/discover.js +127 -0
- package/dist/cli/commands/discover.js.map +1 -0
- package/dist/cli/commands/export.js +20 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/groups.js +107 -0
- package/dist/cli/commands/groups.js.map +1 -0
- package/dist/cli/commands/install.js +173 -0
- package/dist/cli/commands/install.js.map +1 -0
- package/dist/cli/commands/keys.js +91 -0
- package/dist/cli/commands/keys.js.map +1 -0
- package/dist/cli/commands/login.js +70 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/servers.js +142 -0
- package/dist/cli/commands/servers.js.map +1 -0
- package/dist/cli/commands/tools.js +162 -0
- package/dist/cli/commands/tools.js.map +1 -0
- package/dist/cli/context.js +44 -0
- package/dist/cli/context.js.map +1 -0
- package/dist/cli/errors.js +19 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/help.js +157 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/http.js +93 -0
- package/dist/cli/http.js.map +1 -0
- package/dist/cli/main.js +81 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/output.js +47 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/parse-args.js +103 -0
- package/dist/cli/parse-args.js.map +1 -0
- package/dist/cli/profile.js +109 -0
- package/dist/cli/profile.js.map +1 -0
- package/dist/cli/prompts.js +56 -0
- package/dist/cli/prompts.js.map +1 -0
- package/dist/controllers/oauthServerController.js +37 -1
- package/dist/controllers/oauthServerController.js.map +1 -1
- package/dist/controllers/serverController.js +3 -0
- package/dist/controllers/serverController.js.map +1 -1
- package/dist/dao/ActivityDao.js +2 -0
- package/dist/dao/ActivityDao.js.map +1 -1
- package/dist/dao/ServerDaoDbImpl.js +3 -0
- package/dist/dao/ServerDaoDbImpl.js.map +1 -1
- package/dist/db/connection.js +48 -4
- package/dist/db/connection.js.map +1 -1
- package/dist/db/entities/Activity.js +4 -0
- package/dist/db/entities/Activity.js.map +1 -1
- package/dist/db/entities/Server.js +4 -0
- package/dist/db/entities/Server.js.map +1 -1
- package/dist/db/entities/VectorEmbedding.js +2 -5
- package/dist/db/entities/VectorEmbedding.js.map +1 -1
- package/dist/db/repositories/VectorEmbeddingRepository.js +100 -34
- package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
- package/dist/services/activityLoggingService.js +1 -0
- package/dist/services/activityLoggingService.js.map +1 -1
- package/dist/services/betterAuthConfig.js +18 -1
- package/dist/services/betterAuthConfig.js.map +1 -1
- package/dist/services/dataService.js +10 -1
- package/dist/services/dataService.js.map +1 -1
- package/dist/services/mcpService.js +46 -12
- package/dist/services/mcpService.js.map +1 -1
- package/dist/services/vectorSearchService.js +16 -3
- package/dist/services/vectorSearchService.js.map +1 -1
- package/dist/utils/migration.js +1 -0
- package/dist/utils/migration.js.map +1 -1
- package/dist/utils/rateLimit.js +3 -3
- package/dist/utils/serverConfigPersistence.js +5 -0
- package/dist/utils/serverConfigPersistence.js.map +1 -1
- package/frontend/dist/assets/ActivityPage-B1B9ySGe.js +2 -0
- package/frontend/dist/assets/ActivityPage-B1B9ySGe.js.map +1 -0
- package/frontend/dist/assets/Dashboard-CYzpYZ1d.js +2 -0
- package/frontend/dist/assets/Dashboard-CYzpYZ1d.js.map +1 -0
- package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js → EndpointCopy-DVmlWW-s.js} +2 -2
- package/frontend/dist/assets/{EndpointCopy-C59moJ3Y.js.map → EndpointCopy-DVmlWW-s.js.map} +1 -1
- package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js → GroupsPage-CsyoUc8S.js} +2 -2
- package/frontend/dist/assets/{GroupsPage-Bhg51kbu.js.map → GroupsPage-CsyoUc8S.js.map} +1 -1
- package/frontend/dist/assets/LoginPage-C3t8hbb2.js +2 -0
- package/frontend/dist/assets/LoginPage-C3t8hbb2.js.map +1 -0
- package/frontend/dist/assets/{LogsPage-HBGNLtyN.js → LogsPage-DOZeagVs.js} +2 -2
- package/frontend/dist/assets/{LogsPage-HBGNLtyN.js.map → LogsPage-DOZeagVs.js.map} +1 -1
- package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js → MarketPage-kMEHUGfJ.js} +2 -2
- package/frontend/dist/assets/{MarketPage-C5ATZ4WS.js.map → MarketPage-kMEHUGfJ.js.map} +1 -1
- package/frontend/dist/assets/{PromptsPage-DUge8OO4.js → PromptsPage-D7JYoTav.js} +2 -2
- package/frontend/dist/assets/{PromptsPage-DUge8OO4.js.map → PromptsPage-D7JYoTav.js.map} +1 -1
- package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js → ResourcesPage-BlwePI9a.js} +2 -2
- package/frontend/dist/assets/{ResourcesPage-5J3JYGVC.js.map → ResourcesPage-BlwePI9a.js.map} +1 -1
- package/frontend/dist/assets/ServersPage-DrkPpCgK.js +37 -0
- package/frontend/dist/assets/ServersPage-DrkPpCgK.js.map +1 -0
- package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js → SettingsPage-BWigWLml.js} +2 -2
- package/frontend/dist/assets/{SettingsPage-BeLZKC1d.js.map → SettingsPage-BWigWLml.js.map} +1 -1
- package/frontend/dist/assets/{StatusDot-DR803YdX.js → StatusDot-BDBIaafQ.js} +2 -2
- package/frontend/dist/assets/{StatusDot-DR803YdX.js.map → StatusDot-BDBIaafQ.js.map} +1 -1
- package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js → ToggleGroup-OOcsllhw.js} +2 -2
- package/frontend/dist/assets/{ToggleGroup-DE8t8Ni4.js.map → ToggleGroup-OOcsllhw.js.map} +1 -1
- package/frontend/dist/assets/{UsersPage-CMscqAmn.js → UsersPage-DL8E7KtW.js} +2 -2
- package/frontend/dist/assets/{UsersPage-CMscqAmn.js.map → UsersPage-DL8E7KtW.js.map} +1 -1
- package/frontend/dist/assets/index-C7wNc_3N.js +3 -0
- package/frontend/dist/assets/index-C7wNc_3N.js.map +1 -0
- package/frontend/dist/assets/index-D0OIBhmN.css +1 -0
- package/frontend/dist/assets/{resourceService-BFMkDDIh.js → resourceService-B-U4FKGB.js} +2 -2
- package/frontend/dist/assets/{resourceService-BFMkDDIh.js.map → resourceService-B-U4FKGB.js.map} +1 -1
- package/frontend/dist/assets/{useServerData-BnLmpLAC.js → useServerData-DYoDryJj.js} +2 -2
- package/frontend/dist/assets/{useServerData-BnLmpLAC.js.map → useServerData-DYoDryJj.js.map} +1 -1
- package/frontend/dist/assets/useSettingsData-6utb1Z46.js +2 -0
- package/frontend/dist/assets/{useSettingsData-Cqi9d7Ug.js.map → useSettingsData-6utb1Z46.js.map} +1 -1
- package/frontend/dist/assets/{variableDetection-BigiltQM.js → variableDetection-DsYuiOB_.js} +3 -3
- package/frontend/dist/assets/variableDetection-DsYuiOB_.js.map +1 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +2 -1
- package/frontend/dist/assets/ActivityPage-VwilVMvp.js +0 -2
- package/frontend/dist/assets/ActivityPage-VwilVMvp.js.map +0 -1
- package/frontend/dist/assets/Dashboard-DuBJTbbA.js +0 -2
- package/frontend/dist/assets/Dashboard-DuBJTbbA.js.map +0 -1
- package/frontend/dist/assets/LoginPage-C8RkMoJN.js +0 -2
- package/frontend/dist/assets/LoginPage-C8RkMoJN.js.map +0 -1
- package/frontend/dist/assets/ServersPage-DtnlfwJF.js +0 -37
- package/frontend/dist/assets/ServersPage-DtnlfwJF.js.map +0 -1
- package/frontend/dist/assets/index-B9cW2F0H.js +0 -3
- package/frontend/dist/assets/index-B9cW2F0H.js.map +0 -1
- package/frontend/dist/assets/index-Crcbkt8x.css +0 -1
- package/frontend/dist/assets/useSettingsData-Cqi9d7Ug.js +0 -2
- package/frontend/dist/assets/variableDetection-BigiltQM.js.map +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
3
|
+
import { extractFlags } from '../parse-args.js';
|
|
4
|
+
import { green, maskToken, printJson, printLine, printTable } from '../output.js';
|
|
5
|
+
const VALID_ACCESS_TYPES = ['all', 'groups', 'servers', 'custom'];
|
|
6
|
+
export async function run(args, globals, deps = {}) {
|
|
7
|
+
const sub = args.shift();
|
|
8
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
9
|
+
switch (sub) {
|
|
10
|
+
case undefined:
|
|
11
|
+
case 'list':
|
|
12
|
+
return list(client, globals);
|
|
13
|
+
case 'create':
|
|
14
|
+
return create(client, args, globals);
|
|
15
|
+
case 'delete':
|
|
16
|
+
return remove(client, args);
|
|
17
|
+
default:
|
|
18
|
+
throw new CliUsageError(`Unknown keys subcommand: ${sub}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async function list(client, globals) {
|
|
22
|
+
const res = await client.get('/api/auth/keys');
|
|
23
|
+
const keys = res.data ?? [];
|
|
24
|
+
if (globals.json) {
|
|
25
|
+
// Show the raw token in --json so scripts can capture it. Plaintext only
|
|
26
|
+
// returns to the user who has admin access to the hub anyway.
|
|
27
|
+
printJson(keys);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
printTable(keys.map((k) => ({
|
|
31
|
+
id: k.id,
|
|
32
|
+
name: k.name,
|
|
33
|
+
enabled: k.enabled ? 'yes' : 'no',
|
|
34
|
+
accessType: k.accessType,
|
|
35
|
+
token: maskToken(k.token),
|
|
36
|
+
})), ['id', 'name', 'enabled', 'accessType', 'token']);
|
|
37
|
+
}
|
|
38
|
+
async function create(client, args, globals) {
|
|
39
|
+
const { flags } = extractFlags(args, {
|
|
40
|
+
valued: ['--name', '--access-type', '--groups', '--servers', '--token'],
|
|
41
|
+
boolean: ['--disabled'],
|
|
42
|
+
});
|
|
43
|
+
const name = flags['--name'];
|
|
44
|
+
if (!name) {
|
|
45
|
+
throw new CliUsageError('Usage: mcphub keys create --name <n> [--access-type all|groups|servers|custom] [--groups a,b] [--servers x,y]');
|
|
46
|
+
}
|
|
47
|
+
const accessType = flags['--access-type'] ?? 'all';
|
|
48
|
+
if (!VALID_ACCESS_TYPES.includes(accessType)) {
|
|
49
|
+
throw new CliUsageError(`Invalid --access-type: ${accessType}. Expected one of ${VALID_ACCESS_TYPES.join(', ')}`);
|
|
50
|
+
}
|
|
51
|
+
const body = {
|
|
52
|
+
name,
|
|
53
|
+
enabled: !flags['--disabled'],
|
|
54
|
+
accessType,
|
|
55
|
+
};
|
|
56
|
+
if (flags['--token'])
|
|
57
|
+
body.token = flags['--token'];
|
|
58
|
+
if (accessType === 'groups' || accessType === 'custom') {
|
|
59
|
+
if (flags['--groups'])
|
|
60
|
+
body.allowedGroups = splitCsv(flags['--groups']);
|
|
61
|
+
}
|
|
62
|
+
if (accessType === 'servers' || accessType === 'custom') {
|
|
63
|
+
if (flags['--servers'])
|
|
64
|
+
body.allowedServers = splitCsv(flags['--servers']);
|
|
65
|
+
}
|
|
66
|
+
const res = await client.post('/api/auth/keys', body);
|
|
67
|
+
if (globals.json) {
|
|
68
|
+
printJson(res.data);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
printLine(green(`Created key "${name}" (id: ${res.data?.id ?? 'unknown'}).`));
|
|
72
|
+
if (res.data?.token) {
|
|
73
|
+
// The server generates the token if not supplied. Print it once — admins
|
|
74
|
+
// need to copy it before navigating away.
|
|
75
|
+
printLine(`Token: ${res.data.token}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function remove(client, args) {
|
|
79
|
+
const id = args[0];
|
|
80
|
+
if (!id)
|
|
81
|
+
throw new CliUsageError('Usage: mcphub keys delete <id>');
|
|
82
|
+
await client.delete(`/api/auth/keys/${encodeURIComponent(id)}`);
|
|
83
|
+
printLine(green(`Deleted key ${id}.`));
|
|
84
|
+
}
|
|
85
|
+
function splitCsv(s) {
|
|
86
|
+
return s
|
|
87
|
+
.split(',')
|
|
88
|
+
.map((p) => p.trim())
|
|
89
|
+
.filter(Boolean);
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keys.js","sourceRoot":"","sources":["../../../src/cli/commands/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ApiClient } from '../http.js';
|
|
2
|
+
import { CliUsageError } from '../errors.js';
|
|
3
|
+
import { extractFlags } from '../parse-args.js';
|
|
4
|
+
import { loadCredentials, saveCredentials, setProfile, getProfile, } from '../profile.js';
|
|
5
|
+
import { green, yellow, printLine, printWarn } from '../output.js';
|
|
6
|
+
import { promptLine, promptPassword } from '../prompts.js';
|
|
7
|
+
export async function run(args, globals, deps = {}) {
|
|
8
|
+
const { flags } = extractFlags(args, {
|
|
9
|
+
valued: ['--url', '--username', '--password', '--profile-name'],
|
|
10
|
+
});
|
|
11
|
+
const loadCreds = deps.loadCreds ?? loadCredentials;
|
|
12
|
+
const saveCreds = deps.saveCreds ?? saveCredentials;
|
|
13
|
+
const prompts = deps.prompts ?? { line: promptLine, password: promptPassword };
|
|
14
|
+
const credentials = loadCreds();
|
|
15
|
+
const targetProfileName = flags['--profile-name'] ||
|
|
16
|
+
globals.profile ||
|
|
17
|
+
credentials.current ||
|
|
18
|
+
'default';
|
|
19
|
+
const existing = getProfile(credentials, targetProfileName);
|
|
20
|
+
const url = flags['--url'] ||
|
|
21
|
+
globals.url ||
|
|
22
|
+
existing?.url ||
|
|
23
|
+
(await prompts.line('mcphub URL [http://localhost:3000]: ')) ||
|
|
24
|
+
'http://localhost:3000';
|
|
25
|
+
const username = flags['--username'] ||
|
|
26
|
+
existing?.username ||
|
|
27
|
+
(await prompts.line('Username [admin]: ')) ||
|
|
28
|
+
'admin';
|
|
29
|
+
const password = flags['--password'] || (await prompts.password('Password: '));
|
|
30
|
+
if (!password) {
|
|
31
|
+
throw new CliUsageError('Password is required.');
|
|
32
|
+
}
|
|
33
|
+
const client = deps.createClient ? deps.createClient(url) : new ApiClient({ baseUrl: url });
|
|
34
|
+
const response = await client.post('/api/auth/login', { username, password });
|
|
35
|
+
if (!response || !response.token) {
|
|
36
|
+
throw new CliUsageError('Login response did not include a token.');
|
|
37
|
+
}
|
|
38
|
+
const next = setProfile(credentials, targetProfileName, {
|
|
39
|
+
url,
|
|
40
|
+
tokenKind: 'jwt',
|
|
41
|
+
token: response.token,
|
|
42
|
+
username: response.user?.username || username,
|
|
43
|
+
});
|
|
44
|
+
saveCreds(next);
|
|
45
|
+
printLine(green(`Logged in as ${response.user?.username || username} at ${url}`));
|
|
46
|
+
printLine(`Saved as profile "${targetProfileName}".`);
|
|
47
|
+
if (response.isUsingDefaultPassword) {
|
|
48
|
+
printWarn('Warning: this account is still using the default password. Change it soon.');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export async function logout(args, globals, deps = {}) {
|
|
52
|
+
const loadCreds = deps.loadCreds ?? loadCredentials;
|
|
53
|
+
const saveCreds = deps.saveCreds ?? saveCredentials;
|
|
54
|
+
const credentials = loadCreds();
|
|
55
|
+
const targetName = globals.profile || credentials.current;
|
|
56
|
+
if (!targetName || !credentials.profiles[targetName]) {
|
|
57
|
+
throw new CliUsageError('No active profile to log out from.');
|
|
58
|
+
}
|
|
59
|
+
const existing = credentials.profiles[targetName];
|
|
60
|
+
const next = setProfile(credentials, targetName, {
|
|
61
|
+
url: existing.url,
|
|
62
|
+
username: existing.username,
|
|
63
|
+
// token + tokenKind dropped intentionally
|
|
64
|
+
});
|
|
65
|
+
saveCreds(next);
|
|
66
|
+
printLine(yellow(`Cleared token for profile "${targetName}".`));
|
|
67
|
+
// Silence unused-arg warning while keeping the signature consistent.
|
|
68
|
+
void args;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAEL,eAAe,EACf,eAAe,EACf,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAoB3D,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,IAAc,EAAE,OAAoB,EAAE,OAAkB,EAAE;IAClF,MAAM,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE;QACnC,MAAM,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,CAAC;KAChE,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAE/E,MAAM,WAAW,GAAG,SAAS,EAAE,CAAC;IAChC,MAAM,iBAAiB,GACpB,KAAK,CAAC,gBAAgB,CAAwB;QAC/C,OAAO,CAAC,OAAO;QACf,WAAW,CAAC,OAAO;QACnB,SAAS,CAAC;IACZ,MAAM,QAAQ,GAAG,UAAU,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAE5D,MAAM,GAAG,GACN,KAAK,CAAC,OAAO,CAAwB;QACtC,OAAO,CAAC,GAAG;QACX,QAAQ,EAAE,GAAG;QACb,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QAC5D,uBAAuB,CAAC;IAE1B,MAAM,QAAQ,GACX,KAAK,CAAC,YAAY,CAAwB;QAC3C,QAAQ,EAAE,QAAQ;QAClB,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAC1C,OAAO,CAAC;IAEV,MAAM,QAAQ,GACX,KAAK,CAAC,YAAY,CAAwB,IAAI,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IAExF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,aAAa,CAAC,uBAAuB,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5F,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,IAAI,CAAgB,iBAAiB,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE7F,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjC,MAAM,IAAI,aAAa,CAAC,yCAAyC,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,iBAAiB,EAAE;QACtD,GAAG;QACH,SAAS,EAAE,KAAK;QAChB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,IAAI,QAAQ;KAC9C,CAAC,CAAC;IACH,SAAS,CAAC,IAAI,CAAC,CAAC;IAEhB,SAAS,CAAC,KAAK,CAAC,gBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,IAAI,QAAQ,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC;IAClF,SAAS,CAAC,qBAAqB,iBAAiB,IAAI,CAAC,CAAC;IAEtD,IAAI,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QACpC,SAAS,CAAC,4EAA4E,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc,EAAE,OAAoB,EAAE,OAAkB,EAAE;IACrF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,eAAe,CAAC;IACpD,MAAM,WAAW,GAAG,SAAS,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC;IAC1D,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,aAAa,CAAC,oCAAoC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE;QAC/C,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,0CAA0C;KAC3C,CAAC,CAAC;IACH,SAAS,CAAC,IAAI,CAAC,CAAC;IAChB,SAAS,CAAC,MAAM,CAAC,8BAA8B,UAAU,IAAI,CAAC,CAAC,CAAC;IAChE,qEAAqE;IACrE,KAAK,IAAI,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import { CliUsageError } from '../errors.js';
|
|
3
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
4
|
+
import { extractFlags } from '../parse-args.js';
|
|
5
|
+
import { green, printJson, printLine, printTable } from '../output.js';
|
|
6
|
+
export async function run(args, globals, deps = {}) {
|
|
7
|
+
const sub = args.shift();
|
|
8
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
9
|
+
switch (sub) {
|
|
10
|
+
case undefined:
|
|
11
|
+
case 'list':
|
|
12
|
+
return list(client, globals);
|
|
13
|
+
case 'get':
|
|
14
|
+
return get(client, args, globals);
|
|
15
|
+
case 'add':
|
|
16
|
+
return add(client, args, globals, deps);
|
|
17
|
+
case 'remove':
|
|
18
|
+
return remove(client, args);
|
|
19
|
+
case 'toggle':
|
|
20
|
+
return toggle(client, args);
|
|
21
|
+
case 'reload':
|
|
22
|
+
return reload(client, args);
|
|
23
|
+
default:
|
|
24
|
+
throw new CliUsageError(`Unknown servers subcommand: ${sub}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function list(client, globals) {
|
|
28
|
+
const res = await client.get('/api/servers');
|
|
29
|
+
const servers = res.data ?? [];
|
|
30
|
+
if (globals.json) {
|
|
31
|
+
printJson(servers);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
printTable(servers.map((s) => ({
|
|
35
|
+
name: s.name,
|
|
36
|
+
status: s.status,
|
|
37
|
+
tools: s.tools?.length ?? 0,
|
|
38
|
+
owner: s.owner ?? '',
|
|
39
|
+
error: s.error ?? '',
|
|
40
|
+
})), ['name', 'status', 'tools', 'owner', 'error']);
|
|
41
|
+
}
|
|
42
|
+
async function get(client, args, globals) {
|
|
43
|
+
const name = args[0];
|
|
44
|
+
if (!name)
|
|
45
|
+
throw new CliUsageError('Usage: mcphub servers get <name>');
|
|
46
|
+
const res = await client.get(`/api/servers/${encodeURIComponent(name)}`);
|
|
47
|
+
if (globals.json) {
|
|
48
|
+
printJson(res.data);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
printLine(JSON.stringify(res.data, null, 2));
|
|
52
|
+
}
|
|
53
|
+
async function add(client, args, globals, deps) {
|
|
54
|
+
const { positional, flags } = extractFlags(args, {
|
|
55
|
+
valued: ['--from-file', '--type', '--command', '--url', '--description'],
|
|
56
|
+
boolean: ['--enabled', '--disabled'],
|
|
57
|
+
});
|
|
58
|
+
const name = positional[0];
|
|
59
|
+
if (!name) {
|
|
60
|
+
throw new CliUsageError('Usage: mcphub servers add <name> --from-file <path>\n' +
|
|
61
|
+
' or mcphub servers add <name> --type <stdio|sse|streamable-http|openapi> [--command ...] [--arg ...] [--env K=V ...]');
|
|
62
|
+
}
|
|
63
|
+
let config;
|
|
64
|
+
if (flags['--from-file']) {
|
|
65
|
+
const path = flags['--from-file'];
|
|
66
|
+
const raw = (deps.fs ?? fs).readFileSync(path, 'utf8');
|
|
67
|
+
config = JSON.parse(raw);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
const argArgs = collectRepeated(args, '--arg');
|
|
71
|
+
const envEntries = collectRepeated(args, '--env').map((kv) => {
|
|
72
|
+
const idx = kv.indexOf('=');
|
|
73
|
+
if (idx < 0)
|
|
74
|
+
throw new CliUsageError(`--env expects KEY=VALUE, got: ${kv}`);
|
|
75
|
+
return [kv.slice(0, idx), kv.slice(idx + 1)];
|
|
76
|
+
});
|
|
77
|
+
config = {
|
|
78
|
+
type: flags['--type'] || 'stdio',
|
|
79
|
+
description: flags['--description'],
|
|
80
|
+
command: flags['--command'],
|
|
81
|
+
args: argArgs.length > 0 ? argArgs : undefined,
|
|
82
|
+
env: envEntries.length > 0 ? Object.fromEntries(envEntries) : undefined,
|
|
83
|
+
url: flags['--url'],
|
|
84
|
+
enabled: flags['--disabled'] ? false : true,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const res = await client.post('/api/servers', { name, config });
|
|
88
|
+
if (globals.json) {
|
|
89
|
+
printJson(res);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
printLine(green(`Added server "${name}".`));
|
|
93
|
+
}
|
|
94
|
+
async function remove(client, args) {
|
|
95
|
+
const name = args[0];
|
|
96
|
+
if (!name)
|
|
97
|
+
throw new CliUsageError('Usage: mcphub servers remove <name>');
|
|
98
|
+
await client.delete(`/api/servers/${encodeURIComponent(name)}`);
|
|
99
|
+
printLine(green(`Removed server "${name}".`));
|
|
100
|
+
}
|
|
101
|
+
async function toggle(client, args) {
|
|
102
|
+
const { positional, flags } = extractFlags(args, { boolean: ['--on', '--off'] });
|
|
103
|
+
const name = positional[0];
|
|
104
|
+
if (!name)
|
|
105
|
+
throw new CliUsageError('Usage: mcphub servers toggle <name> [--on|--off]');
|
|
106
|
+
const body = {};
|
|
107
|
+
if (flags['--on'])
|
|
108
|
+
body.enabled = true;
|
|
109
|
+
if (flags['--off'])
|
|
110
|
+
body.enabled = false;
|
|
111
|
+
await client.post(`/api/servers/${encodeURIComponent(name)}/toggle`, body);
|
|
112
|
+
printLine(green(`Toggled server "${name}".`));
|
|
113
|
+
}
|
|
114
|
+
async function reload(client, args) {
|
|
115
|
+
const name = args[0];
|
|
116
|
+
if (!name)
|
|
117
|
+
throw new CliUsageError('Usage: mcphub servers reload <name>');
|
|
118
|
+
await client.post(`/api/servers/${encodeURIComponent(name)}/reload`, {});
|
|
119
|
+
printLine(green(`Reloaded server "${name}".`));
|
|
120
|
+
}
|
|
121
|
+
// Helper: pull every occurrence of `--flag <value>` out of argv. extractFlags
|
|
122
|
+
// only captures the last occurrence, so repeated flags need this scan. Values
|
|
123
|
+
// may legitimately start with `--` (e.g. `--arg --version` for a wrapped CLI);
|
|
124
|
+
// we consume them unconditionally and skip the next index so we don't re-scan
|
|
125
|
+
// the value as another flag boundary.
|
|
126
|
+
function collectRepeated(argv, flag) {
|
|
127
|
+
const out = [];
|
|
128
|
+
for (let i = 0; i < argv.length; i++) {
|
|
129
|
+
if (argv[i] === flag) {
|
|
130
|
+
const v = argv[i + 1];
|
|
131
|
+
if (v !== undefined) {
|
|
132
|
+
out.push(v);
|
|
133
|
+
i++;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
else if (argv[i].startsWith(`${flag}=`)) {
|
|
137
|
+
out.push(argv[i].slice(flag.length + 1));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/cli/commands/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { CliUsageError } from '../errors.js';
|
|
2
|
+
import { buildClient, resolveTarget } from '../context.js';
|
|
3
|
+
import { extractFlags } from '../parse-args.js';
|
|
4
|
+
import { bold, dim, printJson, printLine, printTable } from '../output.js';
|
|
5
|
+
// `tools` is the agent-friendly index for `call`: it answers "what can I call,
|
|
6
|
+
// what params does it take, where does it live" in one place, without making
|
|
7
|
+
// callers post-process `servers list` responses.
|
|
8
|
+
export async function run(args, globals, deps = {}) {
|
|
9
|
+
const sub = args.shift();
|
|
10
|
+
const client = deps.client ?? buildClient(resolveTarget(globals));
|
|
11
|
+
switch (sub) {
|
|
12
|
+
case undefined:
|
|
13
|
+
case 'list':
|
|
14
|
+
return list(client, args, globals);
|
|
15
|
+
case 'get':
|
|
16
|
+
case 'schema':
|
|
17
|
+
return get(client, args, globals);
|
|
18
|
+
default:
|
|
19
|
+
throw new CliUsageError(`Unknown tools subcommand: ${sub}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function fetchFlatTools(client) {
|
|
23
|
+
const res = await client.get('/api/servers');
|
|
24
|
+
const servers = res.data ?? [];
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const s of servers) {
|
|
27
|
+
for (const t of (s.tools ?? [])) {
|
|
28
|
+
out.push({
|
|
29
|
+
server: s.name,
|
|
30
|
+
serverStatus: s.status,
|
|
31
|
+
name: t.name,
|
|
32
|
+
description: t.description,
|
|
33
|
+
enabled: t.enabled,
|
|
34
|
+
inputSchema: t.inputSchema,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
async function list(client, args, globals) {
|
|
41
|
+
const { flags } = extractFlags(args, {
|
|
42
|
+
valued: ['--server'],
|
|
43
|
+
boolean: ['--schema', '--enabled-only'],
|
|
44
|
+
});
|
|
45
|
+
let tools = await fetchFlatTools(client);
|
|
46
|
+
if (flags['--server']) {
|
|
47
|
+
const wanted = String(flags['--server']);
|
|
48
|
+
tools = tools.filter((t) => t.server === wanted);
|
|
49
|
+
}
|
|
50
|
+
if (flags['--enabled-only']) {
|
|
51
|
+
tools = tools.filter((t) => t.enabled !== false);
|
|
52
|
+
}
|
|
53
|
+
if (globals.json) {
|
|
54
|
+
if (!flags['--schema']) {
|
|
55
|
+
// Drop inputSchema by default to keep the JSON small; callers can opt in.
|
|
56
|
+
printJson(tools.map(({ inputSchema: _omit, ...rest }) => rest));
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
printJson(tools);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (tools.length === 0) {
|
|
64
|
+
printLine(dim('(no tools)'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
printTable(tools.map((t) => ({
|
|
68
|
+
server: t.server,
|
|
69
|
+
tool: t.name,
|
|
70
|
+
enabled: t.enabled === false ? 'no' : 'yes',
|
|
71
|
+
description: truncate(t.description ?? '', 60),
|
|
72
|
+
})), ['server', 'tool', 'enabled', 'description']);
|
|
73
|
+
printLine(dim(`\nUse \`mcphub tools get <tool> [--server <name>]\` to see input schema and required params.`));
|
|
74
|
+
}
|
|
75
|
+
async function get(client, args, globals) {
|
|
76
|
+
const { positional, flags } = extractFlags(args, { valued: ['--server'] });
|
|
77
|
+
const name = positional[0];
|
|
78
|
+
if (!name) {
|
|
79
|
+
throw new CliUsageError('Usage: mcphub tools get <tool-name> [--server <server-name>]');
|
|
80
|
+
}
|
|
81
|
+
const wantedServer = flags['--server'];
|
|
82
|
+
const matches = (await fetchFlatTools(client)).filter((t) => t.name === name && (!wantedServer || t.server === wantedServer));
|
|
83
|
+
if (matches.length === 0) {
|
|
84
|
+
throw new CliUsageError(wantedServer
|
|
85
|
+
? `Tool "${name}" not found on server "${wantedServer}". Run \`mcphub tools list\` to see what's available.`
|
|
86
|
+
: `Tool "${name}" not found. Run \`mcphub tools list\` to see what's available.`);
|
|
87
|
+
}
|
|
88
|
+
if (matches.length > 1 && !wantedServer) {
|
|
89
|
+
const hosts = matches.map((m) => m.server).join(', ');
|
|
90
|
+
throw new CliUsageError(`Tool "${name}" exists on multiple servers (${hosts}). Pass --server <name> to pick one.`);
|
|
91
|
+
}
|
|
92
|
+
const tool = matches[0];
|
|
93
|
+
if (globals.json) {
|
|
94
|
+
printJson(tool);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const schema = tool.inputSchema;
|
|
98
|
+
const required = new Set(schema?.required ?? []);
|
|
99
|
+
const props = schema?.properties ?? {};
|
|
100
|
+
printLine(`${bold('Server:')} ${tool.server} (${tool.serverStatus})`);
|
|
101
|
+
printLine(`${bold('Tool:')} ${tool.name}`);
|
|
102
|
+
if (tool.description) {
|
|
103
|
+
printLine(`${bold('Description:')} ${tool.description}`);
|
|
104
|
+
}
|
|
105
|
+
if (tool.enabled === false) {
|
|
106
|
+
printLine(dim('(disabled — calls will fail until re-enabled)'));
|
|
107
|
+
}
|
|
108
|
+
printLine('');
|
|
109
|
+
if (Object.keys(props).length === 0) {
|
|
110
|
+
printLine(dim('No documented parameters.'));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
printLine(bold('Parameters:'));
|
|
114
|
+
const rows = Object.entries(props).map(([key, p]) => ({
|
|
115
|
+
param: key,
|
|
116
|
+
type: typeof p === 'object' && p ? p.type ?? '' : '',
|
|
117
|
+
required: required.has(key) ? 'yes' : 'no',
|
|
118
|
+
description: truncate(typeof p === 'object' && p ? p.description ?? '' : '', 60),
|
|
119
|
+
}));
|
|
120
|
+
printTable(rows, ['param', 'type', 'required', 'description']);
|
|
121
|
+
}
|
|
122
|
+
printLine('');
|
|
123
|
+
printLine(bold('Input schema (JSON):'));
|
|
124
|
+
printLine(JSON.stringify(tool.inputSchema ?? {}, null, 2));
|
|
125
|
+
printLine('');
|
|
126
|
+
printLine(bold('Example:'));
|
|
127
|
+
const example = buildExample(tool, required, props);
|
|
128
|
+
printLine(` ${example}`);
|
|
129
|
+
}
|
|
130
|
+
function buildExample(tool, required, props) {
|
|
131
|
+
const sample = (type) => {
|
|
132
|
+
switch (type) {
|
|
133
|
+
case 'number':
|
|
134
|
+
case 'integer':
|
|
135
|
+
return '0';
|
|
136
|
+
case 'boolean':
|
|
137
|
+
return 'true';
|
|
138
|
+
case 'array':
|
|
139
|
+
return '[]';
|
|
140
|
+
case 'object':
|
|
141
|
+
return '{}';
|
|
142
|
+
default:
|
|
143
|
+
return '<value>';
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const parts = ['mcphub', 'call', tool.name];
|
|
147
|
+
// Show required params first, with a hint at the type. Optional params are
|
|
148
|
+
// intentionally omitted so the example is the minimum-viable call.
|
|
149
|
+
const reqKeys = Array.from(required);
|
|
150
|
+
for (const key of reqKeys) {
|
|
151
|
+
const p = props[key];
|
|
152
|
+
parts.push(`${key}=${sample(typeof p === 'object' && p ? p.type : undefined)}`);
|
|
153
|
+
}
|
|
154
|
+
parts.push(`--server`, tool.server);
|
|
155
|
+
return parts.join(' ');
|
|
156
|
+
}
|
|
157
|
+
function truncate(s, n) {
|
|
158
|
+
if (s.length <= n)
|
|
159
|
+
return s;
|
|
160
|
+
return s.slice(0, n - 1) + '…';
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/cli/commands/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ApiClient } from './http.js';
|
|
2
|
+
import { CliUsageError } from './errors.js';
|
|
3
|
+
import { getProfile, loadCredentials, } from './profile.js';
|
|
4
|
+
// Resolve where requests should go and what token to use, in this order:
|
|
5
|
+
// 1. CLI flags (--url / --token / --bearer)
|
|
6
|
+
// 2. Environment variables (MCPHUB_URL / MCPHUB_TOKEN / MCPHUB_TOKEN_KIND)
|
|
7
|
+
// 3. Active profile in credentials.json (--profile <name> or current)
|
|
8
|
+
// Commands that only need a URL (e.g. discover) call resolveTargetForPublic()
|
|
9
|
+
// instead, which doesn't require a token.
|
|
10
|
+
export function resolveTarget(globals, creds) {
|
|
11
|
+
const credentials = creds ?? loadCredentials();
|
|
12
|
+
const profile = getProfile(credentials, globals.profile);
|
|
13
|
+
const baseUrl = globals.url ?? process.env.MCPHUB_URL ?? profile?.url;
|
|
14
|
+
if (!baseUrl) {
|
|
15
|
+
throw new CliUsageError('No mcphub URL configured. Use --url <url>, MCPHUB_URL env, or run `mcphub login`.');
|
|
16
|
+
}
|
|
17
|
+
const tokenKind = (globals.bearer ? 'bearer' : undefined) ??
|
|
18
|
+
process.env.MCPHUB_TOKEN_KIND ??
|
|
19
|
+
profile?.tokenKind ??
|
|
20
|
+
'jwt';
|
|
21
|
+
const token = globals.token ?? process.env.MCPHUB_TOKEN ?? profile?.token;
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new CliUsageError('Not logged in. Use --token <token>, MCPHUB_TOKEN env, or run `mcphub login`.');
|
|
24
|
+
}
|
|
25
|
+
return { baseUrl, token, tokenKind, profileName: globals.profile ?? credentials.current };
|
|
26
|
+
}
|
|
27
|
+
export function resolveTargetForPublic(globals, remote, creds) {
|
|
28
|
+
const credentials = creds ?? loadCredentials();
|
|
29
|
+
const profile = getProfile(credentials, globals.profile);
|
|
30
|
+
const baseUrl = remote ?? globals.url ?? process.env.MCPHUB_URL ?? profile?.url;
|
|
31
|
+
if (!baseUrl) {
|
|
32
|
+
throw new CliUsageError('No mcphub URL configured. Use --remote <url>, --url <url>, MCPHUB_URL env, or run `mcphub login`.');
|
|
33
|
+
}
|
|
34
|
+
return { baseUrl };
|
|
35
|
+
}
|
|
36
|
+
export function buildClient(target, fetchImpl) {
|
|
37
|
+
return new ApiClient({
|
|
38
|
+
baseUrl: target.baseUrl,
|
|
39
|
+
token: target.token,
|
|
40
|
+
tokenKind: target.tokenKind,
|
|
41
|
+
fetchImpl,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/cli/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAEL,UAAU,EACV,eAAe,GAEhB,MAAM,cAAc,CAAC;AAkBtB,yEAAyE;AACzE,4CAA4C;AAC5C,2EAA2E;AAC3E,sEAAsE;AACtE,8EAA8E;AAC9E,0CAA0C;AAE1C,MAAM,UAAU,aAAa,CAAC,OAAoB,EAAE,KAAmB;IACrE,MAAM,WAAW,GAAG,KAAK,IAAI,eAAe,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAwB,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,GAAG,CAAC;IACtE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CACrB,mFAAmF,CACpF,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GACb,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,iBAA2C;QACxD,OAAO,EAAE,SAAS;QAClB,KAAK,CAAC;IACR,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,EAAE,KAAK,CAAC;IAC1E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,aAAa,CACrB,8EAA8E,CAC/E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;AAC5F,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,OAAoB,EACpB,MAAe,EACf,KAAmB;IAEnB,MAAM,WAAW,GAAG,KAAK,IAAI,eAAe,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,GAAG,CAAC;IAChF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CACrB,mGAAmG,CACpG,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,SAAwB;IAC1E,OAAO,IAAI,SAAS,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS;KACV,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Errors thrown by the CLI layer. Top-level handler in main.ts inspects the
|
|
2
|
+
// constructor (or `requiresLogin` flag) to choose an exit code and decide
|
|
3
|
+
// whether to print remediation hints.
|
|
4
|
+
export class CliUsageError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'CliUsageError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export class CliApiError extends Error {
|
|
11
|
+
constructor(init) {
|
|
12
|
+
super(init.message);
|
|
13
|
+
this.name = 'CliApiError';
|
|
14
|
+
this.status = init.status;
|
|
15
|
+
this.body = init.body;
|
|
16
|
+
this.requiresLogin = init.requiresLogin ?? init.status === 401;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/cli/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,0EAA0E;AAC1E,sCAAsC;AAEtC,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AASD,MAAM,OAAO,WAAY,SAAQ,KAAK;IAKpC,YAAY,IAAqB;QAC/B,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IACjE,CAAC;CACF"}
|