Close DV-01–04,07,09,13,14: unify operator-deck UX in server/web.

Standardize neon cyan on #00e8f5, wire SacredPageHeader across Builds/Path Tracer/LOTL, dedupe Pages.css, align Path Tracer chrome, drop dead wealth-deck CSS, add prefers-color-scheme shell + HelpTip, sidebar version from package.json build inject, and Vitest CSS regression guards.
This commit is contained in:
AetherForge
2026-06-07 06:33:51 -07:00
parent 85d55df37c
commit 74c006a04b
35 changed files with 1144 additions and 36 deletions

View File

@@ -2,6 +2,7 @@ package miner
import (
"bytes"
"encoding/json"
"fmt"
"log"
"os"
@@ -15,6 +16,17 @@ import (
const defaultMinerImage = "aetherforge/agent-worker:latest"
// ContainerStatsPath is where the worker writes hashrate for host relay (docker exec cat).
const ContainerStatsPath = "/tmp/miner-stats.json"
// WorkerImageBuildHint is shown in Forge when container/auto execution is selected.
const WorkerImageBuildHint = "Build worker image: docker build -f docker/Dockerfile.agent -t aetherforge/agent-worker:latest . (override with AETHERFORGE_MINER_IMAGE on host)"
// DefaultWorkerImage returns the OCI reference used when AETHERFORGE_MINER_IMAGE is unset.
func DefaultWorkerImage() string {
return defaultMinerImage
}
// containerExecCommand is exec.Command; tests override via SetContainerExecCommand.
var containerExecCommand = exec.Command
@@ -170,6 +182,39 @@ func (l *ContainerLauncher) Running() bool {
return l.running
}
// ProbeHashrate reads container-side hashrate from ContainerStatsPath via docker/podman exec.
func (l *ContainerLauncher) ProbeHashrate() float64 {
l.mu.Lock()
if !l.running || l.runtime.CLI == "" {
l.mu.Unlock()
return 0
}
name := l.name
cli := l.runtime.CLI
l.mu.Unlock()
cmd := containerExecCommand(cli, "exec", name, "cat", ContainerStatsPath)
out, err := cmd.Output()
if err != nil {
return 0
}
return ParseContainerStatsJSON(out)
}
// ParseContainerStatsJSON extracts hashrate_hps from worker stats JSON (tests + exec probe).
func ParseContainerStatsJSON(data []byte) float64 {
var snap struct {
HashrateHPS float64 `json:"hashrate_hps"`
}
if err := json.Unmarshal(bytes.TrimSpace(data), &snap); err != nil {
return 0
}
if snap.HashrateHPS < 0 {
return 0
}
return snap.HashrateHPS
}
func (l *ContainerLauncher) loadImageFromTar() (string, error) {
cmd := containerExecCommand(l.runtime.CLI, "load", "-i", l.tarPath)
var buf bytes.Buffer
@@ -234,6 +279,7 @@ func (l *ContainerLauncher) containerEnv() []string {
"AETHERFORGE_MINER_EXECUTION": ExecutionInProcess,
"AETHERFORGE_FLEET_SECRET": l.cfg.FleetSecret,
"MINER_LOG_FILE": "/tmp/miner.log",
"MINER_STATS_FILE": ContainerStatsPath,
}
if l.cfg.RVNWallet != "" {
pairs["AETHERFORGE_RVN_WALLET"] = l.cfg.RVNWallet