fix renamed economy plugin update status

This commit is contained in:
Franz Rolfsvaag 2026-06-17 22:39:29 +02:00
parent 580b4392b4
commit a48b946754
5 changed files with 66 additions and 20 deletions

View File

@ -124,6 +124,7 @@ This file tracks larger Lumi work that cannot safely be completed in one pass. K
- Review localization/translation keys if present so simplified wording remains consistent across languages. - Review localization/translation keys if present so simplified wording remains consistent across languages.
## Done ## Done
- 2026-06-17: Fixed update metadata for renamed Economy plugins so legacy installed rows are folded into canonical `economy-*` plugin update rows instead of appearing as separate installs; bumped core to v0.1.8.
- 2026-06-17: Renamed all remaining Economy internals from the old misspelled IDs/paths/tables to `economy-*`, added startup migration for legacy plugin rows, settings, command usage IDs, tables, uploads, asset paths, old URLs, and bumped core/plugin patch versions. - 2026-06-17: Renamed all remaining Economy internals from the old misspelled IDs/paths/tables to `economy-*`, added startup migration for legacy plugin rows, settings, command usage IDs, tables, uploads, asset paths, old URLs, and bumped core/plugin patch versions.
- 2026-06-17: Fixed user-facing Economy spelling, restored `/stats/{username}` Compare toggling, linked Top commands run leaderboard entries to `/commands`, and bumped core/plugin patch versions. - 2026-06-17: Fixed user-facing Economy spelling, restored `/stats/{username}` Compare toggling, linked Top commands run leaderboard entries to `/commands`, and bumped core/plugin patch versions.
- 2026-06-17: Fixed custom command Edit buttons and `/commands` Copy Link / expand buttons with delegated handlers, clipboard fallback, and v0.1.5 patch bump. - 2026-06-17: Fixed custom command Edit buttons and `/commands` Copy Link / expand buttons with delegated handlers, clipboard fallback, and v0.1.5 patch bump.

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "lumi-bot", "name": "lumi-bot",
"version": "0.1.7", "version": "0.1.8",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "lumi-bot", "name": "lumi-bot",
"version": "0.1.7", "version": "0.1.8",
"dependencies": { "dependencies": {
"adm-zip": "^0.5.12", "adm-zip": "^0.5.12",
"better-sqlite3": "^11.5.0", "better-sqlite3": "^11.5.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "lumi-bot", "name": "lumi-bot",
"version": "0.1.7", "version": "0.1.8",
"private": true, "private": true,
"type": "commonjs", "type": "commonjs",
"scripts": { "scripts": {

View File

@ -16,6 +16,20 @@ const economyCommandAliases = [
{ from: `${legacyEconomyStem}-games:coinflip`, to: "economy-games:coinflip" }, { from: `${legacyEconomyStem}-games:coinflip`, to: "economy-games:coinflip" },
{ from: `${legacyEconomyStem}-games:mystery`, to: "economy-games:mystery" } { from: `${legacyEconomyStem}-games:mystery`, to: "economy-games:mystery" }
]; ];
const pluginCanonicalAliases = Object.fromEntries(
Object.entries(economyPluginAliases).flatMap(([canonicalId, legacyIds]) =>
legacyIds.map((legacyId) => [legacyId, canonicalId])
)
);
function canonicalPluginId(id) {
const raw = String(id || "").trim();
return pluginCanonicalAliases[raw] || raw;
}
function pluginLegacyIds(id) {
return economyPluginAliases[canonicalPluginId(id)] || [];
}
function readJson(filePath) { function readJson(filePath) {
const raw = fs.readFileSync(filePath, "utf8"); const raw = fs.readFileSync(filePath, "utf8");
@ -27,7 +41,7 @@ function scanPluginDirectories() {
return []; return [];
} }
const entries = fs.readdirSync(pluginsDir, { withFileTypes: true }); const entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
const plugins = []; const plugins = new Map();
for (const entry of entries) { for (const entry of entries) {
if (!entry.isDirectory()) { if (!entry.isDirectory()) {
continue; continue;
@ -41,20 +55,33 @@ function scanPluginDirectories() {
} }
try { try {
const manifest = readJson(manifestPath); const manifest = readJson(manifestPath);
plugins.push({ const id = canonicalPluginId(manifest.id);
id: manifest.id, const plugin = {
id,
manifestId: manifest.id,
name: manifest.name || manifest.id, name: manifest.name || manifest.id,
version: manifest.version || "0.0.0", version: manifest.version || "0.0.0",
description: manifest.description || "", description: manifest.description || "",
main: manifest.main || "index.js", main: manifest.main || "index.js",
dir: path.join(pluginsDir, entry.name), dir: path.join(pluginsDir, entry.name),
legacyIds: economyPluginAliases[manifest.id] || [] legacyIds: pluginLegacyIds(manifest.id)
}); };
const existing = plugins.get(id);
if (!existing || isCanonicalPluginDirectory(plugin, entry.name, existing)) {
plugins.set(id, plugin);
}
} catch { } catch {
continue; continue;
} }
} }
return plugins; return Array.from(plugins.values());
}
function isCanonicalPluginDirectory(plugin, directoryName, existing) {
if (directoryName === plugin.id || plugin.manifestId === plugin.id) {
return true;
}
return existing.manifestId !== existing.id && existing.dir !== path.join(pluginsDir, existing.id);
} }
function syncPluginRegistry() { function syncPluginRegistry() {
@ -322,5 +349,7 @@ module.exports = {
stopPlugins, stopPlugins,
installFromGit, installFromGit,
updatePluginFromGit, updatePluginFromGit,
createLocalPlugin createLocalPlugin,
canonicalPluginId,
pluginLegacyIds
}; };

View File

@ -1,7 +1,7 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const { getSetting } = require("./settings"); const { getSetting } = require("./settings");
const { scanPluginDirectories, getPlugins } = require("./plugins"); const { scanPluginDirectories, getPlugins, canonicalPluginId } = require("./plugins");
const { const {
parseSemver, parseSemver,
compareSemver, compareSemver,
@ -112,19 +112,22 @@ function snapshotAvailability(kind, id = null) {
function localPluginCandidates(registry) { function localPluginCandidates(registry) {
const candidates = new Map(); const candidates = new Map();
for (const plugin of scanPluginDirectories()) { for (const plugin of scanPluginDirectories()) {
candidates.set(plugin.id, { ...plugin, installed: true }); const id = canonicalPluginId(plugin.id);
candidates.set(id, { ...plugin, id, installed: true });
} }
for (const plugin of registry.values()) { for (const plugin of registry.values()) {
if (isLumiAiToolId(plugin.id)) { const id = canonicalPluginId(plugin.id);
if (isLumiAiToolId(id)) {
continue; continue;
} }
if (candidates.has(plugin.id)) { if (candidates.has(id)) {
continue; continue;
} }
const pluginPath = plugin.path || ""; const pluginPath = plugin.path || "";
const installed = Boolean(pluginPath && fs.existsSync(path.join(pluginPath, "plugin.json"))); const installed = Boolean(pluginPath && fs.existsSync(path.join(pluginPath, "plugin.json")));
candidates.set(plugin.id, { candidates.set(id, {
id: plugin.id, id,
registry_id: plugin.id,
name: plugin.name || plugin.id, name: plugin.name || plugin.id,
version: plugin.version || "0.0.0", version: plugin.version || "0.0.0",
description: "", description: "",
@ -136,6 +139,18 @@ function localPluginCandidates(registry) {
return candidates; return candidates;
} }
function pluginRegistry() {
const registry = new Map();
for (const plugin of getPlugins()) {
const id = canonicalPluginId(plugin.id);
const existing = registry.get(id);
if (!existing || plugin.id === id) {
registry.set(id, { ...plugin, id, registry_id: plugin.id });
}
}
return registry;
}
function localToolCandidates() { function localToolCandidates() {
const tools = new Map(); const tools = new Map();
const pluginsPath = path.join(repoRoot, "plugins"); const pluginsPath = path.join(repoRoot, "plugins");
@ -299,7 +314,7 @@ function getUpdateStatus(options = {}) {
sourceBranch, sourceBranch,
channel: requestedSource === "experimental" ? "experimental" : "stable" channel: requestedSource === "experimental" ? "experimental" : "stable"
}); });
const registry = new Map(getPlugins().map((plugin) => [plugin.id, plugin])); const registry = pluginRegistry();
const remoteDirs = new Set(reader.listPluginDirs()); const remoteDirs = new Set(reader.listPluginDirs());
const remotePluginDirs = new Set(); const remotePluginDirs = new Set();
const remoteTools = new Map(); const remoteTools = new Map();
@ -320,11 +335,12 @@ function getUpdateStatus(options = {}) {
continue; continue;
} }
remotePluginDirs.add(pluginId); remotePluginDirs.add(pluginId);
if (candidates.has(pluginId)) { const canonicalRemoteId = canonicalPluginId(pluginId);
if (candidates.has(canonicalRemoteId)) {
continue; continue;
} }
candidates.set(pluginId, { candidates.set(canonicalRemoteId, {
id: pluginId, id: canonicalRemoteId,
name: manifest.name || pluginId, name: manifest.name || pluginId,
version: "0.0.0", version: "0.0.0",
description: manifest.description || "", description: manifest.description || "",