Merge claude/1

This commit is contained in:
librelad 2026-05-27 00:32:43 +01:00
commit 6ca6320c88

View File

@ -870,59 +870,69 @@ class TasksManager {
formatCommandForUser(task) {
if (!task.command) return 'Unknown Task';
// Declarative pattern table — order matters (first match wins, so put
// specific patterns ahead of catch-alls). `title` is either a literal
// string or a function taking the regex match and returning the title;
// the latter is used for per-app patterns that extract the app slug.
//
// Adding a new task: just append one row here. Add the matching command
// shape in the WebUI submission site and you're done — no new branch
// needed in this function.
const displayName = (slug) => window.getAppDisplayName ? window.getAppDisplayName(slug) : (slug.charAt(0).toUpperCase() + slug.slice(1));
if (/^libreportal setup config\b/.test(task.command)) return 'LibrePortal - Apply Configuration';
if (/^libreportal setup finalize\b/.test(task.command)) return 'LibrePortal - Finalize Setup';
if (/^libreportal setup apply\b/.test(task.command)) return 'LibrePortal - Setup Wizard';
const PATTERNS = [
// -- System / setup ----------------------------------------------------
{ match: /^libreportal setup config\b/, title: 'LibrePortal - Apply Configuration' },
{ match: /^libreportal setup finalize\b/, title: 'LibrePortal - Finalize Setup' },
{ match: /^libreportal setup apply\b/, title: 'LibrePortal - Setup Wizard' },
{ match: /^libreportal config update\b/, title: 'LibrePortal - Apply Configuration' },
// Self-update actions (WebUI "Update now" / "Check for updates").
if (/^libreportal update (apply|now)\b/.test(task.command)) return 'LibrePortal - Update';
if (/^libreportal update check\b/.test(task.command)) return 'LibrePortal - Check for Updates';
// -- Self-update -------------------------------------------------------
{ match: /^libreportal update (apply|now)\b/, title: 'LibrePortal - Update' },
{ match: /^libreportal update check\b/, title: 'LibrePortal - Check for Updates' },
// Backup engine — per-app actions.
const backupDeleteAllMatch = task.command.match(/libreportal backup app delete_all (\w+)/);
if (backupDeleteAllMatch) return `${displayName(backupDeleteAllMatch[1])} - Delete All Backups`;
// -- Peers -------------------------------------------------------------
{ match: /^libreportal peer add\b/, title: 'LibrePortal - Add Peer' },
{ match: /^libreportal peer remove\b/, title: 'LibrePortal - Remove Peer' },
{ match: /^libreportal peer pair\b/, title: 'LibrePortal - Pair with Peer' },
const backupDeleteMatch = task.command.match(/libreportal backup app delete (\w+) (.+)/);
if (backupDeleteMatch) return `${displayName(backupDeleteMatch[1])} - Delete Backup`;
// -- Regen -------------------------------------------------------------
{ match: /^libreportal regen\b/, title: 'LibrePortal - Regenerate WebUI Data' },
const backupCreateMatch = task.command.match(/^libreportal backup app create (\w+)/);
if (backupCreateMatch) return `${displayName(backupCreateMatch[1])} - Create Backup`;
// -- Backup: per-app (these capture the app slug) ----------------------
{ match: /^libreportal backup app create (\w+)/, title: (m) => `${displayName(m[1])} - Create Backup` },
{ match: /^libreportal backup app schedule (\w+)/, title: (m) => `${displayName(m[1])} - Scheduled Backup` },
{ match: /^libreportal backup app list (\w+)/, title: (m) => `${displayName(m[1])} - List Backups` },
{ match: /^libreportal backup app delete_all (\w+)/, title: (m) => `${displayName(m[1])} - Delete All Backups` },
{ match: /^libreportal backup app delete (\w+)/, title: (m) => `${displayName(m[1])} - Delete Backup` },
const backupScheduleMatch = task.command.match(/^libreportal backup app schedule (\w+)/);
if (backupScheduleMatch) return `${displayName(backupScheduleMatch[1])} - Scheduled Backup`;
// -- Backup: system / locations ----------------------------------------
{ match: /^libreportal backup all\b/, title: 'LibrePortal - Backup All Apps' },
{ match: /^libreportal backup verify\b/, title: 'LibrePortal - Verify Backups' },
{ match: /^libreportal backup system\b/, title: 'LibrePortal - Backup System Config' },
{ match: /^libreportal backup location add\b/, title: 'LibrePortal - Add Backup Location' },
{ match: /^libreportal backup location remove\b/, title: 'LibrePortal - Remove Backup Location' },
{ match: /^libreportal backup location init\b/, title: 'LibrePortal - Initialise Backup Locations' },
{ match: /^libreportal backup location check\b/, title: 'LibrePortal - Check Backup Locations' },
{ match: /^libreportal backup location list\b/, title: 'LibrePortal - List Backup Locations' },
{ match: /^libreportal backup location stats\b/, title: 'LibrePortal - Backup Location Stats' },
const backupListMatch = task.command.match(/^libreportal backup app list (\w+)/);
if (backupListMatch) return `${displayName(backupListMatch[1])} - List Backups`;
// -- Restore / migrate -------------------------------------------------
{ match: /^libreportal restore app start (\w+)/, title: (m) => `${displayName(m[1])} - Restore Backup` },
{ match: /^libreportal restore app list (\w+)/, title: (m) => `${displayName(m[1])} - List Backups` },
{ match: /^libreportal restore migrate app (\w+)/, title: (m) => `${displayName(m[1])} - Migrate from Host` },
{ match: /^libreportal restore migrate system\b/, title: 'LibrePortal - Migrate System' },
{ match: /^libreportal restore migrate discover\b/, title: 'LibrePortal - Discover Backups' },
{ match: /^libreportal restore first-run\b/, title: 'LibrePortal - First-Run Restore' },
];
// Backup engine — restore actions.
const restoreStartMatch = task.command.match(/^libreportal restore app start (\w+)/);
if (restoreStartMatch) return `${displayName(restoreStartMatch[1])} - Restore Backup`;
for (const p of PATTERNS) {
const m = task.command.match(p.match);
if (m) return typeof p.title === 'function' ? p.title(m) : p.title;
}
const restoreListMatch = task.command.match(/^libreportal restore app list (\w+)/);
if (restoreListMatch) return `${displayName(restoreListMatch[1])} - List Backups`;
const migrateAppMatch = task.command.match(/^libreportal restore migrate app (\w+)/);
if (migrateAppMatch) return `${displayName(migrateAppMatch[1])} - Migrate from Host`;
// Backup engine — system-level actions (no per-app target).
if (/^libreportal backup all\b/.test(task.command)) return 'LibrePortal - Backup All Apps';
if (/^libreportal backup verify\b/.test(task.command)) return 'LibrePortal - Verify Backups';
if (/^libreportal backup location add\b/.test(task.command)) return 'LibrePortal - Add Backup Location';
if (/^libreportal backup location remove\b/.test(task.command)) return 'LibrePortal - Remove Backup Location';
if (/^libreportal backup location init\b/.test(task.command)) return 'LibrePortal - Initialise Backup Locations';
if (/^libreportal backup location check\b/.test(task.command)) return 'LibrePortal - Check Backup Locations';
if (/^libreportal backup location list\b/.test(task.command)) return 'LibrePortal - List Backup Locations';
if (/^libreportal backup location stats\b/.test(task.command)) return 'LibrePortal - Backup Location Stats';
if (/^libreportal restore migrate system\b/.test(task.command)) return 'LibrePortal - Migrate System';
if (/^libreportal restore migrate discover\b/.test(task.command)) return 'LibrePortal - Discover Backups';
if (/^libreportal restore first-run\b/.test(task.command)) return 'LibrePortal - First-Run Restore';
// `libreportal app tool <app> <tool_id> ['<args>']` — show the
// tool's friendly label instead of "Tool Application". Pull the
// label from window.toolsCatalog if loaded; otherwise titlecase
// the snake_case tool id.
// `libreportal app tool <app> <tool_id> ['<args>']` — needs the tools
// catalog to resolve the friendly label, so it lives outside the table.
const toolMatch = task.command.match(/libreportal app tool (\S+) (\S+)/);
if (toolMatch) {
const appName = toolMatch[1];
@ -939,13 +949,12 @@ class TasksManager {
return `${displayName(appName)} - ${label}`;
}
// Parse libreportal commands. Capture only the app name token — anything after
// (e.g. config overrides like `CFG_FOO=bar|...`) is for the CLI, not the title.
// Generic `libreportal app <action> <app>` — capture the app token only;
// anything after (e.g. config overrides `CFG_FOO=bar|…`) is for the CLI.
const libreportalMatch = task.command.match(/libreportal app (\w+) (\S+)/);
if (libreportalMatch) {
const action = libreportalMatch[1];
const appName = libreportalMatch[2];
const actionMap = {
'install': 'Install Application',
'uninstall': 'Uninstall Application',
@ -955,23 +964,15 @@ class TasksManager {
'update': 'Update Application',
'rebuild': 'Rebuild Application',
'delete': 'Delete Backup',
'backup': 'Backup Application'
'backup': 'Backup Application',
};
const formattedAction = actionMap[action] || `${action.charAt(0).toUpperCase() + action.slice(1)} Application`;
return `${displayName(appName)} - ${formattedAction}`;
}
// Handle other common patterns
if (task.command.includes('docker-compose')) {
return 'Docker Compose Operation';
}
if (task.command.includes('docker')) {
return 'Docker Operation';
}
// Return first 50 chars of command as fallback
if (task.command.includes('docker-compose')) return 'Docker Compose Operation';
if (task.command.includes('docker')) return 'Docker Operation';
return task.command.length > 50 ? task.command.substring(0, 47) + '...' : task.command;
}