Release validation: tests green, USB pack, fleet UX and API hardening.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Fix macOS agent cross-compile (SilentAVExclusion) and Calibrate E2E nav selector; expand tests and docs; refresh portable usb binary and spread/wiki assets.
This commit is contained in:
70
server/web/src/help/wsStatsCoalesce.ts
Normal file
70
server/web/src/help/wsStatsCoalesce.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { Agent } from '../types';
|
||||
import type { WSStatsUpdate } from '../types/ws';
|
||||
|
||||
/** Returns true when a stats_update payload would not change visible agent fields. */
|
||||
export function agentStatsUnchanged(agent: Agent, u: WSStatsUpdate): boolean {
|
||||
if (agent.hashrate_15s !== u.hashrate_15s) return false;
|
||||
if (agent.hashrate_1m !== u.hashrate_1m) return false;
|
||||
if (agent.hashrate_15m !== u.hashrate_15m) return false;
|
||||
if (agent.cpu_usage_pct !== u.cpu_usage_pct) return false;
|
||||
if (u.memory_usage_pct !== undefined && agent.memory_usage_pct !== u.memory_usage_pct) return false;
|
||||
if (u.uptime_seconds !== undefined && agent.uptime_seconds !== u.uptime_seconds) return false;
|
||||
if (u.shares_submitted !== undefined && agent.shares_total !== u.shares_submitted) return false;
|
||||
if (u.shares_accepted !== undefined && agent.shares_good !== u.shares_accepted) return false;
|
||||
if (u.listen_port_count !== undefined && agent.listen_port_count !== u.listen_port_count) return false;
|
||||
if (u.dns_drifted !== undefined && agent.dns_drifted !== u.dns_drifted) return false;
|
||||
if (u.cpu_freq_mhz !== undefined && agent.cpu_freq_mhz !== u.cpu_freq_mhz) return false;
|
||||
if (u.cpu_max_mhz !== undefined && agent.cpu_max_mhz !== u.cpu_max_mhz) return false;
|
||||
if (u.cpu_throttle !== undefined && agent.cpu_throttle !== u.cpu_throttle) return false;
|
||||
if (u.cpu_temp_c !== undefined && agent.cpu_temp_c !== u.cpu_temp_c) return false;
|
||||
if (u.disk_free_gb !== undefined && agent.disk_free_gb !== u.disk_free_gb) return false;
|
||||
if (u.disk_total_gb !== undefined && agent.disk_total_gb !== u.disk_total_gb) return false;
|
||||
if (u.disk_free_pct !== undefined && agent.disk_free_pct !== u.disk_free_pct) return false;
|
||||
if (u.gpu_temp_c !== undefined && agent.gpu_temp_c !== u.gpu_temp_c) return false;
|
||||
if (u.gpu_usage_pct !== undefined && agent.gpu_usage_pct !== u.gpu_usage_pct) return false;
|
||||
if (u.gpu_miner_active !== undefined && agent.gpu_miner_active !== u.gpu_miner_active) return false;
|
||||
if (u.gpu_hashrate_15s !== undefined && agent.gpu_hashrate_15s !== u.gpu_hashrate_15s) return false;
|
||||
if (u.gpu_hashrate_1m !== undefined && agent.gpu_hashrate_1m !== u.gpu_hashrate_1m) return false;
|
||||
if (u.gpu_hashrate_15m !== undefined && agent.gpu_hashrate_15m !== u.gpu_hashrate_15m) return false;
|
||||
if (u.gpu_model !== undefined && agent.gpu_model !== u.gpu_model) return false;
|
||||
if (u.ssh_available !== undefined && agent.ssh_available !== u.ssh_available) return false;
|
||||
if (u.posture_score !== undefined && agent.posture_score !== u.posture_score) return false;
|
||||
if (u.last_patch_days !== undefined && agent.last_patch_days !== u.last_patch_days) return false;
|
||||
if (u.defender_rtp !== undefined && agent.defender_rtp !== u.defender_rtp) return false;
|
||||
if (u.firewall_domain !== undefined && agent.firewall_domain !== u.firewall_domain) return false;
|
||||
if (u.firewall_private !== undefined && agent.firewall_private !== u.firewall_private) return false;
|
||||
if (u.firewall_public !== undefined && agent.firewall_public !== u.firewall_public) return false;
|
||||
if (u.reboot_pending !== undefined && agent.reboot_pending !== u.reboot_pending) return false;
|
||||
if (u.agent_elevated !== undefined && agent.agent_elevated !== u.agent_elevated) return false;
|
||||
if (u.latency_ms !== undefined && agent.latency_ms !== u.latency_ms) return false;
|
||||
if (u.pending_updates !== undefined && agent.pending_updates !== u.pending_updates) return false;
|
||||
if (u.last_patch !== undefined && agent.last_patch !== u.last_patch) return false;
|
||||
if (u.dns_servers !== undefined && !shallowStrArrayEq(agent.dns_servers, u.dns_servers)) return false;
|
||||
if (u.dns_search_domains !== undefined && !shallowStrArrayEq(agent.dns_search_domains, u.dns_search_domains)) return false;
|
||||
if (u.av_products !== undefined && !shallowStrArrayEq(agent.av_products, u.av_products)) return false;
|
||||
if (u.services !== undefined && agent.services !== u.services) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function shallowStrArrayEq(a?: string[], b?: string[]): boolean {
|
||||
if (a === b) return true;
|
||||
if (!a || !b || a.length !== b.length) return false;
|
||||
for (let i = 0; i < a.length; i++) {
|
||||
if (a[i] !== b[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** WS message types that drive latestMessage consumers (sound, presence, emberwake). */
|
||||
export const WS_LATEST_MESSAGE_TYPES = new Set([
|
||||
'presence_snapshot',
|
||||
'presence_update',
|
||||
'notes_typing',
|
||||
'emberwake_notes_updated',
|
||||
'emberwake_war_room',
|
||||
'agent_online',
|
||||
'agent_offline',
|
||||
'new_share',
|
||||
'fleet_alert',
|
||||
'command_result',
|
||||
]);
|
||||
Reference in New Issue
Block a user