@epicai/legion 1.0.0 → 1.0.1
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/bin/setup.js +50 -145
- package/package.json +1 -1
package/dist/bin/setup.js
CHANGED
|
@@ -104,50 +104,6 @@ function loadCredentials() {
|
|
|
104
104
|
}
|
|
105
105
|
return creds;
|
|
106
106
|
}
|
|
107
|
-
// ─── Category display names ─────────────────────────────────
|
|
108
|
-
const CATEGORY_LABELS = {
|
|
109
|
-
'ai': 'AI / ML',
|
|
110
|
-
'cloud': 'Cloud Infrastructure',
|
|
111
|
-
'collaboration': 'Collaboration',
|
|
112
|
-
'commerce': 'Commerce & eCommerce',
|
|
113
|
-
'communication': 'Communication',
|
|
114
|
-
'compliance': 'Compliance & GRC',
|
|
115
|
-
'construction': 'Construction',
|
|
116
|
-
'crm': 'CRM & Sales',
|
|
117
|
-
'customer-support': 'Customer Support',
|
|
118
|
-
'cybersecurity': 'Cybersecurity',
|
|
119
|
-
'data': 'Data & Analytics',
|
|
120
|
-
'design': 'Design & Creative',
|
|
121
|
-
'devops': 'DevOps & CI/CD',
|
|
122
|
-
'education': 'Education',
|
|
123
|
-
'energy': 'Energy',
|
|
124
|
-
'engineering': 'Engineering & Aerospace',
|
|
125
|
-
'erp': 'ERP',
|
|
126
|
-
'finance': 'Finance & Payments',
|
|
127
|
-
'government': 'Government',
|
|
128
|
-
'healthcare': 'Healthcare',
|
|
129
|
-
'hospitality': 'Hospitality & Food',
|
|
130
|
-
'hr': 'HR & People',
|
|
131
|
-
'identity': 'Identity & Access',
|
|
132
|
-
'insurance': 'Insurance',
|
|
133
|
-
'iot': 'IoT & Devices',
|
|
134
|
-
'legal': 'Legal',
|
|
135
|
-
'logistics': 'Logistics & Shipping',
|
|
136
|
-
'manufacturing': 'Manufacturing',
|
|
137
|
-
'marketing': 'Marketing',
|
|
138
|
-
'media': 'Media & Entertainment',
|
|
139
|
-
'misc': 'Other',
|
|
140
|
-
'observability': 'Observability & Monitoring',
|
|
141
|
-
'productivity': 'Productivity',
|
|
142
|
-
'real-estate': 'Real Estate & Property',
|
|
143
|
-
'science': 'Science & Research',
|
|
144
|
-
'social': 'Social Media',
|
|
145
|
-
'telecom': 'Telecom',
|
|
146
|
-
'travel': 'Travel & Transportation',
|
|
147
|
-
};
|
|
148
|
-
function formatCategory(cat) {
|
|
149
|
-
return CATEGORY_LABELS[cat] || cat.charAt(0).toUpperCase() + cat.slice(1).replace(/-/g, ' ');
|
|
150
|
-
}
|
|
151
107
|
function expandHome(p) {
|
|
152
108
|
return p.startsWith('~') ? join(homedir(), p.slice(1)) : p;
|
|
153
109
|
}
|
|
@@ -1049,117 +1005,66 @@ async function runSetupWizard() {
|
|
|
1049
1005
|
p.log.warning('Doppler CLI not found — install from https://docs.doppler.com/docs/install-cli');
|
|
1050
1006
|
}
|
|
1051
1007
|
}
|
|
1052
|
-
// Step 4:
|
|
1053
|
-
|
|
1054
|
-
const
|
|
1008
|
+
// Step 4: Auto-wire adapters from credentials
|
|
1009
|
+
const selectedAdapterIds = [];
|
|
1010
|
+
const existingCreds = loadCredentials();
|
|
1011
|
+
// Match adapters whose required env keys are already present
|
|
1012
|
+
const autoMatched = [];
|
|
1055
1013
|
for (const adapter of allAdapters) {
|
|
1056
|
-
const
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1014
|
+
const restKey = adapter.rest?.envKey;
|
|
1015
|
+
const mcpKeys = adapter.mcp?.envKeys || [];
|
|
1016
|
+
const allKeys = [...(restKey ? [restKey] : []), ...mcpKeys];
|
|
1017
|
+
if (allKeys.length > 0 && allKeys.every(k => !!existingCreds[k])) {
|
|
1018
|
+
autoMatched.push(adapter);
|
|
1019
|
+
}
|
|
1060
1020
|
}
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
label: 'Security & Identity',
|
|
1065
|
-
cats: ['cybersecurity', 'identity', 'compliance'],
|
|
1066
|
-
},
|
|
1067
|
-
'devops': {
|
|
1068
|
-
label: 'DevOps & Infrastructure',
|
|
1069
|
-
cats: ['devops', 'cloud', 'observability', 'engineering'],
|
|
1070
|
-
},
|
|
1071
|
-
'business': {
|
|
1072
|
-
label: 'Business & Finance',
|
|
1073
|
-
cats: ['finance', 'crm', 'commerce', 'marketing', 'customer-support', 'hr', 'productivity', 'erp'],
|
|
1074
|
-
},
|
|
1075
|
-
'comms': {
|
|
1076
|
-
label: 'Communication & Collaboration',
|
|
1077
|
-
cats: ['communication', 'collaboration'],
|
|
1078
|
-
},
|
|
1079
|
-
'data-ai': {
|
|
1080
|
-
label: 'Data & AI',
|
|
1081
|
-
cats: ['data', 'ai', 'science'],
|
|
1082
|
-
},
|
|
1083
|
-
'industry': {
|
|
1084
|
-
label: 'Industry',
|
|
1085
|
-
cats: ['healthcare', 'hospitality', 'construction', 'manufacturing', 'real-estate', 'travel', 'education', 'insurance', 'legal', 'energy', 'automotive', 'telecom', 'logistics', 'government', 'iot'],
|
|
1086
|
-
},
|
|
1087
|
-
'media': {
|
|
1088
|
-
label: 'Media & Social',
|
|
1089
|
-
cats: ['media', 'social', 'design'],
|
|
1090
|
-
},
|
|
1091
|
-
'other': {
|
|
1092
|
-
label: 'Other',
|
|
1093
|
-
cats: ['misc', 'other'],
|
|
1094
|
-
},
|
|
1095
|
-
};
|
|
1096
|
-
// Count adapters per group
|
|
1097
|
-
function countGroup(cats) {
|
|
1098
|
-
let total = 0;
|
|
1099
|
-
for (const cat of cats)
|
|
1100
|
-
total += (categories.get(cat) || []).length;
|
|
1101
|
-
return total;
|
|
1021
|
+
if (autoMatched.length > 0) {
|
|
1022
|
+
p.note(autoMatched.map(a => `${pc.green('✓')} ${a.name || a.id}`).join('\n'), `${autoMatched.length} adapter${autoMatched.length !== 1 ? 's' : ''} matched from your credentials`);
|
|
1023
|
+
selectedAdapterIds.push(...autoMatched.map(a => a.id));
|
|
1102
1024
|
}
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
const ungrouped = Array.from(categories.keys()).filter(c => !allGroupedCats.has(c));
|
|
1106
|
-
if (ungrouped.length > 0) {
|
|
1107
|
-
GROUPS['other'].cats.push(...ungrouped);
|
|
1025
|
+
else {
|
|
1026
|
+
p.log.info('No adapters matched from credentials — use ' + pc.cyan('npx @epicai/legion add <name>') + ' to connect adapters.');
|
|
1108
1027
|
}
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
label: `${g.label} (${countGroup(g.cats)})`,
|
|
1114
|
-
}));
|
|
1115
|
-
const selectedGroups = await p.multiselect({
|
|
1116
|
-
message: 'What do you work with? (Space to select, Enter to confirm)',
|
|
1117
|
-
options: groupOptions,
|
|
1118
|
-
required: false,
|
|
1028
|
+
// Optional: search for additional adapters
|
|
1029
|
+
const addMore = await p.confirm({
|
|
1030
|
+
message: 'Search for additional adapters to configure?',
|
|
1031
|
+
initialValue: false,
|
|
1119
1032
|
});
|
|
1120
|
-
if (p.isCancel(
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (subCatOptions.length === 0)
|
|
1137
|
-
continue;
|
|
1138
|
-
const selectedSubCats = await p.multiselect({
|
|
1139
|
-
message: `${group.label} — select categories (Space to select, Enter to confirm)`,
|
|
1140
|
-
options: subCatOptions,
|
|
1141
|
-
required: false,
|
|
1142
|
-
});
|
|
1143
|
-
if (p.isCancel(selectedSubCats))
|
|
1144
|
-
continue;
|
|
1145
|
-
if (selectedSubCats.length > 0) {
|
|
1146
|
-
// Show adapters from selected subcategories
|
|
1147
|
-
const available = [];
|
|
1148
|
-
for (const cat of selectedSubCats) {
|
|
1149
|
-
for (const a of categories.get(cat) || []) {
|
|
1150
|
-
available.push({ value: a.id, label: a.name || a.id, hint: a.description?.slice(0, 60) });
|
|
1151
|
-
}
|
|
1033
|
+
if (!p.isCancel(addMore) && addMore) {
|
|
1034
|
+
let searching = true;
|
|
1035
|
+
while (searching) {
|
|
1036
|
+
const searchTerm = await p.text({
|
|
1037
|
+
message: 'Search adapters (name or keyword)',
|
|
1038
|
+
placeholder: 'e.g. grafana, paypal, github',
|
|
1039
|
+
});
|
|
1040
|
+
if (p.isCancel(searchTerm) || !searchTerm)
|
|
1041
|
+
break;
|
|
1042
|
+
const term = searchTerm.toLowerCase();
|
|
1043
|
+
const matches = allAdapters.filter(a => !selectedAdapterIds.includes(a.id) && (a.id.includes(term) ||
|
|
1044
|
+
(a.name || '').toLowerCase().includes(term) ||
|
|
1045
|
+
(a.description || '').toLowerCase().includes(term) ||
|
|
1046
|
+
(a.category || '').includes(term)));
|
|
1047
|
+
if (matches.length === 0) {
|
|
1048
|
+
p.log.warning(`No adapters found for "${searchTerm}"`);
|
|
1152
1049
|
}
|
|
1153
|
-
|
|
1154
|
-
const
|
|
1155
|
-
|
|
1156
|
-
|
|
1050
|
+
else {
|
|
1051
|
+
const options = matches.slice(0, 50).map(a => ({
|
|
1052
|
+
value: a.id,
|
|
1053
|
+
label: a.name || a.id,
|
|
1054
|
+
hint: a.description?.slice(0, 60),
|
|
1055
|
+
}));
|
|
1056
|
+
const picked = await p.multiselect({
|
|
1057
|
+
message: `${matches.length} match${matches.length !== 1 ? 'es' : ''} — select to add`,
|
|
1058
|
+
options,
|
|
1157
1059
|
required: false,
|
|
1158
1060
|
});
|
|
1159
|
-
if (!p.isCancel(
|
|
1160
|
-
selectedAdapterIds.push(...
|
|
1061
|
+
if (!p.isCancel(picked)) {
|
|
1062
|
+
selectedAdapterIds.push(...picked);
|
|
1161
1063
|
}
|
|
1162
1064
|
}
|
|
1065
|
+
const cont = await p.confirm({ message: 'Search for more?', initialValue: false });
|
|
1066
|
+
if (p.isCancel(cont) || !cont)
|
|
1067
|
+
searching = false;
|
|
1163
1068
|
}
|
|
1164
1069
|
}
|
|
1165
1070
|
// Step 5: Credentials
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epicai/legion",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Epic AI® Legion — 35,020 tools. One self-hosted MCP server. Intelligent Virtual Assistant (IVA) integration layer for AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|