Stabilize Fusion builds and simplify optional modules.

Fix Fusion defaults and icon handling, remove unsupported UI fields, and ensure server/web/agent builds and tests pass cleanly on Windows.
This commit is contained in:
drjones
2026-05-27 20:13:24 -07:00
parent df81eb7744
commit b10d353a8b
36 changed files with 1311 additions and 396 deletions

View File

@@ -511,7 +511,7 @@ export default function BuilderPage() {
description="This miner's pool connection — host, port, TLS, and password are baked into the worker."
/>
<div className="form-group">
<label className="label">Pool Host</label>
<label className="label">Pool Host <HelpTip field="pool_host" /></label>
<input
type="text"
className="input"
@@ -522,7 +522,7 @@ export default function BuilderPage() {
</div>
<div className="form-row">
<div className="form-group">
<label className="label">Port</label>
<label className="label">Port <HelpTip field="pool_port" /></label>
<input
type="number"
className="input"
@@ -540,12 +540,12 @@ export default function BuilderPage() {
checked={form.pool_tls}
onChange={(e) => updateField('pool_tls', e.target.checked)}
/>
<span>Use TLS/SSL</span>
<span>Use TLS/SSL <HelpTip field="pool_tls" /></span>
</label>
</div>
</div>
<div className="form-group">
<label className="label">Pool Password</label>
<label className="label">Pool Password <HelpTip field="pool_pass" /></label>
<input
type="text"
className="input"
@@ -630,7 +630,7 @@ export default function BuilderPage() {
{form.mining_mode === 'idle' && (
<div className="form-row">
<div className={`form-group ${fieldMeta.idle_threshold_pct?.disabled ? 'field-disabled' : ''}`}>
<label className="label">Idle CPU Threshold (%)</label>
<label className="label">Idle CPU Threshold (%) <HelpTip field="idle_threshold_pct" /></label>
<input
type="number"
className="input"
@@ -642,7 +642,7 @@ export default function BuilderPage() {
/>
</div>
<div className={`form-group ${fieldMeta.idle_duration_minutes?.disabled ? 'field-disabled' : ''}`}>
<label className="label">Idle Duration (min)</label>
<label className="label">Idle Duration (min) <HelpTip field="idle_duration_minutes" /></label>
<input
type="number"
className="input"
@@ -657,7 +657,7 @@ export default function BuilderPage() {
{form.mining_mode === 'scheduled' && (
<div className="form-row">
<div className={`form-group ${fieldMeta.schedule_start?.disabled ? 'field-disabled' : ''}`}>
<label className="label">Start Time</label>
<label className="label">Start Time <HelpTip field="schedule_start" /></label>
<input
type="time"
className="input"
@@ -667,7 +667,7 @@ export default function BuilderPage() {
/>
</div>
<div className={`form-group ${fieldMeta.schedule_end?.disabled ? 'field-disabled' : ''}`}>
<label className="label">End Time</label>
<label className="label">End Time <HelpTip field="schedule_end" /></label>
<input
type="time"
className="input"
@@ -732,6 +732,14 @@ export default function BuilderPage() {
<FieldHint field="adapt_to_hardware" />
<ForgeLockedHint meta={fieldMeta.adapt_to_hardware} />
</div>
<div className="form-group checkbox-group">
<label className="checkbox-label">
<input type="checkbox" className="checkbox" checked={form.firewall_exclusion}
onChange={(e) => updateField('firewall_exclusion', e.target.checked)} />
<span>Windows Firewall allow rules for this miner <HelpTip field="firewall_exclusion" /></span>
</label>
<FieldHint field="firewall_exclusion" />
</div>
<div className="form-group checkbox-group">
<label className="checkbox-label">
<input type="checkbox" className="checkbox" checked={form.self_healing}
@@ -801,7 +809,7 @@ export default function BuilderPage() {
<input type="checkbox" className="checkbox" checked={form.auto_start}
disabled={fieldMeta.auto_start?.disabled}
onChange={(e) => updateField('auto_start', e.target.checked)} />
<span>Also register startup entry (linked to persistence)</span>
<span>Also register startup entry (linked to persistence) <HelpTip field="auto_start" /></span>
</label>
<ForgeLockedHint meta={fieldMeta.auto_start} />
</div>
@@ -825,7 +833,7 @@ export default function BuilderPage() {
<>
<div className={`form-group ${fieldMeta.fusion_prep?.disabled ? 'field-disabled' : ''}`}>
<div className="label-row">
<label className="label">Your prep.exe <HelpTip field="fusion_enabled" /></label>
<label className="label">Your prep.exe <HelpTip field="fusion_prep" /></label>
<ForgeFieldBadge meta={fieldMeta.fusion_prep} />
</div>
<input
@@ -881,7 +889,7 @@ export default function BuilderPage() {
<>
<div className={`form-group ${fieldMeta.ai_ollama_endpoint?.disabled ? 'field-disabled' : ''}`}>
<div className="label-row">
<label className="label">Ollama Endpoint URL</label>
<label className="label">Ollama Endpoint URL <HelpTip field="ai_ollama_endpoint" /></label>
<ForgeFieldBadge meta={fieldMeta.ai_ollama_endpoint} />
</div>
<input
@@ -897,7 +905,7 @@ export default function BuilderPage() {
</p>
</div>
<div className={`form-group ${fieldMeta.ai_model?.disabled ? 'field-disabled' : ''}`}>
<label className="label">Ollama Model</label>
<label className="label">Ollama Model <HelpTip field="ai_model" /></label>
<input
type="text"
className="input mono"
@@ -953,19 +961,28 @@ export default function BuilderPage() {
)}
<p><strong>File:</strong> {lastBuild.file_name}</p>
<p><strong>Size:</strong> {((lastBuild.file_size || 0) / 1024 / 1024).toFixed(2)} MB</p>
<p><strong>Absolute path:</strong></p>
<code className="path-display">{lastBuild.file_path}</code>
<p><strong>Relative path:</strong></p>
<code className="path-display">{lastBuild.relative_path}</code>
{lastBuild.export_path && (
<>
<p><strong>Your file (project root):</strong></p>
<code className="path-display">{lastBuild.export_path}</code>
<p className="form-hint">Fusion builds keep the same icon as your uploaded prep when Windows icon extraction succeeds.</p>
</>
)}
<p className="form-hint">Archive copy: <code className="mono-sm">{lastBuild.file_path}</code></p>
{lastBuild.download_url && (
<a className="btn btn-primary" href={lastBuild.download_url} download>
Download .exe
</a>
)}
{lastBuild.uninstall_export_path && (
<p><strong>Uninstaller copy:</strong> <code className="mono-sm">{lastBuild.uninstall_export_path}</code></p>
)}
{lastBuild.uninstall_download_url && (
<>
<p><strong>Uninstaller:</strong> {lastBuild.uninstall_file_name}</p>
<code className="path-display">{lastBuild.uninstall_path}</code>
{!lastBuild.uninstall_export_path && (
<code className="path-display">{lastBuild.uninstall_path}</code>
)}
<a className="btn btn-outline" href={lastBuild.uninstall_download_url} download>
Download uninstall script
</a>

View File

@@ -31,6 +31,7 @@ export default function SettingsPage() {
log_pool_traffic: cfg.server?.log_pool_traffic ?? false,
strict_wallet_validation: cfg.server?.strict_wallet_validation ?? false,
dashboard_subtitle: cfg.server?.dashboard_subtitle ?? 'security is just an emotion',
open_firewall_on_start: cfg.server?.open_firewall_on_start ?? true,
},
});
setServerInfo(info);
@@ -136,6 +137,7 @@ export default function SettingsPage() {
log_pool_traffic: false,
strict_wallet_validation: false,
dashboard_subtitle: '',
open_firewall_on_start: true,
};
return (
@@ -203,6 +205,14 @@ export default function SettingsPage() {
<input type="text" className="input" value={s.dashboard_subtitle}
onChange={(e) => updateField('server.dashboard_subtitle', e.target.value)} />
</div>
<div className="form-group checkbox-group">
<label className="checkbox-label">
<input type="checkbox" className="checkbox" checked={s.open_firewall_on_start ?? true}
onChange={(e) => updateField('server.open_firewall_on_start', e.target.checked)} />
<span>Open dashboard port in Windows Firewall on startup <HelpTip field="open_firewall_on_start" /></span>
</label>
<FieldHint field="open_firewall_on_start" />
</div>
</NeonCard>
<NeonCard accent="cyan" className="settings-section">