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.
## 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: 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.

4
package-lock.json generated
View File

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

View File

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

View File

@ -16,6 +16,20 @@ const economyCommandAliases = [
{ from: `${legacyEconomyStem}-games:coinflip`, to: "economy-games:coinflip" },
{ 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) {
const raw = fs.readFileSync(filePath, "utf8");
@ -27,7 +41,7 @@ function scanPluginDirectories() {
return [];
}
const entries = fs.readdirSync(pluginsDir, { withFileTypes: true });
const plugins = [];
const plugins = new Map();
for (const entry of entries) {
if (!entry.isDirectory()) {
continue;
@ -41,20 +55,33 @@ function scanPluginDirectories() {
}
try {
const manifest = readJson(manifestPath);
plugins.push({
id: manifest.id,
const id = canonicalPluginId(manifest.id);
const plugin = {
id,
manifestId: manifest.id,
name: manifest.name || manifest.id,
version: manifest.version || "0.0.0",
description: manifest.description || "",
main: manifest.main || "index.js",
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 {
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() {
@ -322,5 +349,7 @@ module.exports = {
stopPlugins,
installFromGit,
updatePluginFromGit,
createLocalPlugin
createLocalPlugin,
canonicalPluginId,
pluginLegacyIds
};

View File

@ -1,7 +1,7 @@
const fs = require("fs");
const path = require("path");
const { getSetting } = require("./settings");
const { scanPluginDirectories, getPlugins } = require("./plugins");
const { scanPluginDirectories, getPlugins, canonicalPluginId } = require("./plugins");
const {
parseSemver,
compareSemver,
@ -112,19 +112,22 @@ function snapshotAvailability(kind, id = null) {
function localPluginCandidates(registry) {
const candidates = new Map();
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()) {
if (isLumiAiToolId(plugin.id)) {
const id = canonicalPluginId(plugin.id);
if (isLumiAiToolId(id)) {
continue;
}
if (candidates.has(plugin.id)) {
if (candidates.has(id)) {
continue;
}
const pluginPath = plugin.path || "";
const installed = Boolean(pluginPath && fs.existsSync(path.join(pluginPath, "plugin.json")));
candidates.set(plugin.id, {
id: plugin.id,
candidates.set(id, {
id,
registry_id: plugin.id,
name: plugin.name || plugin.id,
version: plugin.version || "0.0.0",
description: "",
@ -136,6 +139,18 @@ function localPluginCandidates(registry) {
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() {
const tools = new Map();
const pluginsPath = path.join(repoRoot, "plugins");
@ -299,7 +314,7 @@ function getUpdateStatus(options = {}) {
sourceBranch,
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 remotePluginDirs = new Set();
const remoteTools = new Map();
@ -320,11 +335,12 @@ function getUpdateStatus(options = {}) {
continue;
}
remotePluginDirs.add(pluginId);
if (candidates.has(pluginId)) {
const canonicalRemoteId = canonicalPluginId(pluginId);
if (candidates.has(canonicalRemoteId)) {
continue;
}
candidates.set(pluginId, {
id: pluginId,
candidates.set(canonicalRemoteId, {
id: canonicalRemoteId,
name: manifest.name || pluginId,
version: "0.0.0",
description: manifest.description || "",