error-ux-cli 1.1.0 → 1.1.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/lib/commands.js +50 -13
- package/lib/git.js +2 -1
- package/lib/plugins.js +1 -1
- package/package.json +1 -1
package/lib/commands.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const fs = require('fs/promises');
|
|
2
|
+
const fsSync = require('fs');
|
|
3
|
+
const path = require('path');
|
|
2
4
|
const auth = require('./auth');
|
|
3
5
|
const git = require('./git');
|
|
4
6
|
const news = require('./news');
|
|
7
|
+
const cmPlugins = require('./plugins');
|
|
5
8
|
const storage = require('./storage');
|
|
6
9
|
const utils = require('./utils');
|
|
7
10
|
|
|
@@ -1030,6 +1033,18 @@ async function handleAdminSync(rl, masterKey) {
|
|
|
1030
1033
|
|
|
1031
1034
|
const { pat, gistId } = JSON.parse(decrypted);
|
|
1032
1035
|
|
|
1036
|
+
if (!pat || !gistId) {
|
|
1037
|
+
console.error('\n❌ Error: Sync credentials not set. Please choose "Update Credentials" first.');
|
|
1038
|
+
console.log('--- Cloud Sync Management ---');
|
|
1039
|
+
const options = ['Update Credentials', 'Back'];
|
|
1040
|
+
const choice = await selectOption(rl, options);
|
|
1041
|
+
if (choice === 0) {
|
|
1042
|
+
// Re-run with intent to update
|
|
1043
|
+
return await handleAdminSync(rl, masterKey);
|
|
1044
|
+
}
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1033
1048
|
console.log('\n--- Cloud Sync Management ---');
|
|
1034
1049
|
const options = ['Push (Upload to Cloud)', 'Pull (Download from Cloud)', 'Update Credentials', 'Back'];
|
|
1035
1050
|
const choice = await selectOption(rl, options);
|
|
@@ -1046,7 +1061,7 @@ async function handleAdminSync(rl, masterKey) {
|
|
|
1046
1061
|
missions: user.missions,
|
|
1047
1062
|
localVault: user.localVault,
|
|
1048
1063
|
settings: user.settings,
|
|
1049
|
-
plugins:
|
|
1064
|
+
plugins: cmPlugins.getAllPluginSource()
|
|
1050
1065
|
});
|
|
1051
1066
|
const encryptedSyncData = storage.encrypt(syncData, masterKey);
|
|
1052
1067
|
await utils.withSpinner('Uploading to GitHub...', async () => {
|
|
@@ -1085,7 +1100,7 @@ async function handleAdminSync(rl, masterKey) {
|
|
|
1085
1100
|
if (remoteData.plugins) {
|
|
1086
1101
|
console.log('Synchronizing plugins to local directory...');
|
|
1087
1102
|
for (const filename in remoteData.plugins) {
|
|
1088
|
-
|
|
1103
|
+
cmPlugins.savePlugin(filename, remoteData.plugins[filename]);
|
|
1089
1104
|
}
|
|
1090
1105
|
}
|
|
1091
1106
|
|
|
@@ -1094,7 +1109,14 @@ async function handleAdminSync(rl, masterKey) {
|
|
|
1094
1109
|
} else if (choice === 2) {
|
|
1095
1110
|
// Update
|
|
1096
1111
|
const newPat = (await askQuestion(rl, 'New GitHub PAT: ')).trim();
|
|
1097
|
-
|
|
1112
|
+
let newGistId = (await askQuestion(rl, 'New Gist ID (or URL): ')).trim();
|
|
1113
|
+
|
|
1114
|
+
// Extract ID if URL is provided
|
|
1115
|
+
if (newGistId.includes('gist.github.com/')) {
|
|
1116
|
+
const parts = newGistId.split('/');
|
|
1117
|
+
newGistId = parts[parts.length - 1];
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1098
1120
|
if (newPat && newGistId) {
|
|
1099
1121
|
user.vault = storage.encrypt(JSON.stringify({ pat: newPat, gistId: newGistId }), masterKey);
|
|
1100
1122
|
await storage.saveConfig(config);
|
|
@@ -1106,6 +1128,25 @@ async function handleAdminSync(rl, masterKey) {
|
|
|
1106
1128
|
}
|
|
1107
1129
|
}
|
|
1108
1130
|
|
|
1131
|
+
async function setupDB(rl, masterKey, user, config) {
|
|
1132
|
+
console.log('\n--- PostgreSQL Credential Setup ---');
|
|
1133
|
+
const host = (await askQuestion(rl, 'Host (default: localhost): ')).trim() || 'localhost';
|
|
1134
|
+
const userStr = (await askQuestion(rl, 'User: ')).trim();
|
|
1135
|
+
const password = await auth.askPassword(rl, 'Password: ');
|
|
1136
|
+
const port = Number.parseInt((await askQuestion(rl, 'Port (default: 5432): ')).trim(), 10) || 5432;
|
|
1137
|
+
|
|
1138
|
+
if (userStr && password) {
|
|
1139
|
+
const dbCreds = { host, user: userStr, password, port };
|
|
1140
|
+
user.localVault = storage.encrypt(JSON.stringify(dbCreds), masterKey);
|
|
1141
|
+
await storage.saveConfig(config);
|
|
1142
|
+
console.log('Credentials updated and saved locally.');
|
|
1143
|
+
return true;
|
|
1144
|
+
} else {
|
|
1145
|
+
console.error('Invalid credentials. Update aborted.');
|
|
1146
|
+
return false;
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1109
1150
|
async function handleDB(rl, masterKey) {
|
|
1110
1151
|
if (!masterKey) {
|
|
1111
1152
|
console.log('Error: This command is only available in Admin mode.');
|
|
@@ -1231,10 +1272,6 @@ async function handlePlugin(rl, masterKey) {
|
|
|
1231
1272
|
return;
|
|
1232
1273
|
}
|
|
1233
1274
|
|
|
1234
|
-
const plugins = require('./plugins');
|
|
1235
|
-
const fs = require('fs');
|
|
1236
|
-
const path = require('path');
|
|
1237
|
-
|
|
1238
1275
|
console.log('\n--- Admin Plugin Management ---');
|
|
1239
1276
|
const choice = await selectOption(rl, [
|
|
1240
1277
|
'List Installed Plugins',
|
|
@@ -1244,7 +1281,7 @@ async function handlePlugin(rl, masterKey) {
|
|
|
1244
1281
|
]);
|
|
1245
1282
|
|
|
1246
1283
|
if (choice === 0) {
|
|
1247
|
-
const active =
|
|
1284
|
+
const active = cmPlugins.loadPlugins();
|
|
1248
1285
|
const names = Object.keys(active);
|
|
1249
1286
|
if (names.length === 0) {
|
|
1250
1287
|
console.log('No plugins installed in ~/.error-ux/plugins/');
|
|
@@ -1259,9 +1296,9 @@ async function handlePlugin(rl, masterKey) {
|
|
|
1259
1296
|
if (!name) return;
|
|
1260
1297
|
|
|
1261
1298
|
const fileName = `${name}.js`;
|
|
1262
|
-
const targetPath = path.join(
|
|
1299
|
+
const targetPath = path.join(cmPlugins.getPluginDir(), fileName);
|
|
1263
1300
|
|
|
1264
|
-
if (
|
|
1301
|
+
if (fsSync.existsSync(targetPath)) {
|
|
1265
1302
|
console.error(`Error: Plugin "${name}" already exists.`);
|
|
1266
1303
|
return;
|
|
1267
1304
|
}
|
|
@@ -1279,11 +1316,11 @@ module.exports = {
|
|
|
1279
1316
|
}
|
|
1280
1317
|
};
|
|
1281
1318
|
`;
|
|
1282
|
-
|
|
1319
|
+
fsSync.writeFileSync(targetPath, boilerplate, 'utf8');
|
|
1283
1320
|
console.log(`\nSuccess! Plugin boilerplate created at: ${targetPath}`);
|
|
1284
1321
|
console.log('Please restart the CLI to load your new plugin.');
|
|
1285
1322
|
} else if (choice === 2) {
|
|
1286
|
-
const active =
|
|
1323
|
+
const active = cmPlugins.loadPlugins();
|
|
1287
1324
|
const names = Object.keys(active);
|
|
1288
1325
|
if (names.length === 0) {
|
|
1289
1326
|
console.log('No plugins found to delete.');
|
|
@@ -1297,7 +1334,7 @@ module.exports = {
|
|
|
1297
1334
|
const targetName = names[pluginChoice];
|
|
1298
1335
|
const confirm = (await askQuestion(rl, `Are you SURE you want to delete "${targetName}"? (y/N): `)).toLowerCase();
|
|
1299
1336
|
if (confirm === 'y') {
|
|
1300
|
-
if (
|
|
1337
|
+
if (cmPlugins.deletePlugin(targetName)) {
|
|
1301
1338
|
console.log(`\nSuccess! Plugin "${targetName}" has been purged.`);
|
|
1302
1339
|
} else {
|
|
1303
1340
|
console.error(`Error: Could not delete "${targetName}".`);
|
package/lib/git.js
CHANGED
|
@@ -34,7 +34,8 @@ async function gistSync(token, gistId, data, action = 'pull') {
|
|
|
34
34
|
res.on('data', (d) => body += d);
|
|
35
35
|
res.on('end', () => {
|
|
36
36
|
if (res.statusCode >= 400) {
|
|
37
|
-
|
|
37
|
+
const maskedId = gistId ? `...${gistId.slice(-4)}` : 'MISSING';
|
|
38
|
+
return reject(new Error(`GitHub Error: ${res.statusCode} (ID: ${maskedId}) - ${body}`));
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
try {
|
package/lib/plugins.js
CHANGED
|
@@ -20,7 +20,7 @@ function loadPlugins() {
|
|
|
20
20
|
const files = fs.readdirSync(PLUGIN_DIR);
|
|
21
21
|
|
|
22
22
|
for (const file of files) {
|
|
23
|
-
if (file.endsWith('.js')) {
|
|
23
|
+
if (file.endsWith('.js') && !file.startsWith('.')) {
|
|
24
24
|
try {
|
|
25
25
|
const pluginPath = path.join(PLUGIN_DIR, file);
|
|
26
26
|
// Clear cache to allow reloading if needed
|